[erlang-js] Ver. 1.0.2
Peter Lemenkov
peter at fedoraproject.org
Wed Jul 4 20:45:46 UTC 2012
commit 5c88737486bc15774373b8d72a4e4deb80bf2e92
Author: Peter Lemenkov <lemenkov at gmail.com>
Date: Thu Jul 5 00:45:34 2012 +0400
Ver. 1.0.2
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
.gitignore | 1 +
...-js-0001-Fix-building-of-linked-in-driver.patch | 1077 +++++++++++++++++-
erlang-js-0002-Build-with-js-1.7.0.patch | 75 --
erlang-js-0002-build-fix-for-js-1.8.5.patch | 130 +++
...0003-Don-t-require-make-all-for-make-test.patch | 26 -
erlang-js-0003-Fix-deprecation-warning.patch | 26 +
...Include-eunit-headers-only-when-necessary.patch | 27 -
...-Use-mochiweb-instead-of-a-bundled-copies.patch | 1174 ++++++++++++++++++++
erlang-js-0005-Use-standard-layout-for-rebar.patch | 558 ++++++++++
erlang-js-0005-js-1.8.5.patch | 114 --
erlang-js-0006-Dont-treat-warnings-as-errors.patch | 26 +
erlang-js-0007-Start-erlang_js-explicitly.patch | 24 +
erlang-js.spec | 55 +-
sources | 2 +-
14 files changed, 3007 insertions(+), 308 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index ef16c1b..ab81a0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
/basho-erlang_js-erlang_js-0.5.0-0-g5350ed2.tar.gz
+/basho-erlang_js-1.0.2-0-g16bc10d.tar.gz
diff --git a/erlang-js-0001-Fix-building-of-linked-in-driver.patch b/erlang-js-0001-Fix-building-of-linked-in-driver.patch
index 3b48983..d1da899 100644
--- a/erlang-js-0001-Fix-building-of-linked-in-driver.patch
+++ b/erlang-js-0001-Fix-building-of-linked-in-driver.patch
@@ -1,63 +1,172 @@
-From 936e1fb62e0826515383e424bd96d24e7e100862 Mon Sep 17 00:00:00 2001
+From ae1726fd6c1f826a5780cc58e168a58ae6d7d330 Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov at gmail.com>
Date: Thu, 28 Oct 2010 12:26:25 +0400
-Subject: [PATCH 1/4] Fix building of linked-in driver
+Subject: [PATCH 1/7] Fix building of linked-in driver
Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
---
- c_src/Makefile | 59 +++-------------
- c_src/build_driver_deps.sh | 11 ---
+ GNUmakefile | 30 ---
+ Makefile | 22 +-
+ build_docs.sh | 4 -
+ c_src/Makefile | 62 -----
+ c_src/build_driver_deps.sh | 11 -
c_src/js-1.8.0-rc1.tar.gz | Bin 1310344 -> 0 bytes
c_src/nsprpub-4.8.tar.gz | Bin 1189679 -> 0 bytes
- c_src/patches/js-src-Makefile.in.OS_RELEASE.patch | 11 ---
- .../patches/js-src-Makefile.ref.LIB_ASFILES.patch | 14 ----
- c_src/patches/js-src-Makefile.ref.jscpucfg.patch | 11 ---
- c_src/patches/js-src-config-SunOS5.10.mk.patch | 19 -----
- .../patches/js-src-config-SunOS5.10_i86pc.mk.patch | 51 --------------
- c_src/patches/js-src-config-SunOS5.11.mk.patch | 63 -----------------
- .../patches/js-src-config-SunOS5.11_i86pc.mk.patch | 51 --------------
- .../patches/js-src-config-SunOS5.1x_i86pc.mk.patch | 72 --------------------
- c_src/patches/js-src-config.mk.patch | 12 ---
- 13 files changed, 12 insertions(+), 362 deletions(-)
+ c_src/patches/js-src-Makefile.in.OS_RELEASE.patch | 11 -
+ .../patches/js-src-Makefile.ref.LIB_ASFILES.patch | 14 --
+ c_src/patches/js-src-Makefile.ref.jscpucfg.patch | 11 -
+ c_src/patches/js-src-config-DragonFly.mk.patch | 97 --------
+ c_src/patches/js-src-config-FreeBSD.mk.patch | 102 --------
+ c_src/patches/js-src-config-NetBSD.mk.patch | 103 --------
+ c_src/patches/js-src-config-OpenBSD.mk.patch | 103 --------
+ c_src/patches/js-src-config-SunOS5.10.mk.patch | 19 --
+ .../patches/js-src-config-SunOS5.10_i86pc.mk.patch | 51 ----
+ c_src/patches/js-src-config-SunOS5.11.mk.patch | 63 -----
+ .../patches/js-src-config-SunOS5.11_i86pc.mk.patch | 51 ----
+ .../patches/js-src-config-SunOS5.1x_i86pc.mk.patch | 72 ------
+ c_src/patches/js-src-config.mk.patch | 39 ---
+ c_src/patches/nspr-src-Makefile.in.patch | 16 --
+ c_src/patches/nspr-src-configure.in.patch | 59 -----
+ c_src/patches/nspr-src-configure.patch | 251 --------------------
+ c_src/patches/nspr-src-prnetdb.c.patch | 14 --
+ rebar.config | 7 +-
+ rebar.mk | 38 ---
+ 26 files changed, 11 insertions(+), 1239 deletions(-)
+ delete mode 100644 GNUmakefile
+ delete mode 100755 build_docs.sh
+ delete mode 100644 c_src/Makefile
delete mode 100755 c_src/build_driver_deps.sh
delete mode 100644 c_src/js-1.8.0-rc1.tar.gz
delete mode 100644 c_src/nsprpub-4.8.tar.gz
delete mode 100644 c_src/patches/js-src-Makefile.in.OS_RELEASE.patch
delete mode 100644 c_src/patches/js-src-Makefile.ref.LIB_ASFILES.patch
delete mode 100644 c_src/patches/js-src-Makefile.ref.jscpucfg.patch
+ delete mode 100644 c_src/patches/js-src-config-DragonFly.mk.patch
+ delete mode 100644 c_src/patches/js-src-config-FreeBSD.mk.patch
+ delete mode 100644 c_src/patches/js-src-config-NetBSD.mk.patch
+ delete mode 100644 c_src/patches/js-src-config-OpenBSD.mk.patch
delete mode 100644 c_src/patches/js-src-config-SunOS5.10.mk.patch
delete mode 100644 c_src/patches/js-src-config-SunOS5.10_i86pc.mk.patch
delete mode 100644 c_src/patches/js-src-config-SunOS5.11.mk.patch
delete mode 100644 c_src/patches/js-src-config-SunOS5.11_i86pc.mk.patch
delete mode 100644 c_src/patches/js-src-config-SunOS5.1x_i86pc.mk.patch
delete mode 100644 c_src/patches/js-src-config.mk.patch
+ delete mode 100644 c_src/patches/nspr-src-Makefile.in.patch
+ delete mode 100644 c_src/patches/nspr-src-configure.in.patch
+ delete mode 100644 c_src/patches/nspr-src-configure.patch
+ delete mode 100644 c_src/patches/nspr-src-prnetdb.c.patch
+ delete mode 100644 rebar.mk
+diff --git a/GNUmakefile b/GNUmakefile
+deleted file mode 100644
+index 9df6429..0000000
+--- a/GNUmakefile
++++ /dev/null
+@@ -1,30 +0,0 @@
+-
+-all:
+- $(REBAR) compile
+-
+-verbose:
+- $(REBAR) compile verbose=1
+-
+-clean: c_src_clean
+- rm -rf tests_ebin docs
+- $(REBAR) clean
+-
+-c_src:
+- cd c_src; $(MAKE)
+-
+-c_src_clean:
+- cd c_src; $(MAKE) clean
+-
+-test: all
+- @mkdir -p tests_ebin
+- @cd tests;erl -make
+- @erl -noshell -boot start_sasl -pa ebin -pa tests_ebin -s erlang_js -eval 'test_suite:test().' -s init stop
+- @rm -f ebin/test_* ebin/*_tests.erl
+-
+-docs: all
+- @mkdir -p docs
+- @./build_docs.sh
+-
+-.PHONY: c_src docs
+-
+-include rebar.mk
+diff --git a/Makefile b/Makefile
+index 9657397..df3c065 100644
+--- a/Makefile
++++ b/Makefile
+@@ -2,24 +2,20 @@
+ # instead of this file. This provides compatability on systems where GNU make is
+ # not the system 'make' (eg. most non-linux UNIXes).
+
++REBAR ?= $(shell which rebar 2>/dev/null || which ./rebar)
++
+ all:
+- @gmake all
++ $(REBAR) compile
+
+ verbose:
+- @gmake verbose
++ $(REBAR) compile verbose=1
+
+-test:
+- @gmake test
++check: test
++test: all
++ $(REBAR) eunit
+
+ docs:
+- @gmake docs
+-
+-c_src: FORCE
+- @gmake c_src
+-FORCE:
+-
+-c_src_clean:
+- @gmake c_src_clean
++ $(REBAR) doc
+
+ clean:
+- @gmake clean
++ $(REBAR) clean
+diff --git a/build_docs.sh b/build_docs.sh
+deleted file mode 100755
+index a6990a8..0000000
+--- a/build_docs.sh
++++ /dev/null
+@@ -1,4 +0,0 @@
+-#!/bin/bash
+-
+-export ERL_LIBS=`cd ..;pwd`;
+-erl -noshell -eval 'edoc:application(erlang_js, [{dir, "docs"}]), init:stop().'
+\ No newline at end of file
diff --git a/c_src/Makefile b/c_src/Makefile
-index b9c045c..ba202a0 100644
+deleted file mode 100644
+index 169408a..0000000
--- a/c_src/Makefile
-+++ b/c_src/Makefile
-@@ -1,52 +1,17 @@
++++ /dev/null
+@@ -1,62 +0,0 @@
-# This Makefile builds the dependencies (libjs and libnspr) needed by
-# spidermonkey_drv.so
-+MAKE = make
-+CFLAGS ?= -g -Wall -O2
-+CC ?= gcc
-+OBJS = driver_comm.o spidermonkey.o spidermonkey_drv.o
-+ERLANG_ROOT := $(shell erl -eval 'io:format("~s", [code:root_dir()])' -s init stop -noshell)
-+ERL_INC_DIR = $(ERLANG_ROOT)/usr/include
-+LDFLAGS = -ljs -lerts -L$(ERLANG_ROOT)/usr/lib
-
+-
+-UNAME := $(shell uname -s)
-TAR ?= tar
-GUNZIP ?= gunzip
-SMONKEY_VER := 1.8.0-rc1
-NSPR_VER := 4.8
-+all: $(OBJS)
-+ $(CC) $(LDFLAGS) -shared -o erlang_js_drv.so $(OBJS)
-
+-
+-ifeq ($(UNAME),SunOS)
+- PATCH ?= gpatch
+-else
+- PATCH ?= patch
+-endif
+-
-SYSTEM_DIR := $(CURDIR)/system
-LIB_DIR := $(SYSTEM_DIR)/lib
-INC_DIR := $(SYSTEM_DIR)/include
-
+-
-JS_DIR := $(CURDIR)/js
-NSPR_DIR := $(CURDIR)/nsprpub
-
@@ -68,7 +177,7 @@ index b9c045c..ba202a0 100644
-$(LIB_DIR)/libjs.a: $(LIB_DIR)/libnspr4.a
- $(GUNZIP) -c js-$(SMONKEY_VER).tar.gz | $(TAR) xf -
- @for I in patches/js-*.patch; do \
-- (patch -p1 < $${I} || echo "Skipping patch"); \
+- ($(PATCH) -p1 < $${I} || echo "Skipping patch"); \
- done
- @$(MAKE) -C $(JS_DIR)/src BUILD_OPT=1 JS_DIST=$(SYSTEM_DIR) \
- JS_THREADSAFE=1 \
@@ -83,14 +192,15 @@ index b9c045c..ba202a0 100644
-
-$(LIB_DIR)/libnspr4.a:
- $(GUNZIP) -c nsprpub-$(NSPR_VER).tar.gz | $(TAR) xf -
+- @for I in patches/nspr-*.patch; do \
+- ($(PATCH) -p1 < $${I} || echo "Skipping patch"); \
+- done
- (cd $(NSPR_DIR) && \
- ./configure --disable-debug --enable-optimize \
- --prefix=$(SYSTEM_DIR) $(NSPR_SIXTYFOUR) && \
- $(MAKE) all install)
-+%.o: %.c
-+ $(CC) $(CFLAGS) $(LDFLAGS) -I $(ERL_INC_DIR) -DXP_UNIX -o $@ -c $<
-
- clean:
+-
+-clean:
- @rm -rf $(SYSTEM_DIR) $(NSPR_DIR) $(JS_DIR)
- @rm -rf *flymake*
-
@@ -100,7 +210,6 @@ index b9c045c..ba202a0 100644
- co -r NSPR_4_8_RTM -d nsprpub mozilla/nsprpub
-
-.EXPORT_ALL_VARIABLES:
-+ rm -f *~ *.o *.so
diff --git a/c_src/build_driver_deps.sh b/c_src/build_driver_deps.sh
deleted file mode 100755
index ff5ab52..0000000
@@ -48200,6 +48309,435 @@ index af17f67..0000000
-
- # Add to TARGETS for clobber rule
- TARGETS += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg \
+diff --git a/c_src/patches/js-src-config-DragonFly.mk.patch b/c_src/patches/js-src-config-DragonFly.mk.patch
+deleted file mode 100644
+index 53f9dc8..0000000
+--- a/c_src/patches/js-src-config-DragonFly.mk.patch
++++ /dev/null
+@@ -1,97 +0,0 @@
+---- c_src/js.orig/src/config/Dragonfly.mk 1969-12-31 19:00:00.000000000 -0500
+-+++ c_src/js/src/config/DragonFly.mk 2011-03-30 20:50:05.000000000 -0400
+-@@ -0,0 +1,94 @@
+-+# -*- Mode: makefile -*-
+-+#
+-+# ***** BEGIN LICENSE BLOCK *****
+-+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+-+#
+-+# The contents of this file are subject to the Mozilla Public License Version
+-+# 1.1 (the "License"); you may not use this file except in compliance with
+-+# the License. You may obtain a copy of the License at
+-+# http://www.mozilla.org/MPL/
+-+#
+-+# Software distributed under the License is distributed on an "AS IS" basis,
+-+# WITHOUT WARRANTY OF 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 *****
+-+
+-+#
+-+# Config for FreeBSD/NetBSD/OpenBSD.
+-+#
+-+
+-+#CC = gcc
+-+#CCC = g++
+-+CFLAGS+= -Wall -Wno-format
+-+OS_CFLAGS= -DXP_UNIX -DSVR4
+-+OS_CFLAGS+= -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE # -DHAVE_LOCALTIME_R
+-+INTERP_CFLAGS+= `pkg-config --cflags-only-I nspr`
+-+
+-+RANLIB = echo
+-+MKSHLIB = $(LD) -lm `pkg-config --libs nspr` -shared $(LDFLAGS) $(XMKSHLIBOPTS)
+-+
+-+#.c.o:
+-+# $(CC) -c -MD $*.d $(CFLAGS) $<
+-+
+-+CPU_ARCH = $(shell uname -m)
+-+# don't filter in x86-64 architecture
+-+ifneq (amd64,$(CPU_ARCH))
+-+ifeq (86,$(findstring 86,$(CPU_ARCH)))
+-+CPU_ARCH = x86
+-+OS_CFLAGS+= -DX86_LINUX
+-+
+-+ifeq (gcc, $(CC))
+-+# if using gcc on x86, check version for opt bug
+-+# (http://bugzilla.mozilla.org/show_bug.cgi?id=24892)
+-+GCC_VERSION := $(shell gcc -v 2>&1 | grep version | awk '{ print $$3 }')
+-+GCC_LIST:=$(sort 2.91.66 $(GCC_VERSION) )
+-+ifeq (2.91.66, $(firstword $(GCC_LIST)))
+-+CFLAGS+= -DGCC_OPT_BUG
+-+endif
+-+endif
+-+endif
+-+endif
+-+
+-+GFX_ARCH = x
+-+
+-+OS_LIBS = -lm $(LDFLAGS)
+-+
+-+ASFLAGS += -x assembler-with-cpp
+-+
+-+
+-+ifeq ($(CPU_ARCH),alpha)
+-+
+-+# Ask the C compiler on alpha linux to let us work with denormalized
+-+# double values, which are required by the ECMA spec.
+-+
+-+OS_CFLAGS += -mieee
+-+endif
+-+
+-+JS_EDITLINE = 1
+-+
+-+OS_CFLAGS += -DHAVE_VA_COPY -DVA_COPY=va_copy
+-+OS_CFLAGS += -DPIC -fPIC -DJS_HAVE_LONG_LONG -DHAVE_INTTYPES_H
+diff --git a/c_src/patches/js-src-config-FreeBSD.mk.patch b/c_src/patches/js-src-config-FreeBSD.mk.patch
+deleted file mode 100644
+index f15b4ea..0000000
+--- a/c_src/patches/js-src-config-FreeBSD.mk.patch
++++ /dev/null
+@@ -1,102 +0,0 @@
+---- c_src.orig/js/src/config/FreeBSD.mk 1969-12-31 19:00:00.000000000 -0500
+-+++ c_src/js/src/config/FreeBSD.mk 2011-03-30 20:12:51.000000000 -0400
+-@@ -0,0 +1,99 @@
+-+# -*- Mode: makefile -*-
+-+#
+-+# ***** BEGIN LICENSE BLOCK *****
+-+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+-+#
+-+# The contents of this file are subject to the Mozilla Public License Version
+-+# 1.1 (the "License"); you may not use this file except in compliance with
+-+# the License. You may obtain a copy of the License at
+-+# http://www.mozilla.org/MPL/
+-+#
+-+# Software distributed under the License is distributed on an "AS IS" basis,
+-+# WITHOUT WARRANTY OF 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 *****
+-+
+-+#
+-+# Config for all versions of Linux
+-+#
+-+
+-+CC ?= gcc
+-+CCC ?= g++
+-+CFLAGS += -Wall -Wno-format
+-+OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R
+-+
+-+RANLIB = echo
+-+MKSHLIB = $(LD) -shared $(XMKSHLIBOPTS)
+-+
+-+#.c.o:
+-+# $(CC) -c -MD $*.d $(CFLAGS) $<
+-+
+-+CPU_ARCH = $(shell uname -m)
+-+# don't filter in x86-64 architecture
+-+ifneq (x86_64,$(CPU_ARCH))
+-+ifeq (86,$(findstring 86,$(CPU_ARCH)))
+-+CPU_ARCH = x86
+-+OS_CFLAGS+= -DX86_LINUX
+-+
+-+ifeq (gcc, $(CC))
+-+# if using gcc on x86, check version for opt bug
+-+# (http://bugzilla.mozilla.org/show_bug.cgi?id=24892)
+-+GCC_VERSION := $(shell gcc -v 2>&1 | grep version | awk '{ print $$3 }')
+-+GCC_LIST:=$(sort 2.91.66 $(GCC_VERSION) )
+-+
+-+ifeq (2.91.66, $(firstword $(GCC_LIST)))
+-+CFLAGS+= -DGCC_OPT_BUG
+-+endif
+-+endif
+-+endif
+-+endif
+-+
+-+GFX_ARCH = x
+-+
+-+OS_LIBS = -lm
+-+
+-+ASFLAGS += -x assembler-with-cpp
+-+
+-+
+-+ifeq ($(CPU_ARCH),alpha)
+-+
+-+# Ask the C compiler on alpha linux to let us work with denormalized
+-+# double values, which are required by the ECMA spec.
+-+
+-+OS_CFLAGS += -mieee
+-+endif
+-+
+-+# Use the editline library to provide line-editing support.
+-+JS_READLINE = 1
+-+
+-+OS_CFLAGS += -DHAVE_VA_COPY -DVA_COPY=va_copy
+-+
+-+ifeq ($(CPU_ARCH),sparc64)
+-+OS_CFLAGS += -DPIC -fPIC
+-+else
+-+OS_CFLAGS += -DPIC -fpic
+-+endif
+diff --git a/c_src/patches/js-src-config-NetBSD.mk.patch b/c_src/patches/js-src-config-NetBSD.mk.patch
+deleted file mode 100644
+index c4cb8d8..0000000
+--- a/c_src/patches/js-src-config-NetBSD.mk.patch
++++ /dev/null
+@@ -1,103 +0,0 @@
+---- c_src/js.old/src/config/NetBSD.mk Fri Apr 1 20:06:04 2011
+-+++ c_src/js/src/config/NetBSD.mk Fri Apr 1 20:31:19 2011
+-@@ -0,0 +1,100 @@
+-+# -*- Mode: makefile -*-
+-+#
+-+# ***** BEGIN LICENSE BLOCK *****
+-+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+-+#
+-+# The contents of this file are subject to the Mozilla Public License Version
+-+# 1.1 (the "License"); you may not use this file except in compliance with
+-+# the License. You may obtain a copy of the License at
+-+# http://www.mozilla.org/MPL/
+-+#
+-+# Software distributed under the License is distributed on an "AS IS" basis,
+-+# WITHOUT WARRANTY OF 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 *****
+-+
+-+#
+-+# Config for all versions of Linux
+-+#
+-+
+-+CC = gcc
+-+CCC = g++
+-+CFLAGS += -Wall -Wno-format
+-+OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R
+-+
+-+RANLIB = echo
+-+MKSHLIB = $(CC) -shared $(XMKSHLIBOPTS)
+-+
+-+#.c.o:
+-+# $(CC) -c -MD $*.d $(CFLAGS) $<
+-+
+-+CPU_ARCH = $(shell uname -m)
+-+# don't filter in x86-64 architecture
+-+ifneq (x86_64,$(CPU_ARCH))
+-+ifeq (86,$(findstring 86,$(CPU_ARCH)))
+-+CPU_ARCH = x86
+-+OS_CFLAGS+= -DX86_LINUX
+-+
+-+ifeq (gcc, $(CC))
+-+# if using gcc on x86, check version for opt bug
+-+# (http://bugzilla.mozilla.org/show_bug.cgi?id=24892)
+-+GCC_VERSION := $(shell gcc -v 2>&1 | grep version | awk '{ print $$3 }')
+-+GCC_LIST:=$(sort 2.91.66 $(GCC_VERSION) )
+-+
+-+ifeq (2.91.66, $(firstword $(GCC_LIST)))
+-+CFLAGS+= -DGCC_OPT_BUG
+-+endif
+-+endif
+-+endif
+-+endif
+-+
+-+GFX_ARCH = x
+-+
+-+OS_LIBS = -lm
+-+
+-+ASFLAGS += -x assembler-with-cpp
+-+
+-+PROG_LIBS += -pthread
+-+
+-+ifeq ($(CPU_ARCH),alpha)
+-+
+-+# Ask the C compiler on alpha linux to let us work with denormalized
+-+# double values, which are required by the ECMA spec.
+-+
+-+OS_CFLAGS += -mieee
+-+endif
+-+
+-+# Use the editline library to provide line-editing support.
+-+JS_EDITLINE = 1
+-+
+-+OS_CFLAGS += -DHAVE_VA_COPY -DVA_COPY=va_copy
+-+
+-+ifeq ($(CPU_ARCH),sparc64)
+-+OS_CFLAGS += -DPIC -fPIC
+-+else
+-+OS_CFLAGS += -DPIC -fpic
+-+endif
+diff --git a/c_src/patches/js-src-config-OpenBSD.mk.patch b/c_src/patches/js-src-config-OpenBSD.mk.patch
+deleted file mode 100644
+index ef6c5a1..0000000
+--- a/c_src/patches/js-src-config-OpenBSD.mk.patch
++++ /dev/null
+@@ -1,103 +0,0 @@
+---- c_src/js.old/src/config/OpenBSD.mk Fri Apr 1 20:06:04 2011
+-+++ c_src/js/src/config/OpenBSD.mk Fri Apr 1 20:31:19 2011
+-@@ -0,0 +1,100 @@
+-+# -*- Mode: makefile -*-
+-+#
+-+# ***** BEGIN LICENSE BLOCK *****
+-+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+-+#
+-+# The contents of this file are subject to the Mozilla Public License Version
+-+# 1.1 (the "License"); you may not use this file except in compliance with
+-+# the License. You may obtain a copy of the License at
+-+# http://www.mozilla.org/MPL/
+-+#
+-+# Software distributed under the License is distributed on an "AS IS" basis,
+-+# WITHOUT WARRANTY OF 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 *****
+-+
+-+#
+-+# Config for all versions of Linux
+-+#
+-+
+-+CC = gcc
+-+CCC = g++
+-+CFLAGS += -Wall -Wno-format
+-+OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R
+-+
+-+RANLIB = echo
+-+MKSHLIB = $(CC) -shared $(XMKSHLIBOPTS)
+-+
+-+#.c.o:
+-+# $(CC) -c -MD $*.d $(CFLAGS) $<
+-+
+-+CPU_ARCH = $(shell uname -m)
+-+# don't filter in x86-64 architecture
+-+ifneq (x86_64,$(CPU_ARCH))
+-+ifeq (86,$(findstring 86,$(CPU_ARCH)))
+-+CPU_ARCH = x86
+-+OS_CFLAGS+= -DX86_LINUX
+-+
+-+ifeq (gcc, $(CC))
+-+# if using gcc on x86, check version for opt bug
+-+# (http://bugzilla.mozilla.org/show_bug.cgi?id=24892)
+-+GCC_VERSION := $(shell gcc -v 2>&1 | grep version | awk '{ print $$3 }')
+-+GCC_LIST:=$(sort 2.91.66 $(GCC_VERSION) )
+-+
+-+ifeq (2.91.66, $(firstword $(GCC_LIST)))
+-+CFLAGS+= -DGCC_OPT_BUG
+-+endif
+-+endif
+-+endif
+-+endif
+-+
+-+GFX_ARCH = x
+-+
+-+OS_LIBS = -lm
+-+
+-+ASFLAGS += -x assembler-with-cpp
+-+
+-+PROG_LIBS += -pthread
+-+
+-+ifeq ($(CPU_ARCH),alpha)
+-+
+-+# Ask the C compiler on alpha linux to let us work with denormalized
+-+# double values, which are required by the ECMA spec.
+-+
+-+OS_CFLAGS += -mieee
+-+endif
+-+
+-+# Use the editline library to provide line-editing support.
+-+JS_READLINE = 1
+-+
+-+OS_CFLAGS += -DHAVE_VA_COPY -DVA_COPY=va_copy
+-+
+-+ifeq ($(CPU_ARCH),sparc64)
+-+OS_CFLAGS += -DPIC -fPIC
+-+else
+-+OS_CFLAGS += -DPIC -fpic
+-+endif
diff --git a/c_src/patches/js-src-config-SunOS5.10.mk.patch b/c_src/patches/js-src-config-SunOS5.10.mk.patch
deleted file mode 100644
index 1fe0367..0000000
@@ -48488,13 +49026,40 @@ index 0ee3b33..0000000
-+JS_EDITLINE = 1
diff --git a/c_src/patches/js-src-config.mk.patch b/c_src/patches/js-src-config.mk.patch
deleted file mode 100644
-index 2277310..0000000
+index d6e44c8..0000000
--- a/c_src/patches/js-src-config.mk.patch
+++ /dev/null
-@@ -1,12 +0,0 @@
----- c_src.orig/js/src/config.mk 2010-02-10 15:25:09.000000000 -0800
--+++ c_src/js/src/config.mk 2010-02-10 15:26:42.000000000 -0800
--@@ -141,7 +141,9 @@
+@@ -1,39 +0,0 @@
+---- c_src.orig/js/src/config.mk 2008-03-12 10:36:06.000000000 -0400
+-+++ c_src/js/src/config.mk 2011-03-30 20:11:30.000000000 -0400
+-@@ -100,10 +100,26 @@
+- ifeq ($(OS_ARCH),Darwin)
+- OS_CONFIG := Darwin
+- else
+-+ifeq ($(OS_ARCH), NetBSD)
+-+OS_CONFIG := NetBSD
+-+else
+-+ifeq ($(OS_ARCH), FreeBSD)
+-+OS_CONFIG := FreeBSD
+-+else
+-+ifeq ($(OS_ARCH), DragonFly)
+-+OS_CONFIG := DragonFly
+-+else
+-+ifeq ($(OS_ARCH), OpenBSD)
+-+OS_CONFIG := OpenBSD
+-+else
+- OS_CONFIG := $(OS_ARCH)$(OS_OBJTYPE)$(OS_RELEASE)
+- endif
+- endif
+- endif
+-+endif
+-+endif
+-+endif
+-+endif
+-
+- ASFLAGS =
+- DEFINES =
+-@@ -141,7 +157,9 @@
-
- SO_SUFFIX = so
-
@@ -48504,6 +49069,436 @@ index 2277310..0000000
-
- # Java stuff
- CLASSDIR = $(DEPTH)/liveconnect/classes
+diff --git a/c_src/patches/nspr-src-Makefile.in.patch b/c_src/patches/nspr-src-Makefile.in.patch
+deleted file mode 100644
+index 2fb1f56..0000000
+--- a/c_src/patches/nspr-src-Makefile.in.patch
++++ /dev/null
+@@ -1,16 +0,0 @@
+-$OpenBSD: patch-mozilla_nsprpub_lib_tests_Makefile_in,v 1.4 2009/08/04 13:56:09 martynas Exp $
+---- mozilla/nsprpub/lib/tests/Makefile.in.orig Sun Feb 22 20:56:04 2009
+-+++ mozilla/nsprpub/lib/tests/Makefile.in Sat Jun 20 23:38:30 2009
+-@@ -117,6 +117,12 @@ ifeq (,$(filter-out OpenBSD,$(OS_ARCH)))
+- endif
+- endif
+-
+-+ifeq ($(OS_ARCH), OpenBSD)
+-+ ifeq ($(USE_PTHREADS),1)
+-+ EXTRA_LIBS = -lpthread
+-+ endif
+-+endif
+-+
+- ifeq ($(OS_ARCH), OSF1)
+- LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread
+- endif
+diff --git a/c_src/patches/nspr-src-configure.in.patch b/c_src/patches/nspr-src-configure.in.patch
+deleted file mode 100644
+index 16aa64f..0000000
+--- a/c_src/patches/nspr-src-configure.in.patch
++++ /dev/null
+@@ -1,59 +0,0 @@
+---- c_src/nsprpub.old/configure.in 2011-03-31 21:51:51 -0400
+-+++ c_src/nsprpub/configure.in 2011-03-31 21:53:18 -0400
+-@@ -1161,6 +1161,29 @@
+- MDCPUCFG_H=_freebsd.cfg
+- PR_MD_CSRCS=freebsd.c
+- ;;
+-+*-dragonfly*)
+-+ 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
+-+ if test "$LIBRUNPATH"; then
+-+ DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+-+ fi
+-+ ;;
+-
+- *-hpux*)
+- AC_DEFINE(XP_UNIX)
+-@@ -2511,7 +2534,7 @@
+- 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* | dragonfly*)
+- # Freebsd doesn't use -pthread for compiles, it uses them for linking
+- ;;
+- *)
+-@@ -2549,7 +2572,7 @@
+- _PTHREAD_LDFLAGS=
+- fi
+- ;;
+-- *-freebsd*)
+-+ *-freebsd* | dragonfly*)
+- AC_DEFINE(_REENTRANT)
+- AC_DEFINE(_THREAD_SAFE)
+- dnl -pthread links in -lc_r, so don't specify it explicitly.
+-@@ -2630,7 +2653,7 @@
+- AC_DEFINE(_PR_NEED_PTHREAD_INIT)
+- fi
+- ;;
+--*-freebsd*)
+-+*-freebsd* | dragonfly*)
+- if test -n "$USE_NSPR_THREADS"; then
+- AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+- fi
+diff --git a/c_src/patches/nspr-src-configure.patch b/c_src/patches/nspr-src-configure.patch
+deleted file mode 100644
+index 2bbb6a3..0000000
+--- a/c_src/patches/nspr-src-configure.patch
++++ /dev/null
+@@ -1,251 +0,0 @@
+---- c_src/nsprpub.old/configure 2011-03-31 21:51:51 -0400
+-+++ c_src/nsprpub/configure 2011-03-31 21:54:10 -0400
+-@@ -3518,6 +3518,41 @@
+- MDCPUCFG_H=_freebsd.cfg
+- PR_MD_CSRCS=freebsd.c
+- ;;
+-+*-dragonfly*)
+-+ 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
+-+ if test "$LIBRUNPATH"; then
+-+ DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+-+ fi
+-+ ;;
+-
+- *-hpux*)
+- cat >> confdefs.h <<\EOF
+-@@ -4505,17 +4540,17 @@
+- _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:4509: checking for machine/builtins.h" >&5
+-+echo "configure:4544: 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 4514 "configure"
+-+#line 4549 "configure"
+- #include "confdefs.h"
+- #include <machine/builtins.h>
+- EOF
+- ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+--{ (eval echo configure:4519: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+-+{ (eval echo configure:4554: \"$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*
+-@@ -5164,7 +5199,7 @@
+- ;;
+- *)
+- echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+--echo "configure:5168: checking for dlopen in -ldl" >&5
+-+echo "configure:5203: 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
+-@@ -5172,7 +5207,7 @@
+- ac_save_LIBS="$LIBS"
+- LIBS="-ldl $LIBS"
+- cat > conftest.$ac_ext <<EOF
+--#line 5176 "configure"
+-+#line 5211 "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
+-@@ -5183,7 +5218,7 @@
+- dlopen()
+- ; return 0; }
+- EOF
+--if { (eval echo configure:5187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+-+if { (eval echo configure:5222: \"$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
+-@@ -5200,17 +5235,17 @@
+- 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:5204: checking for dlfcn.h" >&5
+-+echo "configure:5239: 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 5209 "configure"
+-+#line 5244 "configure"
+- #include "confdefs.h"
+- #include <dlfcn.h>
+- EOF
+- ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+--{ (eval echo configure:5214: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+-+{ (eval echo configure:5249: \"$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*
+-@@ -5243,13 +5278,13 @@
+-
+- if test $ac_cv_prog_gcc = yes; then
+- echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+--echo "configure:5247: checking whether ${CC-cc} needs -traditional" >&5
+-+echo "configure:5282: 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 5253 "configure"
+-+#line 5288 "configure"
+- #include "confdefs.h"
+- #include <sgtty.h>
+- Autoconf TIOCGETP
+-@@ -5267,7 +5302,7 @@
+-
+- if test $ac_cv_prog_gcc_traditional = no; then
+- cat > conftest.$ac_ext <<EOF
+--#line 5271 "configure"
+-+#line 5306 "configure"
+- #include "confdefs.h"
+- #include <termio.h>
+- Autoconf TCGETA
+-@@ -5291,12 +5326,12 @@
+- for ac_func in lchown strerror
+- do
+- echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+--echo "configure:5295: checking for $ac_func" >&5
+-+echo "configure:5330: 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 5300 "configure"
+-+#line 5335 "configure"
+- #include "confdefs.h"
+- /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char $ac_func(); below. */
+-@@ -5319,7 +5354,7 @@
+-
+- ; return 0; }
+- EOF
+--if { (eval echo configure:5323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+-+if { (eval echo configure:5358: \"$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
+-@@ -5360,7 +5395,7 @@
+- if test -z "$GNU_CC"; then
+-
+- echo $ac_n "checking for +Olit support""... $ac_c" 1>&6
+--echo "configure:5364: checking for +Olit support" >&5
+-+echo "configure:5399: 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
+-@@ -5399,7 +5434,7 @@
+- *)
+-
+- echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
+--echo "configure:5403: checking for pthread_create in -lpthreads" >&5
+-+echo "configure:5438: checking for pthread_create in -lpthreads" >&5
+- echo "
+- #include <pthread.h>
+- void *foo(void *v) { return v; }
+-@@ -5421,7 +5456,7 @@
+- echo "$ac_t""no" 1>&6
+-
+- echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+--echo "configure:5425: checking for pthread_create in -lpthread" >&5
+-+echo "configure:5460: checking for pthread_create in -lpthread" >&5
+- echo "
+- #include <pthread.h>
+- void *foo(void *v) { return v; }
+-@@ -5443,7 +5478,7 @@
+- echo "$ac_t""no" 1>&6
+-
+- echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
+--echo "configure:5447: checking for pthread_create in -lc_r" >&5
+-+echo "configure:5482: checking for pthread_create in -lc_r" >&5
+- echo "
+- #include <pthread.h>
+- void *foo(void *v) { return v; }
+-@@ -5465,7 +5500,7 @@
+- echo "$ac_t""no" 1>&6
+-
+- echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6
+--echo "configure:5469: checking for pthread_create in -lc" >&5
+-+echo "configure:5504: checking for pthread_create in -lc" >&5
+- echo "
+- #include <pthread.h>
+- void *foo(void *v) { return v; }
+-@@ -5597,14 +5632,14 @@
+- rm -f conftest*
+- ac_cv_have_dash_pthread=no
+- echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
+--echo "configure:5601: checking whether ${CC-cc} accepts -pthread" >&5
+-+echo "configure:5636: 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* | dragonfly*)
+- # Freebsd doesn't use -pthread for compiles, it uses them for linking
+- ;;
+- *)
+-@@ -5620,7 +5655,7 @@
+- 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:5624: checking whether ${CC-cc} accepts -pthreads" >&5
+-+echo "configure:5659: 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
+-@@ -5640,7 +5675,7 @@
+- _PTHREAD_LDFLAGS=
+- fi
+- ;;
+-- *-freebsd*)
+-+ *-freebsd* | dragonfly*)
+- cat >> confdefs.h <<\EOF
+- #define _REENTRANT 1
+- EOF
+-@@ -5754,7 +5789,7 @@
+-
+- fi
+- ;;
+--*-freebsd*)
+-+*-freebsd* | dragonfly*)
+- if test -n "$USE_NSPR_THREADS"; then
+- cat >> confdefs.h <<\EOF
+- #define _PR_LOCAL_THREADS_ONLY 1
+diff --git a/c_src/patches/nspr-src-prnetdb.c.patch b/c_src/patches/nspr-src-prnetdb.c.patch
+deleted file mode 100644
+index b4fb0e9..0000000
+--- a/c_src/patches/nspr-src-prnetdb.c.patch
++++ /dev/null
+@@ -1,14 +0,0 @@
+---- c_src/nsprpub.old/pr/src/misc/prnetdb.c 2011-03-31 21:51:51 -0400
+-+++ c_src/nsprpub/pr/src/misc/prnetdb.c 2011-03-31 21:53:08 -0400
+-@@ -114,6 +114,11 @@
+- #define _PR_HAVE_5_ARG_GETPROTO_R
+- #endif
+-
+-+#if __DragonFly_version >= 200202
+-+#define _PR_HAVE_GETPROTO_R
+-+#define _PR_HAVE_5_ARG_GETPROTO_R
+-+#endif
+-+
+- /* BeOS has glibc but not the glibc-style getprotobyxxx_r functions. */
+- #if (defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(XP_BEOS))
+- #define _PR_HAVE_GETPROTO_R
+diff --git a/rebar.config b/rebar.config
+index a86be90..d6803b5 100644
+--- a/rebar.config
++++ b/rebar.config
+@@ -8,8 +8,8 @@
+ {erl_opts, [warnings_as_errors]}.
+
+ {port_envs, [
+- {"DRV_CFLAGS", "$DRV_CFLAGS -I c_src/system/include/js -DXP_UNIX"},
+- {"DRV_LDFLAGS", "$DRV_LDFLAGS c_src/system/lib/libjs.a c_src/system/lib/libnspr4.a"},
++ {"DRV_CFLAGS", "$DRV_CFLAGS `pkg-config libjs --cflags`"},
++ {"DRV_LDFLAGS", "$DRV_LDFLAGS `pkg-config libjs --libs`"},
+
+ %% Define flags for enabling/disable 64 bit build of NSPR
+ {"-32$", "NSPR_SIXTYFOUR", "--disable-64bit"},
+@@ -28,6 +28,3 @@
+ {"darwin10.*-32$", "CFLAGS", "-m32"},
+ {"darwin10.*-32$", "LDFLAGS", "-arch i386"}
+ ]}.
+-
+-{pre_hooks, [{compile, "make c_src"}]}.
+-{post_hooks, [{clean, "make c_src_clean"}]}.
+diff --git a/rebar.mk b/rebar.mk
+deleted file mode 100644
+index bfb4156..0000000
+--- a/rebar.mk
++++ /dev/null
+@@ -1,38 +0,0 @@
+-
+-REBAR_URL ?= http://github.com/downloads/basho/rebar/rebar
+-
+-REBAR_GLOBAL ?= $(shell which rebar)
+-REBAR_LOCAL ?= $(shell which ./rebar)
+-REBAR_TARGET ?= $(dir $(shell which escript))
+-
+-ifneq ($(strip $(REBAR_LOCAL)), )
+-REBAR ?= $(REBAR_LOCAL)
+-else ifneq ($(strip $(REBAR_GLOBAL)), )
+-REBAR ?= $(REBAR_GLOBAL)
+-else
+-REBAR ?= rebar
+-$(warning Rebar not installed or available. Try 'make rebar-info')
+-endif
+-
+-ifneq ($(strip $(shell which wget)), )
+-REBAR_FETCH ?= wget --no-check-certificate -q -O - $(REBAR_URL)
+-else
+-REBAR_FETCH ?= curl -s -f $(REBAR_URL)
+-endif
+-
+-
+-rebar-info:
+- @echo "Rebar needs to be either on your path or present in the current" \
+- "working directory:\n" \
+- "* 'make rebar-install' will download and install it into your Erlang path (RECOMMENDED)\n" \
+- "* 'make rebar-get' will download it to your current working directory\n" \
+-
+-
+-rebar-install:
+- $(REBAR_FETCH) > $(REBAR_TARGET)/rebar
+- chmod a+x $(REBAR_TARGET)/rebar
+-
+-rebar-get:
+- $(REBAR_FETCH) > ./rebar
+- chmod u+x ./rebar
+-
--
-1.7.2.3
+1.7.10.4
diff --git a/erlang-js-0002-build-fix-for-js-1.8.5.patch b/erlang-js-0002-build-fix-for-js-1.8.5.patch
new file mode 100644
index 0000000..2d80eb7
--- /dev/null
+++ b/erlang-js-0002-build-fix-for-js-1.8.5.patch
@@ -0,0 +1,130 @@
+From 2ec99ed3dc6e893ec8df7de5155d7870a0f88c40 Mon Sep 17 00:00:00 2001
+From: Martin Stransky <stransky at redhat.com>
+Date: Tue, 3 Jul 2012 19:03:44 +0400
+Subject: [PATCH 2/7] build fix for js 1.8.5
+
+---
+ c_src/spidermonkey.c | 53 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 30 insertions(+), 23 deletions(-)
+
+diff --git a/c_src/spidermonkey.c b/c_src/spidermonkey.c
+index 667a8d4..569e2a6 100644
+--- a/c_src/spidermonkey.c
++++ b/c_src/spidermonkey.c
+@@ -26,7 +26,7 @@ void free_error(spidermonkey_state *state);
+ /* The class of the global object. */
+ static JSClass global_class = {
+ "global", JSCLASS_GLOBAL_FLAGS,
+- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
++ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
+ JSCLASS_NO_OPTIONAL_MEMBERS
+ };
+@@ -39,9 +39,11 @@ char *copy_string(const char *source) {
+ return retval;
+ }
+
+-char *copy_jsstring(JSString *source) {
+- char *buf = JS_GetStringBytes(source);
+- return copy_string(buf);
++char *copy_jsstring(JSContext *cx, JSString *source) {
++ char *buf = JS_EncodeString(cx, source);
++ char *retval = copy_string(buf);
++ JS_free(cx, buf);
++ return retval;
+ }
+
+ void begin_request(spidermonkey_vm *vm) {
+@@ -76,7 +78,7 @@ void on_error(JSContext *context, const char *message, JSErrorReport *report) {
+ }
+ }
+
+-JSBool on_branch(JSContext *context, JSScript *script) {
++JSBool on_branch(JSContext *context) {
+ JSBool return_value = JS_TRUE;
+ spidermonkey_state *state = (spidermonkey_state *) JS_GetContextPrivate(context);
+ state->branch_count++;
+@@ -114,8 +116,8 @@ JSBool js_log(JSContext *cx, uintN argc, jsval *vp) {
+ jsval *argv = JS_ARGV(cx, vp);
+ jsval jsfilename = argv[0];
+ jsval jsoutput = argv[1];
+- char *filename = JS_GetStringBytes(JS_ValueToString(cx, jsfilename));
+- char *output = JS_GetStringBytes(JS_ValueToString(cx, jsoutput));
++ char *filename = JS_EncodeString(cx, JS_ValueToString(cx, jsfilename));
++ char *output = JS_EncodeString(cx, JS_ValueToString(cx, jsoutput));
+ FILE *fd = fopen(filename, "a+");
+ if (fd != NULL) {
+ write_timestamp(fd);
+@@ -127,6 +129,8 @@ JSBool js_log(JSContext *cx, uintN argc, jsval *vp) {
+ else {
+ JS_SET_RVAL(cx, vp, JSVAL_FALSE);
+ }
++ JS_free(cx, filename);
++ JS_free(cx, output);
+ }
+ return JSVAL_TRUE;
+ }
+@@ -153,14 +157,14 @@ spidermonkey_vm *sm_initialize(long thread_stack, long heap_size) {
+ JS_SetOptions(vm->context, JSOPTION_STRICT);
+ JS_SetOptions(vm->context, JSOPTION_COMPILE_N_GO);
+ JS_SetOptions(vm->context, JSVERSION_LATEST);
+- vm->global = JS_NewObject(vm->context, &global_class, NULL, NULL);
++ vm->global = JS_NewCompartmentAndGlobalObject(vm->context, &global_class, NULL);
+ JS_InitStandardClasses(vm->context, vm->global);
+ JS_SetErrorReporter(vm->context, on_error);
+- JS_SetBranchCallback(vm->context, on_branch);
++ JS_SetOperationCallback(vm->context, on_branch);
+ JS_SetContextPrivate(vm->context, state);
+- JSNative *funptr = (JSNative *) *js_log;
++ JSNative funptr = (JSNative) js_log;
+ JS_DefineFunction(vm->context, JS_GetGlobalObject(vm->context), "ejsLog", funptr,
+- 0, JSFUN_FAST_NATIVE);
++ 0, 0);
+ end_request(vm);
+
+ return vm;
+@@ -256,7 +260,7 @@ void free_error(spidermonkey_state *state) {
+
+ char *sm_eval(spidermonkey_vm *vm, const char *filename, const char *code, int handle_retval) {
+ char *retval = NULL;
+- JSScript *script;
++ JSObject *script;
+ jsval result;
+
+ if (code == NULL) {
+@@ -275,18 +279,21 @@ char *sm_eval(spidermonkey_vm *vm, const char *filename, const char *code, int h
+ state = (spidermonkey_state *) JS_GetContextPrivate(vm->context);
+ if (state->error == NULL) {
+ if (handle_retval) {
+- if (JSVAL_IS_STRING(result)) {
+- JSString *str = JS_ValueToString(vm->context, result);
+- retval = copy_jsstring(str);
+- }
+- else if(strcmp(JS_GetStringBytes(JS_ValueToString(vm->context, result)), "undefined") == 0) {
+- retval = copy_string("{\"error\": \"Expression returned undefined\", \"lineno\": 0, \"source\": \"unknown\"}");
+- }
+- else {
+- retval = copy_string("{\"error\": \"non-JSON return value\", \"lineno\": 0, \"source\": \"unknown\"}");
+- }
++ if (JSVAL_IS_STRING(result)) {
++ JSString *str = JS_ValueToString(vm->context, result);
++ retval = copy_jsstring(vm->context, str);
++ }
++ else {
++ char *tmp = JS_EncodeString(vm->context, JS_ValueToString(vm->context, result));
++ if(strcmp(tmp, "undefined") == 0) {
++ retval = copy_string("{\"error\": \"Expression returned undefined\", \"lineno\": 0, \"source\": \"unknown\"}");
++ }
++ else {
++ retval = copy_string("{\"error\": \"non-JSON return value\", \"lineno\": 0, \"source\": \"unknown\"}");
++ }
++ JS_free(vm->context, tmp);
++ }
+ }
+- JS_DestroyScript(vm->context, script);
+ }
+ else {
+ retval = error_to_json(state->error);
+--
+1.7.10.4
+
diff --git a/erlang-js-0003-Fix-deprecation-warning.patch b/erlang-js-0003-Fix-deprecation-warning.patch
new file mode 100644
index 0000000..fd72b01
--- /dev/null
+++ b/erlang-js-0003-Fix-deprecation-warning.patch
@@ -0,0 +1,26 @@
+From 4dc645a3e1bd8101c145c56b7755cbfff34ef77f Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Tue, 3 Jul 2012 19:07:47 +0400
+Subject: [PATCH 3/7] Fix deprecation warning
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ rebar.config | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rebar.config b/rebar.config
+index d6803b5..ff9bf9a 100644
+--- a/rebar.config
++++ b/rebar.config
+@@ -7,7 +7,7 @@
+
+ {erl_opts, [warnings_as_errors]}.
+
+-{port_envs, [
++{port_env, [
+ {"DRV_CFLAGS", "$DRV_CFLAGS `pkg-config libjs --cflags`"},
+ {"DRV_LDFLAGS", "$DRV_LDFLAGS `pkg-config libjs --libs`"},
+
+--
+1.7.10.4
+
diff --git a/erlang-js-0004-Use-mochiweb-instead-of-a-bundled-copies.patch b/erlang-js-0004-Use-mochiweb-instead-of-a-bundled-copies.patch
new file mode 100644
index 0000000..3256b70
--- /dev/null
+++ b/erlang-js-0004-Use-mochiweb-instead-of-a-bundled-copies.patch
@@ -0,0 +1,1174 @@
+From 0b2b8c5882d546c4f101c410e5ca8b954c11c39b Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Tue, 3 Jul 2012 22:50:21 +0400
+Subject: [PATCH 4/7] Use mochiweb instead of a bundled copies
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ ebin/erlang_js.app | 2 +-
+ src/js.erl | 6 +-
+ src/js_driver.erl | 6 +-
+ src/js_mochijson2.erl | 782 -------------------------------------------------
+ src/js_mochinum.erl | 290 ------------------
+ tests/eval_tests.erl | 2 +-
+ 6 files changed, 8 insertions(+), 1080 deletions(-)
+ delete mode 100644 src/js_mochijson2.erl
+ delete mode 100644 src/js_mochinum.erl
+
+diff --git a/ebin/erlang_js.app b/ebin/erlang_js.app
+index 65707cd..cf20f1d 100644
+--- a/ebin/erlang_js.app
++++ b/ebin/erlang_js.app
+@@ -2,7 +2,7 @@
+ {application, erlang_js,
+ [{description, "Interface between BEAM and JS"},
+ {vsn, "1.0.2"},
+- {modules, [erlang_js, erlang_js_sup, js, js_benchmark, js_cache, js_driver, js_drv_comm, js_memory, js_mochijson2, js_mochinum]},
++ {modules, [erlang_js, erlang_js_sup, js, js_benchmark, js_cache, js_driver, js_drv_comm, js_memory]},
+ {registered, [erlang_js_sup, js_cache]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {erlang_js, []}}]}.
+diff --git a/src/js.erl b/src/js.erl
+index 05f5e2b..1debfc9 100644
+--- a/src/js.erl
++++ b/src/js.erl
+@@ -69,11 +69,11 @@ build_bindings([{VarName, Value}|T], Accum) ->
+ false ->
+ VarName
+ end,
+- build_bindings(T, [[FinalVarName, "=", js_mochijson2:encode(Value), ";"]|Accum]).
++ build_bindings(T, [[FinalVarName, "=", mochijson2:encode(Value), ";"]|Accum]).
+
+ build_arg_list([], Accum) ->
+ lists:reverse(Accum);
+ build_arg_list([H|[]], Accum) ->
+- build_arg_list([], [js_mochijson2:encode(H)|Accum]);
++ build_arg_list([], [mochijson2:encode(H)|Accum]);
+ build_arg_list([H|T], Accum) ->
+- build_arg_list(T, [[js_mochijson2:encode(H), ","]|Accum]).
++ build_arg_list(T, [[mochijson2:encode(H), ","]|Accum]).
+diff --git a/src/js_driver.erl b/src/js_driver.erl
+index b86418f..123be7f 100644
+--- a/src/js_driver.erl
++++ b/src/js_driver.erl
+@@ -129,7 +129,7 @@ define_js(Ctx, FileName, Js, Timeout) when is_binary(FileName),
+ is_binary(Js) ->
+ case call_driver(Ctx, "dj", [FileName, Js], Timeout) of
+ {error, ErrorJson} when is_binary(ErrorJson) ->
+- {struct, [{<<"error">>, {struct, Error}}]} = js_mochijson2:decode(ErrorJson),
++ {struct, [{<<"error">>, {struct, Error}}]} = mochijson2:decode(ErrorJson),
+ {error, Error};
+ ok ->
+ ok
+@@ -147,9 +147,9 @@ eval_js(Ctx, {file, FileName}, Timeout) ->
+ eval_js(Ctx, Js, Timeout) when is_binary(Js) ->
+ case call_driver(Ctx, "ej", [<<"<unnamed>">>, jsonify(Js)], Timeout) of
+ {ok, Result} ->
+- {ok, js_mochijson2:decode(Result)};
++ {ok, mochijson2:decode(Result)};
+ {error, ErrorJson} when is_binary(ErrorJson) ->
+- case js_mochijson2:decode(ErrorJson) of
++ case mochijson2:decode(ErrorJson) of
+ {struct, [{<<"error">>, {struct, Error}}]} ->
+ {error, Error};
+ _ ->
+diff --git a/src/js_mochijson2.erl b/src/js_mochijson2.erl
+deleted file mode 100644
+index f33c726..0000000
+--- a/src/js_mochijson2.erl
++++ /dev/null
+@@ -1,782 +0,0 @@
+-%% @author Bob Ippolito <bob at mochimedia.com>
+-%% @copyright 2007 Mochi Media, Inc.
+-
+-%% @doc Yet another JSON (RFC 4627) library for Erlang. mochijson2 works
+-%% with binaries as strings, arrays as lists (without an {array, _})
+-%% wrapper and it only knows how to decode UTF-8 (and ASCII).
+-
+--module(js_mochijson2).
+--author('bob at mochimedia.com').
+--export([encoder/1, encode/1]).
+--export([decoder/1, decode/1]).
+-
+-% This is a macro to placate syntax highlighters..
+--define(Q, $\").
+--define(ADV_COL(S, N), S#decoder{offset=N+S#decoder.offset,
+- column=N+S#decoder.column}).
+--define(INC_COL(S), S#decoder{offset=1+S#decoder.offset,
+- column=1+S#decoder.column}).
+--define(INC_LINE(S), S#decoder{offset=1+S#decoder.offset,
+- column=1,
+- line=1+S#decoder.line}).
+--define(INC_CHAR(S, C),
+- case C of
+- $\n ->
+- S#decoder{column=1,
+- line=1+S#decoder.line,
+- offset=1+S#decoder.offset};
+- _ ->
+- S#decoder{column=1+S#decoder.column,
+- offset=1+S#decoder.offset}
+- end).
+--define(IS_WHITESPACE(C),
+- (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)).
+-
+-%% @type iolist() = [char() | binary() | iolist()]
+-%% @type iodata() = iolist() | binary()
+-%% @type json_string() = atom | binary()
+-%% @type json_number() = integer() | float()
+-%% @type json_array() = [json_term()]
+-%% @type json_object() = {struct, [{json_string(), json_term()}]}
+-%% @type json_iolist() = {json, iolist()}
+-%% @type json_term() = json_string() | json_number() | json_array() |
+-%% json_object() | json_iolist()
+-
+--record(encoder, {handler=null,
+- utf8=false}).
+-
+--record(decoder, {object_hook=null,
+- offset=0,
+- line=1,
+- column=1,
+- state=null}).
+-
+-%% @spec encoder([encoder_option()]) -> function()
+-%% @doc Create an encoder/1 with the given options.
+-%% @type encoder_option() = handler_option() | utf8_option()
+-%% @type utf8_option() = boolean(). Emit unicode as utf8 (default - false)
+-encoder(Options) ->
+- State = parse_encoder_options(Options, #encoder{}),
+- fun (O) -> json_encode(O, State) end.
+-
+-%% @spec encode(json_term()) -> iolist()
+-%% @doc Encode the given as JSON to an iolist.
+-encode(Any) ->
+- json_encode(Any, #encoder{}).
+-
+-%% @spec decoder([decoder_option()]) -> function()
+-%% @doc Create a decoder/1 with the given options.
+-decoder(Options) ->
+- State = parse_decoder_options(Options, #decoder{}),
+- fun (O) -> json_decode(O, State) end.
+-
+-%% @spec decode(iolist()) -> json_term()
+-%% @doc Decode the given iolist to Erlang terms.
+-decode(S) ->
+- json_decode(S, #decoder{}).
+-
+-%% Internal API
+-
+-parse_encoder_options([], State) ->
+- State;
+-parse_encoder_options([{handler, Handler} | Rest], State) ->
+- parse_encoder_options(Rest, State#encoder{handler=Handler});
+-parse_encoder_options([{utf8, Switch} | Rest], State) ->
+- parse_encoder_options(Rest, State#encoder{utf8=Switch}).
+-
+-parse_decoder_options([], State) ->
+- State;
+-parse_decoder_options([{object_hook, Hook} | Rest], State) ->
+- parse_decoder_options(Rest, State#decoder{object_hook=Hook}).
+-
+-json_encode(true, _State) ->
+- <<"true">>;
+-json_encode(false, _State) ->
+- <<"false">>;
+-json_encode(null, _State) ->
+- <<"null">>;
+-json_encode(I, _State) when is_integer(I) andalso I >= -2147483648 andalso I =< 2147483647 ->
+- %% Anything outside of 32-bit integers should be encoded as a float
+- integer_to_list(I);
+-json_encode(I, _State) when is_integer(I) ->
+- js_mochinum:digits(float(I));
+-json_encode(F, _State) when is_float(F) ->
+- js_mochinum:digits(F);
+-json_encode(S, State) when is_binary(S); is_atom(S) ->
+- json_encode_string(S, State);
+-json_encode(Array, State) when is_list(Array) ->
+- json_encode_array(Array, State);
+-json_encode({struct, Props}, State) when is_list(Props) ->
+- json_encode_proplist(Props, State);
+-json_encode({json, IoList}, _State) ->
+- IoList;
+-json_encode(Bad, #encoder{handler=null}) ->
+- exit({json_encode, {bad_term, Bad}});
+-json_encode(Bad, State=#encoder{handler=Handler}) ->
+- json_encode(Handler(Bad), State).
+-
+-json_encode_array([], _State) ->
+- <<"[]">>;
+-json_encode_array(L, State) ->
+- F = fun (O, Acc) ->
+- [$,, json_encode(O, State) | Acc]
+- end,
+- [$, | Acc1] = lists:foldl(F, "[", L),
+- lists:reverse([$\] | Acc1]).
+-
+-json_encode_proplist([], _State) ->
+- <<"{}">>;
+-json_encode_proplist(Props, State) ->
+- F = fun ({K, V}, Acc) ->
+- KS = json_encode_string(K, State),
+- VS = json_encode(V, State),
+- [$,, VS, $:, KS | Acc]
+- end,
+- [$, | Acc1] = lists:foldl(F, "{", Props),
+- lists:reverse([$\} | Acc1]).
+-
+-json_encode_string(A, State) when is_atom(A) ->
+- L = atom_to_list(A),
+- case json_string_is_safe(L) of
+- true ->
+- [?Q, L, ?Q];
+- false ->
+- json_encode_string_unicode(xmerl_ucs:from_utf8(L), State, [?Q])
+- end;
+-json_encode_string(B, State) when is_binary(B) ->
+- case json_bin_is_safe(B) of
+- true ->
+- [?Q, B, ?Q];
+- false ->
+- json_encode_string_unicode(xmerl_ucs:from_utf8(B), State, [?Q])
+- end;
+-json_encode_string(I, _State) when is_integer(I) ->
+- [?Q, integer_to_list(I), ?Q];
+-json_encode_string(L, State) when is_list(L) ->
+- case json_string_is_safe(L) of
+- true ->
+- [?Q, L, ?Q];
+- false ->
+- json_encode_string_unicode(L, State, [?Q])
+- end.
+-
+-json_string_is_safe([]) ->
+- true;
+-json_string_is_safe([C | Rest]) ->
+- case C of
+- ?Q ->
+- false;
+- $\\ ->
+- false;
+- $\b ->
+- false;
+- $\f ->
+- false;
+- $\n ->
+- false;
+- $\r ->
+- false;
+- $\t ->
+- false;
+- C when C >= 0, C < $\s; C >= 16#7f, C =< 16#10FFFF ->
+- false;
+- C when C < 16#7f ->
+- json_string_is_safe(Rest);
+- _ ->
+- false
+- end.
+-
+-json_bin_is_safe(<<>>) ->
+- true;
+-json_bin_is_safe(<<C, Rest/binary>>) ->
+- case C of
+- ?Q ->
+- false;
+- $\\ ->
+- false;
+- $\b ->
+- false;
+- $\f ->
+- false;
+- $\n ->
+- false;
+- $\r ->
+- false;
+- $\t ->
+- false;
+- C when C >= 0, C < $\s; C >= 16#7f ->
+- false;
+- C when C < 16#7f ->
+- json_bin_is_safe(Rest)
+- end.
+-
+-json_encode_string_unicode([], _State, Acc) ->
+- lists:reverse([$\" | Acc]);
+-json_encode_string_unicode([C | Cs], State, Acc) ->
+- Acc1 = case C of
+- ?Q ->
+- [?Q, $\\ | Acc];
+- %% Escaping solidus is only useful when trying to protect
+- %% against "</script>" injection attacks which are only
+- %% possible when JSON is inserted into a HTML document
+- %% in-line. mochijson2 does not protect you from this, so
+- %% if you do insert directly into HTML then you need to
+- %% uncomment the following case or escape the output of encode.
+- %%
+- %% $/ ->
+- %% [$/, $\\ | Acc];
+- %%
+- $\\ ->
+- [$\\, $\\ | Acc];
+- $\b ->
+- [$b, $\\ | Acc];
+- $\f ->
+- [$f, $\\ | Acc];
+- $\n ->
+- [$n, $\\ | Acc];
+- $\r ->
+- [$r, $\\ | Acc];
+- $\t ->
+- [$t, $\\ | Acc];
+- C when C >= 0, C < $\s ->
+- [unihex(C) | Acc];
+- C when C >= 16#7f, C =< 16#10FFFF, State#encoder.utf8 ->
+- [xmerl_ucs:to_utf8(C) | Acc];
+- C when C >= 16#7f, C =< 16#10FFFF, not State#encoder.utf8 ->
+- [unihex(C) | Acc];
+- C when C < 16#7f ->
+- [C | Acc];
+- _ ->
+- exit({json_encode, {bad_char, C}})
+- end,
+- json_encode_string_unicode(Cs, State, Acc1).
+-
+-hexdigit(C) when C >= 0, C =< 9 ->
+- C + $0;
+-hexdigit(C) when C =< 15 ->
+- C + $a - 10.
+-
+-unihex(C) when C < 16#10000 ->
+- <<D3:4, D2:4, D1:4, D0:4>> = <<C:16>>,
+- Digits = [hexdigit(D) || D <- [D3, D2, D1, D0]],
+- [$\\, $u | Digits];
+-unihex(C) when C =< 16#10FFFF ->
+- N = C - 16#10000,
+- S1 = 16#d800 bor ((N bsr 10) band 16#3ff),
+- S2 = 16#dc00 bor (N band 16#3ff),
+- [unihex(S1), unihex(S2)].
+-
+-json_decode(L, S) when is_list(L) ->
+- json_decode(iolist_to_binary(L), S);
+-json_decode(B, S) ->
+- {Res, S1} = decode1(B, S),
+- {eof, _} = tokenize(B, S1#decoder{state=trim}),
+- Res.
+-
+-decode1(B, S=#decoder{state=null}) ->
+- case tokenize(B, S#decoder{state=any}) of
+- {{const, C}, S1} ->
+- {C, S1};
+- {start_array, S1} ->
+- decode_array(B, S1);
+- {start_object, S1} ->
+- decode_object(B, S1)
+- end.
+-
+-make_object(V, #decoder{object_hook=null}) ->
+- V;
+-make_object(V, #decoder{object_hook=Hook}) ->
+- Hook(V).
+-
+-decode_object(B, S) ->
+- decode_object(B, S#decoder{state=key}, []).
+-
+-decode_object(B, S=#decoder{state=key}, Acc) ->
+- case tokenize(B, S) of
+- {end_object, S1} ->
+- V = make_object({struct, lists:reverse(Acc)}, S1),
+- {V, S1#decoder{state=null}};
+- {{const, K}, S1} ->
+- {colon, S2} = tokenize(B, S1),
+- {V, S3} = decode1(B, S2#decoder{state=null}),
+- decode_object(B, S3#decoder{state=comma}, [{K, V} | Acc])
+- end;
+-decode_object(B, S=#decoder{state=comma}, Acc) ->
+- case tokenize(B, S) of
+- {end_object, S1} ->
+- V = make_object({struct, lists:reverse(Acc)}, S1),
+- {V, S1#decoder{state=null}};
+- {comma, S1} ->
+- decode_object(B, S1#decoder{state=key}, Acc)
+- end.
+-
+-decode_array(B, S) ->
+- decode_array(B, S#decoder{state=any}, []).
+-
+-decode_array(B, S=#decoder{state=any}, Acc) ->
+- case tokenize(B, S) of
+- {end_array, S1} ->
+- {lists:reverse(Acc), S1#decoder{state=null}};
+- {start_array, S1} ->
+- {Array, S2} = decode_array(B, S1),
+- decode_array(B, S2#decoder{state=comma}, [Array | Acc]);
+- {start_object, S1} ->
+- {Array, S2} = decode_object(B, S1),
+- decode_array(B, S2#decoder{state=comma}, [Array | Acc]);
+- {{const, Const}, S1} ->
+- decode_array(B, S1#decoder{state=comma}, [Const | Acc])
+- end;
+-decode_array(B, S=#decoder{state=comma}, Acc) ->
+- case tokenize(B, S) of
+- {end_array, S1} ->
+- {lists:reverse(Acc), S1#decoder{state=null}};
+- {comma, S1} ->
+- decode_array(B, S1#decoder{state=any}, Acc)
+- end.
+-
+-tokenize_string(B, S=#decoder{offset=O}) ->
+- case tokenize_string_fast(B, O) of
+- {escape, O1} ->
+- Length = O1 - O,
+- S1 = ?ADV_COL(S, Length),
+- <<_:O/binary, Head:Length/binary, _/binary>> = B,
+- tokenize_string(B, S1, lists:reverse(binary_to_list(Head)));
+- O1 ->
+- Length = O1 - O,
+- <<_:O/binary, String:Length/binary, ?Q, _/binary>> = B,
+- {{const, String}, ?ADV_COL(S, Length + 1)}
+- end.
+-
+-tokenize_string_fast(B, O) ->
+- case B of
+- <<_:O/binary, ?Q, _/binary>> ->
+- O;
+- <<_:O/binary, $\\, _/binary>> ->
+- {escape, O};
+- <<_:O/binary, C1, _/binary>> when C1 < 128 ->
+- tokenize_string_fast(B, 1 + O);
+- <<_:O/binary, C1, C2, _/binary>> when C1 >= 194, C1 =< 223,
+- C2 >= 128, C2 =< 191 ->
+- tokenize_string_fast(B, 2 + O);
+- <<_:O/binary, C1, C2, C3, _/binary>> when C1 >= 224, C1 =< 239,
+- C2 >= 128, C2 =< 191,
+- C3 >= 128, C3 =< 191 ->
+- tokenize_string_fast(B, 3 + O);
+- <<_:O/binary, C1, C2, C3, C4, _/binary>> when C1 >= 240, C1 =< 244,
+- C2 >= 128, C2 =< 191,
+- C3 >= 128, C3 =< 191,
+- C4 >= 128, C4 =< 191 ->
+- tokenize_string_fast(B, 4 + O);
+- _ ->
+- throw(invalid_utf8)
+- end.
+-
+-tokenize_string(B, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, ?Q, _/binary>> ->
+- {{const, iolist_to_binary(lists:reverse(Acc))}, ?INC_COL(S)};
+- <<_:O/binary, "\\\"", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\" | Acc]);
+- <<_:O/binary, "\\\\", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\\ | Acc]);
+- <<_:O/binary, "\\/", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$/ | Acc]);
+- <<_:O/binary, "\\b", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\b | Acc]);
+- <<_:O/binary, "\\f", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\f | Acc]);
+- <<_:O/binary, "\\n", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\n | Acc]);
+- <<_:O/binary, "\\r", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\r | Acc]);
+- <<_:O/binary, "\\t", _/binary>> ->
+- tokenize_string(B, ?ADV_COL(S, 2), [$\t | Acc]);
+- <<_:O/binary, "\\u", C3, C2, C1, C0, Rest/binary>> ->
+- C = erlang:list_to_integer([C3, C2, C1, C0], 16),
+- if C > 16#D7FF, C < 16#DC00 ->
+- %% coalesce UTF-16 surrogate pair
+- <<"\\u", D3, D2, D1, D0, _/binary>> = Rest,
+- D = erlang:list_to_integer([D3,D2,D1,D0], 16),
+- [CodePoint] = xmerl_ucs:from_utf16be(<<C:16/big-unsigned-integer,
+- D:16/big-unsigned-integer>>),
+- Acc1 = lists:reverse(xmerl_ucs:to_utf8(CodePoint), Acc),
+- tokenize_string(B, ?ADV_COL(S, 12), Acc1);
+- true ->
+- Acc1 = lists:reverse(xmerl_ucs:to_utf8(C), Acc),
+- tokenize_string(B, ?ADV_COL(S, 6), Acc1)
+- end;
+- <<_:O/binary, C, _/binary>> ->
+- tokenize_string(B, ?INC_CHAR(S, C), [C | Acc])
+- end.
+-
+-tokenize_number(B, S) ->
+- case tokenize_number(B, sign, S, []) of
+- {{int, Int}, S1} ->
+- {{const, list_to_integer(Int)}, S1};
+- {{float, Float}, S1} ->
+- {{const, list_to_float(Float)}, S1}
+- end.
+-
+-tokenize_number(B, sign, S=#decoder{offset=O}, []) ->
+- case B of
+- <<_:O/binary, $-, _/binary>> ->
+- tokenize_number(B, int, ?INC_COL(S), [$-]);
+- _ ->
+- tokenize_number(B, int, S, [])
+- end;
+-tokenize_number(B, int, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, $0, _/binary>> ->
+- tokenize_number(B, frac, ?INC_COL(S), [$0 | Acc]);
+- <<_:O/binary, C, _/binary>> when C >= $1 andalso C =< $9 ->
+- tokenize_number(B, int1, ?INC_COL(S), [C | Acc])
+- end;
+-tokenize_number(B, int1, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 ->
+- tokenize_number(B, int1, ?INC_COL(S), [C | Acc]);
+- _ ->
+- tokenize_number(B, frac, S, Acc)
+- end;
+-tokenize_number(B, frac, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, $., C, _/binary>> when C >= $0, C =< $9 ->
+- tokenize_number(B, frac1, ?ADV_COL(S, 2), [C, $. | Acc]);
+- <<_:O/binary, E, _/binary>> when E =:= $e orelse E =:= $E ->
+- tokenize_number(B, esign, ?INC_COL(S), [$e, $0, $. | Acc]);
+- _ ->
+- {{int, lists:reverse(Acc)}, S}
+- end;
+-tokenize_number(B, frac1, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 ->
+- tokenize_number(B, frac1, ?INC_COL(S), [C | Acc]);
+- <<_:O/binary, E, _/binary>> when E =:= $e orelse E =:= $E ->
+- tokenize_number(B, esign, ?INC_COL(S), [$e | Acc]);
+- _ ->
+- {{float, lists:reverse(Acc)}, S}
+- end;
+-tokenize_number(B, esign, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when C =:= $- orelse C=:= $+ ->
+- tokenize_number(B, eint, ?INC_COL(S), [C | Acc]);
+- _ ->
+- tokenize_number(B, eint, S, Acc)
+- end;
+-tokenize_number(B, eint, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 ->
+- tokenize_number(B, eint1, ?INC_COL(S), [C | Acc])
+- end;
+-tokenize_number(B, eint1, S=#decoder{offset=O}, Acc) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 ->
+- tokenize_number(B, eint1, ?INC_COL(S), [C | Acc]);
+- _ ->
+- {{float, lists:reverse(Acc)}, S}
+- end.
+-
+-tokenize(B, S=#decoder{offset=O}) ->
+- case B of
+- <<_:O/binary, C, _/binary>> when ?IS_WHITESPACE(C) ->
+- tokenize(B, ?INC_CHAR(S, C));
+- <<_:O/binary, "{", _/binary>> ->
+- {start_object, ?INC_COL(S)};
+- <<_:O/binary, "}", _/binary>> ->
+- {end_object, ?INC_COL(S)};
+- <<_:O/binary, "[", _/binary>> ->
+- {start_array, ?INC_COL(S)};
+- <<_:O/binary, "]", _/binary>> ->
+- {end_array, ?INC_COL(S)};
+- <<_:O/binary, ",", _/binary>> ->
+- {comma, ?INC_COL(S)};
+- <<_:O/binary, ":", _/binary>> ->
+- {colon, ?INC_COL(S)};
+- <<_:O/binary, "null", _/binary>> ->
+- {{const, null}, ?ADV_COL(S, 4)};
+- <<_:O/binary, "true", _/binary>> ->
+- {{const, true}, ?ADV_COL(S, 4)};
+- <<_:O/binary, "false", _/binary>> ->
+- {{const, false}, ?ADV_COL(S, 5)};
+- <<_:O/binary, "\"", _/binary>> ->
+- tokenize_string(B, ?INC_COL(S));
+- <<_:O/binary, C, _/binary>> when (C >= $0 andalso C =< $9)
+- orelse C =:= $- ->
+- tokenize_number(B, S);
+- <<_:O/binary>> ->
+- trim = S#decoder.state,
+- {eof, S}
+- end.
+-%%
+-%% Tests
+-%%
+--ifdef(TEST).
+--include_lib("eunit/include/eunit.hrl").
+-
+-
+-%% testing constructs borrowed from the Yaws JSON implementation.
+-
+-%% Create an object from a list of Key/Value pairs.
+-
+-obj_new() ->
+- {struct, []}.
+-
+-is_obj({struct, Props}) ->
+- F = fun ({K, _}) when is_binary(K) -> true end,
+- lists:all(F, Props).
+-
+-obj_from_list(Props) ->
+- Obj = {struct, Props},
+- ?assert(is_obj(Obj)),
+- Obj.
+-
+-%% Test for equivalence of Erlang terms.
+-%% Due to arbitrary order of construction, equivalent objects might
+-%% compare unequal as erlang terms, so we need to carefully recurse
+-%% through aggregates (tuples and objects).
+-
+-equiv({struct, Props1}, {struct, Props2}) ->
+- equiv_object(Props1, Props2);
+-equiv(L1, L2) when is_list(L1), is_list(L2) ->
+- equiv_list(L1, L2);
+-equiv(N1, N2) when is_number(N1), is_number(N2) -> N1 == N2;
+-equiv(B1, B2) when is_binary(B1), is_binary(B2) -> B1 == B2;
+-equiv(A, A) when A =:= true orelse A =:= false orelse A =:= null -> true.
+-
+-%% Object representation and traversal order is unknown.
+-%% Use the sledgehammer and sort property lists.
+-
+-equiv_object(Props1, Props2) ->
+- L1 = lists:keysort(1, Props1),
+- L2 = lists:keysort(1, Props2),
+- Pairs = lists:zip(L1, L2),
+- true = lists:all(fun({{K1, V1}, {K2, V2}}) ->
+- equiv(K1, K2) and equiv(V1, V2)
+- end, Pairs).
+-
+-%% Recursively compare tuple elements for equivalence.
+-
+-equiv_list([], []) ->
+- true;
+-equiv_list([V1 | L1], [V2 | L2]) ->
+- equiv(V1, V2) andalso equiv_list(L1, L2).
+-
+-decode_test() ->
+- [1199344435545.0, 1] = decode(<<"[1199344435545.0,1]">>),
+- <<16#F0,16#9D,16#9C,16#95>> = decode([34,"\\ud835","\\udf15",34]).
+-
+-e2j_vec_test() ->
+- test_one(e2j_test_vec(utf8), 1).
+-
+-test_one([], _N) ->
+- %% io:format("~p tests passed~n", [N-1]),
+- ok;
+-test_one([{E, J} | Rest], N) ->
+- %% io:format("[~p] ~p ~p~n", [N, E, J]),
+- true = equiv(E, decode(J)),
+- true = equiv(E, decode(encode(E))),
+- test_one(Rest, 1+N).
+-
+-e2j_test_vec(utf8) ->
+- [
+- {1, "1"},
+- {3.1416, "3.14160"}, %% text representation may truncate, trail zeroes
+- {-1, "-1"},
+- {-3.1416, "-3.14160"},
+- {12.0e10, "1.20000e+11"},
+- {1.234E+10, "1.23400e+10"},
+- {-1.234E-10, "-1.23400e-10"},
+- {10.0, "1.0e+01"},
+- {123.456, "1.23456E+2"},
+- {10.0, "1e1"},
+- {<<"foo">>, "\"foo\""},
+- {<<"foo", 5, "bar">>, "\"foo\\u0005bar\""},
+- {<<"">>, "\"\""},
+- {<<"\n\n\n">>, "\"\\n\\n\\n\""},
+- {<<"\" \b\f\r\n\t\"">>, "\"\\\" \\b\\f\\r\\n\\t\\\"\""},
+- {obj_new(), "{}"},
+- {obj_from_list([{<<"foo">>, <<"bar">>}]), "{\"foo\":\"bar\"}"},
+- {obj_from_list([{<<"foo">>, <<"bar">>}, {<<"baz">>, 123}]),
+- "{\"foo\":\"bar\",\"baz\":123}"},
+- {[], "[]"},
+- {[[]], "[[]]"},
+- {[1, <<"foo">>], "[1,\"foo\"]"},
+-
+- %% json array in a json object
+- {obj_from_list([{<<"foo">>, [123]}]),
+- "{\"foo\":[123]}"},
+-
+- %% json object in a json object
+- {obj_from_list([{<<"foo">>, obj_from_list([{<<"bar">>, true}])}]),
+- "{\"foo\":{\"bar\":true}}"},
+-
+- %% fold evaluation order
+- {obj_from_list([{<<"foo">>, []},
+- {<<"bar">>, obj_from_list([{<<"baz">>, true}])},
+- {<<"alice">>, <<"bob">>}]),
+- "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}"},
+-
+- %% json object in a json array
+- {[-123, <<"foo">>, obj_from_list([{<<"bar">>, []}]), null],
+- "[-123,\"foo\",{\"bar\":[]},null]"}
+- ].
+-
+-%% test utf8 encoding
+-encoder_utf8_test() ->
+- %% safe conversion case (default)
+- [34,"\\u0001","\\u0442","\\u0435","\\u0441","\\u0442",34] =
+- encode(<<1,"\321\202\320\265\321\201\321\202">>),
+-
+- %% raw utf8 output (optional)
+- Enc = encoder([{utf8, true}]),
+- [34,"\\u0001",[209,130],[208,181],[209,129],[209,130],34] =
+- Enc(<<1,"\321\202\320\265\321\201\321\202">>).
+-
+-input_validation_test() ->
+- Good = [
+- {16#00A3, <<?Q, 16#C2, 16#A3, ?Q>>}, %% pound
+- {16#20AC, <<?Q, 16#E2, 16#82, 16#AC, ?Q>>}, %% euro
+- {16#10196, <<?Q, 16#F0, 16#90, 16#86, 16#96, ?Q>>} %% denarius
+- ],
+- lists:foreach(fun({CodePoint, UTF8}) ->
+- Expect = list_to_binary(xmerl_ucs:to_utf8(CodePoint)),
+- Expect = decode(UTF8)
+- end, Good),
+-
+- Bad = [
+- %% 2nd, 3rd, or 4th byte of a multi-byte sequence w/o leading byte
+- <<?Q, 16#80, ?Q>>,
+- %% missing continuations, last byte in each should be 80-BF
+- <<?Q, 16#C2, 16#7F, ?Q>>,
+- <<?Q, 16#E0, 16#80,16#7F, ?Q>>,
+- <<?Q, 16#F0, 16#80, 16#80, 16#7F, ?Q>>,
+- %% we don't support code points > 10FFFF per RFC 3629
+- <<?Q, 16#F5, 16#80, 16#80, 16#80, ?Q>>
+- ],
+- lists:foreach(
+- fun(X) ->
+- ok = try decode(X) catch invalid_utf8 -> ok end,
+- %% could be {ucs,{bad_utf8_character_code}} or
+- %% {json_encode,{bad_char,_}}
+- {'EXIT', _} = (catch encode(X))
+- end, Bad).
+-
+-inline_json_test() ->
+- ?assertEqual(<<"\"iodata iodata\"">>,
+- iolist_to_binary(
+- encode({json, [<<"\"iodata">>, " iodata\""]}))),
+- ?assertEqual({struct, [{<<"key">>, <<"iodata iodata">>}]},
+- decode(
+- encode({struct,
+- [{key, {json, [<<"\"iodata">>, " iodata\""]}}]}))),
+- ok.
+-
+-big_unicode_test() ->
+- UTF8Seq = list_to_binary(xmerl_ucs:to_utf8(16#0001d120)),
+- ?assertEqual(
+- <<"\"\\ud834\\udd20\"">>,
+- iolist_to_binary(encode(UTF8Seq))),
+- ?assertEqual(
+- UTF8Seq,
+- decode(iolist_to_binary(encode(UTF8Seq)))),
+- ok.
+-
+-custom_decoder_test() ->
+- ?assertEqual(
+- {struct, [{<<"key">>, <<"value">>}]},
+- (decoder([]))("{\"key\": \"value\"}")),
+- F = fun ({struct, [{<<"key">>, <<"value">>}]}) -> win end,
+- ?assertEqual(
+- win,
+- (decoder([{object_hook, F}]))("{\"key\": \"value\"}")),
+- ok.
+-
+-atom_test() ->
+- %% JSON native atoms
+- [begin
+- ?assertEqual(A, decode(atom_to_list(A))),
+- ?assertEqual(iolist_to_binary(atom_to_list(A)),
+- iolist_to_binary(encode(A)))
+- end || A <- [true, false, null]],
+- %% Atom to string
+- ?assertEqual(
+- <<"\"foo\"">>,
+- iolist_to_binary(encode(foo))),
+- ?assertEqual(
+- <<"\"\\ud834\\udd20\"">>,
+- iolist_to_binary(encode(list_to_atom(xmerl_ucs:to_utf8(16#0001d120))))),
+- ok.
+-
+-key_encode_test() ->
+- %% Some forms are accepted as keys that would not be strings in other
+- %% cases
+- ?assertEqual(
+- <<"{\"foo\":1}">>,
+- iolist_to_binary(encode({struct, [{foo, 1}]}))),
+- ?assertEqual(
+- <<"{\"foo\":1}">>,
+- iolist_to_binary(encode({struct, [{<<"foo">>, 1}]}))),
+- ?assertEqual(
+- <<"{\"foo\":1}">>,
+- iolist_to_binary(encode({struct, [{"foo", 1}]}))),
+- ?assertEqual(
+- <<"{\"\\ud834\\udd20\":1}">>,
+- iolist_to_binary(
+- encode({struct, [{[16#0001d120], 1}]}))),
+- ?assertEqual(
+- <<"{\"1\":1}">>,
+- iolist_to_binary(encode({struct, [{1, 1}]}))),
+- ok.
+-
+-unsafe_chars_test() ->
+- Chars = "\"\\\b\f\n\r\t",
+- [begin
+- ?assertEqual(false, json_string_is_safe([C])),
+- ?assertEqual(false, json_bin_is_safe(<<C>>)),
+- ?assertEqual(<<C>>, decode(encode(<<C>>)))
+- end || C <- Chars],
+- ?assertEqual(
+- false,
+- json_string_is_safe([16#0001d120])),
+- ?assertEqual(
+- false,
+- json_bin_is_safe(list_to_binary(xmerl_ucs:to_utf8(16#0001d120)))),
+- ?assertEqual(
+- [16#0001d120],
+- xmerl_ucs:from_utf8(
+- binary_to_list(
+- decode(encode(list_to_atom(xmerl_ucs:to_utf8(16#0001d120))))))),
+- ?assertEqual(
+- false,
+- json_string_is_safe([16#110000])),
+- ?assertEqual(
+- false,
+- json_bin_is_safe(list_to_binary(xmerl_ucs:to_utf8([16#110000])))),
+- %% solidus can be escaped but isn't unsafe by default
+- ?assertEqual(
+- <<"/">>,
+- decode(<<"\"\\/\"">>)),
+- ok.
+-
+-int_test() ->
+- ?assertEqual(0, decode("0")),
+- ?assertEqual(1, decode("1")),
+- ?assertEqual(11, decode("11")),
+- ok.
+-
+-float_fallback_test() ->
+- ?assertEqual(<<"-2147483649.0">>, iolist_to_binary(encode(-2147483649))),
+- ?assertEqual(<<"2147483648.0">>, iolist_to_binary(encode(2147483648))),
+- ok.
+-
+-handler_test() ->
+- ?assertEqual(
+- {'EXIT',{json_encode,{bad_term,{}}}},
+- catch encode({})),
+- F = fun ({}) -> [] end,
+- ?assertEqual(
+- <<"[]">>,
+- iolist_to_binary((encoder([{handler, F}]))({}))),
+- ok.
+-
+--endif.
+diff --git a/src/js_mochinum.erl b/src/js_mochinum.erl
+deleted file mode 100644
+index ca09ca6..0000000
+--- a/src/js_mochinum.erl
++++ /dev/null
+@@ -1,290 +0,0 @@
+-%% @copyright 2007 Mochi Media, Inc.
+-%% @author Bob Ippolito <bob at mochimedia.com>
+-
+-%% @doc Useful numeric algorithms for floats that cover some deficiencies
+-%% in the math module. More interesting is digits/1, which implements
+-%% the algorithm from:
+-%% http://www.cs.indiana.edu/~burger/fp/index.html
+-%% See also "Printing Floating-Point Numbers Quickly and Accurately"
+-%% in Proceedings of the SIGPLAN '96 Conference on Programming Language
+-%% Design and Implementation.
+-
+-%% Renamed to js_mochinum to prevent codepath conflicts
+--module(js_mochinum).
+--author("Bob Ippolito <bob at mochimedia.com>").
+--export([digits/1, frexp/1, int_pow/2, int_ceil/1, test/0]).
+-
+-%% IEEE 754 Float exponent bias
+--define(FLOAT_BIAS, 1022).
+--define(MIN_EXP, -1074).
+--define(BIG_POW, 4503599627370496).
+-
+-%% External API
+-
+-%% @spec digits(number()) -> string()
+-%% @doc Returns a string that accurately represents the given integer or float
+-%% using a conservative amount of digits. Great for generating
+-%% human-readable output, or compact ASCII serializations for floats.
+-digits(N) when is_integer(N) ->
+- integer_to_list(N);
+-digits(0.0) ->
+- "0.0";
+-digits(Float) ->
+- {Frac, Exp} = frexp(Float),
+- Exp1 = Exp - 53,
+- Frac1 = trunc(abs(Frac) * (1 bsl 53)),
+- [Place | Digits] = digits1(Float, Exp1, Frac1),
+- R = insert_decimal(Place, [$0 + D || D <- Digits]),
+- case Float < 0 of
+- true ->
+- [$- | R];
+- _ ->
+- R
+- end.
+-
+-%% @spec frexp(F::float()) -> {Frac::float(), Exp::float()}
+-%% @doc Return the fractional and exponent part of an IEEE 754 double,
+-%% equivalent to the libc function of the same name.
+-%% F = Frac * pow(2, Exp).
+-frexp(F) ->
+- frexp1(unpack(F)).
+-
+-%% @spec int_pow(X::integer(), N::integer()) -> Y::integer()
+-%% @doc Moderately efficient way to exponentiate integers.
+-%% int_pow(10, 2) = 100.
+-int_pow(_X, 0) ->
+- 1;
+-int_pow(X, N) when N > 0 ->
+- int_pow(X, N, 1).
+-
+-%% @spec int_ceil(F::float()) -> integer()
+-%% @doc Return the ceiling of F as an integer. The ceiling is defined as
+-%% F when F == trunc(F);
+-%% trunc(F) when F < 0;
+-%% trunc(F) + 1 when F > 0.
+-int_ceil(X) ->
+- T = trunc(X),
+- case (X - T) of
+- Neg when Neg < 0 -> T;
+- Pos when Pos > 0 -> T + 1;
+- _ -> T
+- end.
+-
+-
+-%% Internal API
+-
+-int_pow(X, N, R) when N < 2 ->
+- R * X;
+-int_pow(X, N, R) ->
+- int_pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end).
+-
+-insert_decimal(0, S) ->
+- "0." ++ S;
+-insert_decimal(Place, S) when Place > 0 ->
+- L = length(S),
+- case Place - L of
+- 0 ->
+- S ++ ".0";
+- N when N < 0 ->
+- {S0, S1} = lists:split(L + N, S),
+- S0 ++ "." ++ S1;
+- N when N < 6 ->
+- %% More places than digits
+- S ++ lists:duplicate(N, $0) ++ ".0";
+- _ ->
+- insert_decimal_exp(Place, S)
+- end;
+-insert_decimal(Place, S) when Place > -6 ->
+- "0." ++ lists:duplicate(abs(Place), $0) ++ S;
+-insert_decimal(Place, S) ->
+- insert_decimal_exp(Place, S).
+-
+-insert_decimal_exp(Place, S) ->
+- [C | S0] = S,
+- S1 = case S0 of
+- [] ->
+- "0";
+- _ ->
+- S0
+- end,
+- Exp = case Place < 0 of
+- true ->
+- "e-";
+- false ->
+- "e+"
+- end,
+- [C] ++ "." ++ S1 ++ Exp ++ integer_to_list(abs(Place - 1)).
+-
+-
+-digits1(Float, Exp, Frac) ->
+- Round = ((Frac band 1) =:= 0),
+- case Exp >= 0 of
+- true ->
+- BExp = 1 bsl Exp,
+- case (Frac /= ?BIG_POW) of
+- true ->
+- scale((Frac * BExp * 2), 2, BExp, BExp,
+- Round, Round, Float);
+- false ->
+- scale((Frac * BExp * 4), 4, (BExp * 2), BExp,
+- Round, Round, Float)
+- end;
+- false ->
+- case (Exp == ?MIN_EXP) orelse (Frac /= ?BIG_POW) of
+- true ->
+- scale((Frac * 2), 1 bsl (1 - Exp), 1, 1,
+- Round, Round, Float);
+- false ->
+- scale((Frac * 4), 1 bsl (2 - Exp), 2, 1,
+- Round, Round, Float)
+- end
+- end.
+-
+-scale(R, S, MPlus, MMinus, LowOk, HighOk, Float) ->
+- Est = int_ceil(math:log10(abs(Float)) - 1.0e-10),
+- %% Note that the scheme implementation uses a 326 element look-up table
+- %% for int_pow(10, N) where we do not.
+- case Est >= 0 of
+- true ->
+- fixup(R, S * int_pow(10, Est), MPlus, MMinus, Est,
+- LowOk, HighOk);
+- false ->
+- Scale = int_pow(10, -Est),
+- fixup(R * Scale, S, MPlus * Scale, MMinus * Scale, Est,
+- LowOk, HighOk)
+- end.
+-
+-fixup(R, S, MPlus, MMinus, K, LowOk, HighOk) ->
+- TooLow = case HighOk of
+- true ->
+- (R + MPlus) >= S;
+- false ->
+- (R + MPlus) > S
+- end,
+- case TooLow of
+- true ->
+- [(K + 1) | generate(R, S, MPlus, MMinus, LowOk, HighOk)];
+- false ->
+- [K | generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)]
+- end.
+-
+-generate(R0, S, MPlus, MMinus, LowOk, HighOk) ->
+- D = R0 div S,
+- R = R0 rem S,
+- TC1 = case LowOk of
+- true ->
+- R =< MMinus;
+- false ->
+- R < MMinus
+- end,
+- TC2 = case HighOk of
+- true ->
+- (R + MPlus) >= S;
+- false ->
+- (R + MPlus) > S
+- end,
+- case TC1 of
+- false ->
+- case TC2 of
+- false ->
+- [D | generate(R * 10, S, MPlus * 10, MMinus * 10,
+- LowOk, HighOk)];
+- true ->
+- [D + 1]
+- end;
+- true ->
+- case TC2 of
+- false ->
+- [D];
+- true ->
+- case R * 2 < S of
+- true ->
+- [D];
+- false ->
+- [D + 1]
+- end
+- end
+- end.
+-
+-unpack(Float) ->
+- <<Sign:1, Exp:11, Frac:52>> = <<Float:64/float>>,
+- {Sign, Exp, Frac}.
+-
+-frexp1({_Sign, 0, 0}) ->
+- {0.0, 0};
+-frexp1({Sign, 0, Frac}) ->
+- Exp = log2floor(Frac),
+- <<Frac1:64/float>> = <<Sign:1, ?FLOAT_BIAS:11, (Frac-1):52>>,
+- {Frac1, -(?FLOAT_BIAS) - 52 + Exp};
+-frexp1({Sign, Exp, Frac}) ->
+- <<Frac1:64/float>> = <<Sign:1, ?FLOAT_BIAS:11, Frac:52>>,
+- {Frac1, Exp - ?FLOAT_BIAS}.
+-
+-log2floor(Int) ->
+- log2floor(Int, 0).
+-
+-log2floor(0, N) ->
+- N;
+-log2floor(Int, N) ->
+- log2floor(Int bsr 1, 1 + N).
+-
+-
+-test() ->
+- ok = test_frexp(),
+- ok = test_int_ceil(),
+- ok = test_int_pow(),
+- ok = test_digits(),
+- ok.
+-
+-test_int_ceil() ->
+- 1 = int_ceil(0.0001),
+- 0 = int_ceil(0.0),
+- 1 = int_ceil(0.99),
+- 1 = int_ceil(1.0),
+- -1 = int_ceil(-1.5),
+- -2 = int_ceil(-2.0),
+- ok.
+-
+-test_int_pow() ->
+- 1 = int_pow(1, 1),
+- 1 = int_pow(1, 0),
+- 1 = int_pow(10, 0),
+- 10 = int_pow(10, 1),
+- 100 = int_pow(10, 2),
+- 1000 = int_pow(10, 3),
+- ok.
+-
+-test_digits() ->
+- "0" = digits(0),
+- "0.0" = digits(0.0),
+- "1.0" = digits(1.0),
+- "-1.0" = digits(-1.0),
+- "0.1" = digits(0.1),
+- "0.01" = digits(0.01),
+- "0.001" = digits(0.001),
+- ok.
+-
+-test_frexp() ->
+- %% zero
+- {0.0, 0} = frexp(0.0),
+- %% one
+- {0.5, 1} = frexp(1.0),
+- %% negative one
+- {-0.5, 1} = frexp(-1.0),
+- %% small denormalized number
+- %% 4.94065645841246544177e-324
+- <<SmallDenorm/float>> = <<0,0,0,0,0,0,0,1>>,
+- {0.5, -1073} = frexp(SmallDenorm),
+- %% large denormalized number
+- %% 2.22507385850720088902e-308
+- <<BigDenorm/float>> = <<0,15,255,255,255,255,255,255>>,
+- {0.99999999999999978, -1022} = frexp(BigDenorm),
+- %% small normalized number
+- %% 2.22507385850720138309e-308
+- <<SmallNorm/float>> = <<0,16,0,0,0,0,0,0>>,
+- {0.5, -1021} = frexp(SmallNorm),
+- %% large normalized number
+- %% 1.79769313486231570815e+308
+- <<LargeNorm/float>> = <<127,239,255,255,255,255,255,255>>,
+- {0.99999999999999989, 1024} = frexp(LargeNorm),
+- ok.
+diff --git a/tests/eval_tests.erl b/tests/eval_tests.erl
+index ee9b45d..9133cf2 100644
+--- a/tests/eval_tests.erl
++++ b/tests/eval_tests.erl
+@@ -79,7 +79,7 @@ charset_test_() ->
+ json_test_() ->
+ [fun() ->
+ Struct = {struct, [{<<"test">>, <<"1">>}]},
+- ?assertMatch(Struct, js_mochijson2:decode(js_mochijson2:encode(Struct))) end].
++ ?assertMatch(Struct, mochijson2:decode(mochijson2:encode(Struct))) end].
+
+ error_test_() ->
+ [{setup, fun test_util:port_setup/0,
+--
+1.7.10.4
+
diff --git a/erlang-js-0005-Use-standard-layout-for-rebar.patch b/erlang-js-0005-Use-standard-layout-for-rebar.patch
new file mode 100644
index 0000000..1a089b6
--- /dev/null
+++ b/erlang-js-0005-Use-standard-layout-for-rebar.patch
@@ -0,0 +1,558 @@
+From 59af93df4e924db6e2652a7e8775977b34fb6b33 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Tue, 3 Jul 2012 22:58:22 +0400
+Subject: [PATCH 5/7] Use standard layout for rebar
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ ebin/erlang_js.app | 8 ----
+ src/erlang_js.app.src | 8 ++++
+ test/driver_tests.erl | 34 +++++++++++++
+ test/eval_tests.erl | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
+ test/test_suite.erl | 7 +++
+ test/test_util.erl | 54 +++++++++++++++++++++
+ tests/Emakefile | 4 --
+ tests/driver_tests.erl | 34 -------------
+ tests/eval_tests.erl | 124 ------------------------------------------------
+ tests/test_suite.erl | 7 ---
+ tests/test_util.erl | 54 ---------------------
+ 11 files changed, 227 insertions(+), 231 deletions(-)
+ delete mode 100644 ebin/erlang_js.app
+ create mode 100644 src/erlang_js.app.src
+ create mode 100644 test/driver_tests.erl
+ create mode 100644 test/eval_tests.erl
+ create mode 100644 test/test_suite.erl
+ create mode 100644 test/test_util.erl
+ delete mode 100644 tests/Emakefile
+ delete mode 100644 tests/driver_tests.erl
+ delete mode 100644 tests/eval_tests.erl
+ delete mode 100644 tests/test_suite.erl
+ delete mode 100644 tests/test_util.erl
+
+diff --git a/ebin/erlang_js.app b/ebin/erlang_js.app
+deleted file mode 100644
+index cf20f1d..0000000
+--- a/ebin/erlang_js.app
++++ /dev/null
+@@ -1,8 +0,0 @@
+-% -*- mode: erlang -*-
+-{application, erlang_js,
+- [{description, "Interface between BEAM and JS"},
+- {vsn, "1.0.2"},
+- {modules, [erlang_js, erlang_js_sup, js, js_benchmark, js_cache, js_driver, js_drv_comm, js_memory]},
+- {registered, [erlang_js_sup, js_cache]},
+- {applications, [kernel, stdlib, sasl]},
+- {mod, {erlang_js, []}}]}.
+diff --git a/src/erlang_js.app.src b/src/erlang_js.app.src
+new file mode 100644
+index 0000000..7ebc7b6
+--- /dev/null
++++ b/src/erlang_js.app.src
+@@ -0,0 +1,8 @@
++% -*- mode: erlang -*-
++{application, erlang_js,
++ [{description, "Interface between BEAM and JS"},
++ {vsn, "1.0.2"},
++ {modules, []},
++ {registered, [erlang_js_sup, js_cache]},
++ {applications, [kernel, stdlib, sasl]},
++ {mod, {erlang_js, []}}]}.
+diff --git a/test/driver_tests.erl b/test/driver_tests.erl
+new file mode 100644
+index 0000000..a8e9c70
+--- /dev/null
++++ b/test/driver_tests.erl
+@@ -0,0 +1,34 @@
++-module(driver_tests).
++
++-include_lib("eunit/include/eunit.hrl").
++
++load_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assert(is_port(P)),
++ erlang:unlink(P) end]}].
++
++big_heap_test_() ->
++ [{setup, fun() -> test_util:port_setup(64) end,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assert(is_port(P)),
++ erlang:unlink(P) end]}].
++
++destroy_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:null_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(true, js_driver:destroy(P)),
++ ?assertError(badarg, js:define(P, <<"var x = 100;">>)),
++ erlang:unlink(P) end]}].
++
++spinup_test_() ->
++ [fun() ->
++ F = fun({ok, P}) -> js_driver:destroy(P) end,
++ Ports = [js_driver:new() || X <- lists:seq(1, 16)],
++ [F(P) || P <- Ports] end].
+diff --git a/test/eval_tests.erl b/test/eval_tests.erl
+new file mode 100644
+index 0000000..9133cf2
+--- /dev/null
++++ b/test/eval_tests.erl
+@@ -0,0 +1,124 @@
++-module(eval_tests).
++
++-include_lib("eunit/include/eunit.hrl").
++
++var_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"var x = 100;">>)),
++ ?assertMatch({ok, 100}, js:eval(P, <<"x;">>)),
++ erlang:unlink(P) end]}].
++
++null_define_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, "")),
++ erlang:unlink(P) end]}].
++
++
++function_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"function add_two(x, y) { return x + y; };">>)),
++ ?assertMatch({ok, 95}, js:call(P, <<"add_two">>, [85, 10])),
++ ?assertMatch({ok, <<"testing123">>}, js:call(P, <<"add_two">>, [<<"testing">>, <<"123">>])),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"var f = function(x, y) \n{ return y - x; \n};">>)),
++ ?assertMatch({ok, 75}, js:call(P, <<"f">>, [10, 85])),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"function get_first(data) { return data[\"first\"]; };">>)),
++ Data = {struct, [{<<"first">>, <<"abc">>}]},
++ ?assertMatch({ok, <<"abc">>}, js:call(P, <<"get_first">>, [Data])),
++ erlang:unlink(P) end,
++ fun() ->
++ %% Regression test case for embedded error properties in function return values
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"function return_error_property() { return [{\"value\": \"some_value\", \"list\": [{\"error\": \"some_error\"}]}]; }">>)),
++ ?assertMatch({ok,[{struct,[{<<"value">>,<<"some_value">>},{<<"list">>,[{struct,[{<<"error">>,<<"some_error">>}]}]}]}]}, js:call(P, <<"return_error_property">>, [])),
++ erlang:unlink(P) end
++ ]
++ }].
++
++binding_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"var c = 100;function constant_mult(x) { return x * c; }">>)),
++ ?assertMatch({ok, 200}, js:call(P, <<"constant_mult">>, [2])),
++ ?assertMatch({ok, 1000}, js:call(P, <<"constant_mult">>, [2], [{<<"c">>, 500}])),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"function constant_div(x) { return x / q; }">>, [{<<"q">>, 2}])),
++ ?assertMatch({ok, 5}, js:call(P, <<"constant_div">>, [10])),
++ ?assertMatch({ok, 3}, js:call(P, <<"constant_div">>, [9], [{<<"q">>, 3}])),
++ erlang:unlink(P) end]}].
++
++charset_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ %% Kanji character
++ Kanji = <<123,34,116,101,120,116,34,58,34,228,188,141,34,125,10>>,
++ ?assertMatch(ok, js:define(P, <<"function foo(x) { return x; }">>)),
++ ?assertMatch({ok, Kanji}, js:call(P, <<"foo">>, [Kanji])),
++ erlang:unlink(P) end]}].
++
++json_test_() ->
++ [fun() ->
++ Struct = {struct, [{<<"test">>, <<"1">>}]},
++ ?assertMatch(Struct, mochijson2:decode(mochijson2:encode(Struct))) end].
++
++error_test_() ->
++ [{setup, fun test_util:port_setup/0,
++ fun test_util:port_teardown/1,
++ [fun() ->
++ P = test_util:get_thing(),
++ {error, ErrorDesc} = js:define(P, <<"functoin foo(x, y) { return true; };">>),
++ ?assert(verify_error(ErrorDesc)),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ ?assertMatch(ok, js:define(P, <<"function foo(x, y) { return true; };">>)),
++ {error, ErrorDesc} = js:eval(P, <<"foo(100, 200,);">>),
++ ?assert(verify_error(ErrorDesc)),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ {error, ErrorDesc} = js:define(P, <<"functoin foo() { return \"oops\"; };">>),
++ ?assert(verify_error(ErrorDesc)),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ js:define(P, <<"function foo() { return [{\"error\":\"notfound\"}]; }">>),
++ ?assertMatch({error, <<"[{\"error\":\"notfound\"}]">>}, js:call(P, <<"foo">>, [])),
++ erlang:unlink(P) end,
++ fun() ->
++ P = test_util:get_thing(),
++ {error, ErrorDesc} = js:eval(P, <<"blah(\"wubba\");">>),
++ ?assert(verify_error(ErrorDesc)),
++ erlang:unlink(P) end]}].
++
++
++%% Internal functions
++verify_error([{<<"lineno">>, LineNo},
++ {<<"message">>, Msg},
++ {<<"source">>, Source}]) when is_number(LineNo),
++ is_binary(Msg),
++ is_binary(Source) ->
++ true;
++verify_error(Error) ->
++ ?debugFmt("Error: ~p~n", [Error]),
++ false.
+diff --git a/test/test_suite.erl b/test/test_suite.erl
+new file mode 100644
+index 0000000..ecaff99
+--- /dev/null
++++ b/test/test_suite.erl
+@@ -0,0 +1,7 @@
++-module(test_suite).
++
++-include_lib("eunit/include/eunit.hrl").
++
++all_test_() ->
++ [{module, driver_tests},
++ {module, eval_tests}].
+diff --git a/test/test_util.erl b/test/test_util.erl
+new file mode 100644
+index 0000000..aeed391
+--- /dev/null
++++ b/test/test_util.erl
+@@ -0,0 +1,54 @@
++-module(test_util).
++
++-export([port_setup/0, port_setup/1, port_teardown/1, null_teardown/1, get_thing/0]).
++
++port_setup() ->
++ port_setup(8).
++
++port_setup(Size) ->
++ {ok, P} = js_driver:new(8, Size),
++ start_thing_holder(P),
++ P.
++
++port_teardown(P) ->
++ thing_holder ! stop,
++ erlang:port_connect(P, self()),
++ js_driver:destroy(P).
++
++null_teardown(_) ->
++ thing_holder ! stop,
++ ok.
++
++get_thing() ->
++ thing_holder ! {get_thing, self()},
++ receive
++ Thing ->
++ if
++ is_port(Thing) ->
++ erlang:port_connect(Thing, self());
++ true ->
++ ok
++ end,
++ Thing
++ end.
++
++%% Internal functions
++start_thing_holder(Thing) ->
++ if
++ is_port(Thing) ->
++ erlang:unlink(Thing);
++ true ->
++ ok
++ end,
++ Pid = spawn(fun() -> thing_holder(Thing) end),
++ register(thing_holder, Pid),
++ Pid.
++
++thing_holder(Thing) ->
++ receive
++ {get_thing, Caller} ->
++ Caller ! Thing,
++ thing_holder(Thing);
++ stop ->
++ ok
++ end.
+diff --git a/tests/Emakefile b/tests/Emakefile
+deleted file mode 100644
+index d05e4d9..0000000
+--- a/tests/Emakefile
++++ /dev/null
+@@ -1,4 +0,0 @@
+-{"*", [warn_obsolete_guard, warn_unused_import,
+- warn_shadow_vars, warn_export_vars, debug_info,
+- {i, "../include"},
+- {outdir, "../tests_ebin"}]}.
+diff --git a/tests/driver_tests.erl b/tests/driver_tests.erl
+deleted file mode 100644
+index a8e9c70..0000000
+--- a/tests/driver_tests.erl
++++ /dev/null
+@@ -1,34 +0,0 @@
+--module(driver_tests).
+-
+--include_lib("eunit/include/eunit.hrl").
+-
+-load_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assert(is_port(P)),
+- erlang:unlink(P) end]}].
+-
+-big_heap_test_() ->
+- [{setup, fun() -> test_util:port_setup(64) end,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assert(is_port(P)),
+- erlang:unlink(P) end]}].
+-
+-destroy_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:null_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(true, js_driver:destroy(P)),
+- ?assertError(badarg, js:define(P, <<"var x = 100;">>)),
+- erlang:unlink(P) end]}].
+-
+-spinup_test_() ->
+- [fun() ->
+- F = fun({ok, P}) -> js_driver:destroy(P) end,
+- Ports = [js_driver:new() || X <- lists:seq(1, 16)],
+- [F(P) || P <- Ports] end].
+diff --git a/tests/eval_tests.erl b/tests/eval_tests.erl
+deleted file mode 100644
+index 9133cf2..0000000
+--- a/tests/eval_tests.erl
++++ /dev/null
+@@ -1,124 +0,0 @@
+--module(eval_tests).
+-
+--include_lib("eunit/include/eunit.hrl").
+-
+-var_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"var x = 100;">>)),
+- ?assertMatch({ok, 100}, js:eval(P, <<"x;">>)),
+- erlang:unlink(P) end]}].
+-
+-null_define_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, "")),
+- erlang:unlink(P) end]}].
+-
+-
+-function_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"function add_two(x, y) { return x + y; };">>)),
+- ?assertMatch({ok, 95}, js:call(P, <<"add_two">>, [85, 10])),
+- ?assertMatch({ok, <<"testing123">>}, js:call(P, <<"add_two">>, [<<"testing">>, <<"123">>])),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"var f = function(x, y) \n{ return y - x; \n};">>)),
+- ?assertMatch({ok, 75}, js:call(P, <<"f">>, [10, 85])),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"function get_first(data) { return data[\"first\"]; };">>)),
+- Data = {struct, [{<<"first">>, <<"abc">>}]},
+- ?assertMatch({ok, <<"abc">>}, js:call(P, <<"get_first">>, [Data])),
+- erlang:unlink(P) end,
+- fun() ->
+- %% Regression test case for embedded error properties in function return values
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"function return_error_property() { return [{\"value\": \"some_value\", \"list\": [{\"error\": \"some_error\"}]}]; }">>)),
+- ?assertMatch({ok,[{struct,[{<<"value">>,<<"some_value">>},{<<"list">>,[{struct,[{<<"error">>,<<"some_error">>}]}]}]}]}, js:call(P, <<"return_error_property">>, [])),
+- erlang:unlink(P) end
+- ]
+- }].
+-
+-binding_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"var c = 100;function constant_mult(x) { return x * c; }">>)),
+- ?assertMatch({ok, 200}, js:call(P, <<"constant_mult">>, [2])),
+- ?assertMatch({ok, 1000}, js:call(P, <<"constant_mult">>, [2], [{<<"c">>, 500}])),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"function constant_div(x) { return x / q; }">>, [{<<"q">>, 2}])),
+- ?assertMatch({ok, 5}, js:call(P, <<"constant_div">>, [10])),
+- ?assertMatch({ok, 3}, js:call(P, <<"constant_div">>, [9], [{<<"q">>, 3}])),
+- erlang:unlink(P) end]}].
+-
+-charset_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- %% Kanji character
+- Kanji = <<123,34,116,101,120,116,34,58,34,228,188,141,34,125,10>>,
+- ?assertMatch(ok, js:define(P, <<"function foo(x) { return x; }">>)),
+- ?assertMatch({ok, Kanji}, js:call(P, <<"foo">>, [Kanji])),
+- erlang:unlink(P) end]}].
+-
+-json_test_() ->
+- [fun() ->
+- Struct = {struct, [{<<"test">>, <<"1">>}]},
+- ?assertMatch(Struct, mochijson2:decode(mochijson2:encode(Struct))) end].
+-
+-error_test_() ->
+- [{setup, fun test_util:port_setup/0,
+- fun test_util:port_teardown/1,
+- [fun() ->
+- P = test_util:get_thing(),
+- {error, ErrorDesc} = js:define(P, <<"functoin foo(x, y) { return true; };">>),
+- ?assert(verify_error(ErrorDesc)),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- ?assertMatch(ok, js:define(P, <<"function foo(x, y) { return true; };">>)),
+- {error, ErrorDesc} = js:eval(P, <<"foo(100, 200,);">>),
+- ?assert(verify_error(ErrorDesc)),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- {error, ErrorDesc} = js:define(P, <<"functoin foo() { return \"oops\"; };">>),
+- ?assert(verify_error(ErrorDesc)),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- js:define(P, <<"function foo() { return [{\"error\":\"notfound\"}]; }">>),
+- ?assertMatch({error, <<"[{\"error\":\"notfound\"}]">>}, js:call(P, <<"foo">>, [])),
+- erlang:unlink(P) end,
+- fun() ->
+- P = test_util:get_thing(),
+- {error, ErrorDesc} = js:eval(P, <<"blah(\"wubba\");">>),
+- ?assert(verify_error(ErrorDesc)),
+- erlang:unlink(P) end]}].
+-
+-
+-%% Internal functions
+-verify_error([{<<"lineno">>, LineNo},
+- {<<"message">>, Msg},
+- {<<"source">>, Source}]) when is_number(LineNo),
+- is_binary(Msg),
+- is_binary(Source) ->
+- true;
+-verify_error(Error) ->
+- ?debugFmt("Error: ~p~n", [Error]),
+- false.
+diff --git a/tests/test_suite.erl b/tests/test_suite.erl
+deleted file mode 100644
+index ecaff99..0000000
+--- a/tests/test_suite.erl
++++ /dev/null
+@@ -1,7 +0,0 @@
+--module(test_suite).
+-
+--include_lib("eunit/include/eunit.hrl").
+-
+-all_test_() ->
+- [{module, driver_tests},
+- {module, eval_tests}].
+diff --git a/tests/test_util.erl b/tests/test_util.erl
+deleted file mode 100644
+index aeed391..0000000
+--- a/tests/test_util.erl
++++ /dev/null
+@@ -1,54 +0,0 @@
+--module(test_util).
+-
+--export([port_setup/0, port_setup/1, port_teardown/1, null_teardown/1, get_thing/0]).
+-
+-port_setup() ->
+- port_setup(8).
+-
+-port_setup(Size) ->
+- {ok, P} = js_driver:new(8, Size),
+- start_thing_holder(P),
+- P.
+-
+-port_teardown(P) ->
+- thing_holder ! stop,
+- erlang:port_connect(P, self()),
+- js_driver:destroy(P).
+-
+-null_teardown(_) ->
+- thing_holder ! stop,
+- ok.
+-
+-get_thing() ->
+- thing_holder ! {get_thing, self()},
+- receive
+- Thing ->
+- if
+- is_port(Thing) ->
+- erlang:port_connect(Thing, self());
+- true ->
+- ok
+- end,
+- Thing
+- end.
+-
+-%% Internal functions
+-start_thing_holder(Thing) ->
+- if
+- is_port(Thing) ->
+- erlang:unlink(Thing);
+- true ->
+- ok
+- end,
+- Pid = spawn(fun() -> thing_holder(Thing) end),
+- register(thing_holder, Pid),
+- Pid.
+-
+-thing_holder(Thing) ->
+- receive
+- {get_thing, Caller} ->
+- Caller ! Thing,
+- thing_holder(Thing);
+- stop ->
+- ok
+- end.
+--
+1.7.10.4
+
diff --git a/erlang-js-0006-Dont-treat-warnings-as-errors.patch b/erlang-js-0006-Dont-treat-warnings-as-errors.patch
new file mode 100644
index 0000000..0561410
--- /dev/null
+++ b/erlang-js-0006-Dont-treat-warnings-as-errors.patch
@@ -0,0 +1,26 @@
+From 9c5a7ad4a139aee59aaed35a01448c3e71ac9315 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Tue, 3 Jul 2012 22:59:00 +0400
+Subject: [PATCH 6/7] Dont' treat warnings as errors
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ rebar.config | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/rebar.config b/rebar.config
+index ff9bf9a..a9655ca 100644
+--- a/rebar.config
++++ b/rebar.config
+@@ -5,8 +5,6 @@
+ %%
+ {cover_enabled, true}.
+
+-{erl_opts, [warnings_as_errors]}.
+-
+ {port_env, [
+ {"DRV_CFLAGS", "$DRV_CFLAGS `pkg-config libjs --cflags`"},
+ {"DRV_LDFLAGS", "$DRV_LDFLAGS `pkg-config libjs --libs`"},
+--
+1.7.10.4
+
diff --git a/erlang-js-0007-Start-erlang_js-explicitly.patch b/erlang-js-0007-Start-erlang_js-explicitly.patch
new file mode 100644
index 0000000..0e03040
--- /dev/null
+++ b/erlang-js-0007-Start-erlang_js-explicitly.patch
@@ -0,0 +1,24 @@
+From f41c5d10f9322fe07685e542b00f7491f3ed3982 Mon Sep 17 00:00:00 2001
+From: Peter Lemenkov <lemenkov at gmail.com>
+Date: Wed, 4 Jul 2012 17:19:39 +0400
+Subject: [PATCH 7/7] Start erlang_js explicitly
+
+Signed-off-by: Peter Lemenkov <lemenkov at gmail.com>
+---
+ test/test_suite.erl | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/test/test_suite.erl b/test/test_suite.erl
+index ecaff99..634252b 100644
+--- a/test/test_suite.erl
++++ b/test/test_suite.erl
+@@ -3,5 +3,6 @@
+ -include_lib("eunit/include/eunit.hrl").
+
+ all_test_() ->
++ erlang_js:start(),
+ [{module, driver_tests},
+ {module, eval_tests}].
+--
+1.7.10.4
+
diff --git a/erlang-js.spec b/erlang-js.spec
index 4a96cca..10496db 100644
--- a/erlang-js.spec
+++ b/erlang-js.spec
@@ -1,33 +1,36 @@
%global realname js
-%global git_tag 5350ed2
+%global upstream basho
+%global git_tag 16bc10d
+%global patchnumber 0
+%{?filter_setup:
+%filter_provides_in %{_libdir}/erlang/lib/.*\.so$
+%filter_setup
+}
Name: erlang-%{realname}
-Version: 0.5.0
-Release: 4%{?dist}
+Version: 1.0.2
+Release: 1%{?dist}
Summary: A Friendly Erlang to Javascript Binding
Group: Development/Libraries
License: ASL 2.0
URL: https://github.com/basho/erlang_js
-# wget --no-check-certificate https://github.com/basho/erlang_js/tarball/erlang_js-0.5.0
-Source0: basho-erlang_%{realname}-erlang_%{realname}-%{version}-0-g%{git_tag}.tar.gz
+# wget --content-disposition https://github.com/basho/erlang_js/tarball/1.0.2
+Source0: %{upstream}-erlang_%{realname}-%{version}-%{patchnumber}-g%{git_tag}.tar.gz
Patch1: erlang-js-0001-Fix-building-of-linked-in-driver.patch
-Patch2: erlang-js-0002-Build-with-js-1.7.0.patch
-Patch3: erlang-js-0003-Don-t-require-make-all-for-make-test.patch
-Patch4: erlang-js-0004-Include-eunit-headers-only-when-necessary.patch
-Patch5: erlang-js-0005-js-1.8.5.patch
+Patch2: erlang-js-0002-build-fix-for-js-1.8.5.patch
+Patch3: erlang-js-0003-Fix-deprecation-warning.patch
+Patch4: erlang-js-0004-Use-mochiweb-instead-of-a-bundled-copies.patch
+Patch5: erlang-js-0005-Use-standard-layout-for-rebar.patch
+Patch6: erlang-js-0006-Dont-treat-warnings-as-errors.patch
+Patch7: erlang-js-0007-Start-erlang_js-explicitly.patch
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-BuildRequires: erlang-erts
-BuildRequires: erlang-eunit
-BuildRequires: erlang-sasl
-BuildRequires: erlang-xmerl
+BuildRequires: erlang-rebar
BuildRequires: js-devel
Requires: erlang-erts >= R12B-5
Requires: erlang-kernel >= R12B-5
Requires: erlang-mochiweb
-Requires: erlang-sasl
Requires: erlang-stdlib >= R12B-5
-Requires: erlang-xmerl
%description
@@ -35,17 +38,18 @@ A Friendly Erlang to Javascript Binding.
%prep
-%setup -q -n basho-erlang_%{realname}-%{git_tag}
+%setup -q -n %{upstream}-erlang_%{realname}-0bf5965
%patch1 -p1 -b .bundled_libs
-%patch2 -p1 -b .building_with_js_1_7_0
-%patch3 -p1 -b .dont_require_make_all
-%patch4 -p1 -b .dont_require_eunit
-%patch5 -p1 -b .js_1_8_5
+%patch2 -p1 -b .building_with_js_1_8_0
+%patch3 -p1 -b .fix_deprecation_warning
+%patch4 -p1 -b .use_globally_available_mochiweb
+%patch5 -p1 -b .standard_layout_for_rebar
+%patch6 -p1 -b .warnings
+%patch7 -p1 -b .start_erlang_js_during_tests
%build
-cd c_src && CFLAGS="%{optflags} -fPIC -fpermissive" make %{?_smp_mflags} && mv erlang_js_drv.so ../priv && cd -
-erlc -o ebin +debug_info src/*.erl
+rebar compile -v
%install
@@ -63,12 +67,12 @@ rm -rf $RPM_BUILD_ROOT
%check
-make %{?_smp_mflags} test
+rebar eunit -v
%files
%defattr(-,root,root,-)
-%doc LICENSE README
+%doc LICENSE README.org
%dir %{_libdir}/erlang/lib/%{realname}-%{version}
%dir %{_libdir}/erlang/lib/%{realname}-%{version}/ebin
%dir %{_libdir}/erlang/lib/%{realname}-%{version}/priv
@@ -82,6 +86,9 @@ make %{?_smp_mflags} test
%changelog
+* Thu Jul 05 2012 Peter Lemenkov <lemenkov at gmail.com> - 1.0.2-1
+- Ver. 1.0.2
+
* Fri Jan 13 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.5.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
diff --git a/sources b/sources
index 0ff49d8..2b2b2ce 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-8eae51136b62952a69b98cf85766f42d basho-erlang_js-erlang_js-0.5.0-0-g5350ed2.tar.gz
+399240d01afa4bf07d91db848badc023 basho-erlang_js-1.0.2-0-g16bc10d.tar.gz
More information about the scm-commits
mailing list