diff options
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | SConstruct | 16 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/SConscript | 53 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/http.c (renamed from src/couchdb/priv/couch_js/http.c) | 69 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/http.h (renamed from src/couchdb/priv/couch_js/http.h) | 0 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/main.c (renamed from src/couchdb/priv/couch_js/main.c) | 25 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/utf8.c (renamed from src/couchdb/priv/couch_js/utf8.c) | 31 | ||||
-rw-r--r-- | apps/couch/c_src/couch_js/utf8.h (renamed from src/couchdb/priv/couch_js/utf8.h) | 0 | ||||
-rw-r--r-- | apps/couch/js/SConscript | 23 | ||||
-rw-r--r-- | apps/couch/js/filter.js (renamed from rel/overlay/var/share/server/filter.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/json2.js (renamed from rel/overlay/var/share/server/json2.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/loop.js (renamed from rel/overlay/var/share/server/loop.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/mimeparse.js (renamed from rel/overlay/var/share/server/mimeparse.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/render.js (renamed from rel/overlay/var/share/server/render.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/state.js (renamed from rel/overlay/var/share/server/state.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/util.js (renamed from rel/overlay/var/share/server/util.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/validate.js (renamed from rel/overlay/var/share/server/validate.js) | 0 | ||||
-rw-r--r-- | apps/couch/js/views.js (renamed from rel/overlay/var/share/server/views.js) | 0 |
18 files changed, 172 insertions, 51 deletions
@@ -12,6 +12,12 @@ rel/overlay/erts-vsn/bin/erl_call Makefile rebar.config +# scons building +.sconf_temp/ +.sconsign.dblite +build/ +config.log + # testing .eunit @abs_top_builddir@/ diff --git a/SConstruct b/SConstruct new file mode 100644 index 00000000..53f0d771 --- /dev/null +++ b/SConstruct @@ -0,0 +1,16 @@ +# Copyright (c) 2010 Cloudant +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +SConscript(['apps/couch/c_src/couch_js/SConscript'], variant_dir='build') +SConscript(['apps/couch/js/SConscript']) diff --git a/apps/couch/c_src/couch_js/SConscript b/apps/couch/c_src/couch_js/SConscript new file mode 100644 index 00000000..b459ee94 --- /dev/null +++ b/apps/couch/c_src/couch_js/SConscript @@ -0,0 +1,53 @@ +# Copyright (c) 2010 Cloudant +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +def require_lib(name): + if not conf.CheckLib(name): + print 'Could not find required library', name + Exit(1) + +env = Environment(CCFLAGS='-g -O2 -DXP_UNIX') +if not env.GetOption('clean'): + conf = Configure(env, config_h='config.h') + + require_lib('m') + require_lib('pthread') + require_lib('curl') + + ## check for SpiderMonkey development header + if conf.CheckHeader('js/jsapi.h'): + jsapi = 'js/jsapi.h' + elif conf.CheckHeader('mozjs/jsapi.h'): + jsapi = 'mozjs/jsapi.h' + elif conf.CheckHeader('jsapi.h'): + jsapi = 'jsapi.h' + else: + print 'Could not find jsapi.h.', \ + 'Are Mozilla SpiderMonkey headers installed?' + Exit(1) + + ## check for SpiderMonkey library as libjs or libmozjs + if not conf.CheckLibWithHeader('mozjs', jsapi, 'c', autoadd=1): + if not conf.CheckLibWithHeader('js', jsapi, 'c', autoadd=1): + print 'Could not find JS library.', \ + 'Is Mozilla SpiderMonkey installed?' + Exit(1) + + ## SpiderMonkey 1.8 has this callback we use for memory management + if conf.CheckDeclaration('JS_SetOperationCallback', '#include <%s>' % jsapi): + conf.Define('USE_JS_SETOPCB') + + env = conf.Finish() + +env.Program('couchjs', ['main.c', 'http.c', 'utf8.c']) diff --git a/src/couchdb/priv/couch_js/http.c b/apps/couch/c_src/couch_js/http.c index 6c2a8a82..b781f0ef 100644 --- a/src/couchdb/priv/couch_js/http.c +++ b/apps/couch/c_src/couch_js/http.c @@ -13,7 +13,16 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + +#include "config.h" +#ifdef HAVE_JS_JSAPI_H +#include <js/jsapi.h> +#elif HAVE_MOZJS_JSAPI_H +#include <mozjs/jsapi.h> +#else #include <jsapi.h> +#endif + #include <curl/curl.h> #include "utf8.h" @@ -72,7 +81,7 @@ constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) JS_ReportError(cx, "Failed to set private CouchHTTP data."); goto error; } - + ret = JS_TRUE; goto success; @@ -101,7 +110,7 @@ destructor(JSContext* cx, JSObject* obj) static JSBool open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) -{ +{ HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* method = NULL; char* url = NULL; @@ -126,12 +135,12 @@ open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) JS_ReportError(cx, "Failed to encode method."); goto done; } - + for(methid = 0; METHODS[methid] != NULL; methid++) { if(strcasecmp(METHODS[methid], method) == 0) break; } - + if(methid > COPY) { JS_ReportError(cx, "Invalid method specified."); @@ -158,19 +167,19 @@ open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) JS_ReportError(cx, "Failed to encode URL."); goto done; } - + if(argv[2] != JSVAL_VOID && argv[2] != JSVAL_FALSE) { JS_ReportError(cx, "Synchronous flag must be false if specified."); goto done; } - + if(http->req_headers) { curl_slist_free_all(http->req_headers); http->req_headers = NULL; } - + // Disable Expect: 100-continue http->req_headers = curl_slist_append(http->req_headers, "Expect:"); @@ -183,7 +192,7 @@ done: static JSBool setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) -{ +{ HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* keystr = NULL; char* valstr = NULL; @@ -209,20 +218,20 @@ setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) JS_ReportError(cx, "Failed to encode header name."); goto done; } - + if(argv[1] == JSVAL_VOID) { JS_ReportError(cx, "You must specify a header value."); goto done; } - + valstr = enc_string(cx, argv[1], NULL); if(!valstr) { JS_ReportError(cx, "Failed to encode header value."); goto done; } - + hdrlen = strlen(keystr) + strlen(valstr) + 3; hdrbuf = (char*) malloc(hdrlen * sizeof(char)); if(!hdrbuf) @@ -230,7 +239,7 @@ setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) JS_ReportError(cx, "Failed to allocate header buffer."); goto done; } - + snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr); http->req_headers = curl_slist_append(http->req_headers, hdrbuf); @@ -251,7 +260,7 @@ sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) char* body = NULL; size_t bodylen = 0; JSBool ret = JS_FALSE; - + if(!http) { JS_ReportError(cx, "Invalid CouchHTTP instance."); @@ -279,13 +288,13 @@ static JSBool status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) { HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); - + if(!http) { JS_ReportError(cx, "Invalid CouchHTTP instance."); return JS_FALSE; } - + if(INT_FITS_IN_JSVAL(http->last_status)) { *vp = INT_TO_JSVAL(http->last_status); @@ -350,7 +359,7 @@ install_http(JSContext* cx, JSObject* glbl) fprintf(stderr, "Failed to initialize CouchHTTP class.\n"); return NULL; } - + return klass; } @@ -388,10 +397,10 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) JSString* jsbody; JSBool ret = JS_FALSE; jsval tmp; - + state.cx = cx; state.http = http; - + state.sendbuf = body; state.sendlen = bodylen; state.sent = 0; @@ -415,7 +424,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT, "CouchHTTP Client - Relax"); } - + if(!HTTP_HANDLE) { JS_ReportError(cx, "Failed to initialize cURL handle."); @@ -432,7 +441,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0); - + if(http->method == HEAD) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1); @@ -443,10 +452,10 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } - + if(body && bodylen) { - curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen); + curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen); } else { @@ -467,7 +476,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF); goto done; } - + if(!state.resp_headers) { JS_ReportError(cx, "Failed to recieve HTTP headers."); @@ -488,7 +497,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) JS_ReportError(cx, "INTERNAL: Failed to set response headers."); goto done; } - + if(state.recvbuf) // Is good enough? { state.recvbuf[state.read] = '\0'; @@ -512,7 +521,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) { tmp = JS_GetEmptyStringValue(cx); } - + if(!JS_DefineProperty( cx, obj, @@ -526,7 +535,7 @@ go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) JS_ReportError(cx, "INTERNAL: Failed to set responseText."); goto done; } - + ret = JS_TRUE; done: @@ -576,7 +585,7 @@ recv_header(void *ptr, size_t size, size_t nmem, void *data) JSString* hdr = NULL; jsuint hdrlen; jsval hdrval; - + if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) { if(length < 12) @@ -630,14 +639,14 @@ recv_body(void *ptr, size_t size, size_t nmem, void *data) CurlState* state = (CurlState*) data; size_t length = size * nmem; char* tmp = NULL; - + if(!state->recvbuf) { state->recvlen = 4096; state->read = 0; state->recvbuf = JS_malloc(state->cx, state->recvlen); } - + if(!state->recvbuf) { return CURLE_WRITE_ERROR; @@ -648,7 +657,7 @@ recv_body(void *ptr, size_t size, size_t nmem, void *data) tmp = JS_realloc(state->cx, state->recvbuf, state->recvlen); if(!tmp) return CURLE_WRITE_ERROR; state->recvbuf = tmp; - + memcpy(state->recvbuf + state->read, ptr, length); state->read += length; return length; diff --git a/src/couchdb/priv/couch_js/http.h b/apps/couch/c_src/couch_js/http.h index b5f8c70f..b5f8c70f 100644 --- a/src/couchdb/priv/couch_js/http.h +++ b/apps/couch/c_src/couch_js/http.h diff --git a/src/couchdb/priv/couch_js/main.c b/apps/couch/c_src/couch_js/main.c index 376aa15b..25acaf55 100644 --- a/src/couchdb/priv/couch_js/main.c +++ b/apps/couch/c_src/couch_js/main.c @@ -13,8 +13,15 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <jsapi.h> + #include "config.h" +#ifdef HAVE_JS_JSAPI_H +#include <js/jsapi.h> +#elif HAVE_MOZJS_JSAPI_H +#include <mozjs/jsapi.h> +#else +#include <jsapi.h> +#endif #include "utf8.h" #include "http.h" @@ -76,7 +83,7 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval); } - + ret = JS_TRUE; done: @@ -130,7 +137,7 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen) bytes = JS_malloc(cx, byteslen); if(bytes == NULL) return NULL; - + while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0) { used += readlen; @@ -169,7 +176,7 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { bytes = readfp(cx, stdin, &byteslen); if(!bytes) return JS_FALSE; - + /* Treat the empty string specially */ if(byteslen == 0) { @@ -186,7 +193,7 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { return JS_FALSE; } bytes = tmp; - + str = dec_string(cx, bytes, byteslen); JS_free(cx, bytes); @@ -279,7 +286,7 @@ main(int argc, const char * argv[]) JSObject* global = NULL; JSFunctionSpec* sp = NULL; int i = 0; - + rt = JS_NewRuntime(64L * 1024L * 1024L); if (!rt) return 1; @@ -288,13 +295,13 @@ main(int argc, const char * argv[]) JS_SetErrorReporter(cx, printerror); JS_ToggleOptions(cx, JSOPTION_XML); - + SETUP_REQUEST(cx); global = JS_NewObject(cx, &global_class, NULL, NULL); if (!global) return 1; if (!JS_InitStandardClasses(cx, global)) return 1; - + for(sp = global_functions; sp->name != NULL; sp++) { if(!JS_DefineFunction(cx, global, @@ -309,7 +316,7 @@ main(int argc, const char * argv[]) { return 1; } - + JS_SetGlobalObject(cx, global); if(argc > 2) diff --git a/src/couchdb/priv/couch_js/utf8.c b/apps/couch/c_src/couch_js/utf8.c index 699a6fee..57928ba9 100644 --- a/src/couchdb/priv/couch_js/utf8.c +++ b/apps/couch/c_src/couch_js/utf8.c @@ -10,7 +10,14 @@ // License for the specific language governing permissions and limitations under // the License. +#include "config.h" +#ifdef HAVE_JS_JSAPI_H +#include <js/jsapi.h> +#elif HAVE_MOZJS_JSAPI_H +#include <mozjs/jsapi.h> +#else #include <jsapi.h> +#endif static int enc_char(uint8 *utf8Buffer, uint32 ucs4Char) @@ -66,7 +73,7 @@ enc_charbuf(const jschar* src, size_t srclen, char* dst, size_t* dstlenp) srclen--; if((c >= 0xDC00) && (c <= 0xDFFF)) goto bad_surrogate; - + if(c < 0xD800 || c > 0xDBFF) { v = c; @@ -104,7 +111,7 @@ enc_charbuf(const jschar* src, size_t srclen, char* dst, size_t* dstlenp) } dstlen -= utf8Len; } - + *dstlenp = (origDstlen - dstlen); return JS_TRUE; @@ -125,7 +132,7 @@ enc_string(JSContext* cx, jsval arg, size_t* buflen) char* bytes = NULL; size_t srclen = 0; size_t byteslen = 0; - + str = JS_ValueToString(cx, arg); if(!str) goto error; @@ -133,10 +140,10 @@ enc_string(JSContext* cx, jsval arg, size_t* buflen) srclen = JS_GetStringLength(str); if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error; - + bytes = JS_malloc(cx, (byteslen) + 1); bytes[byteslen] = 0; - + if(!enc_charbuf(src, srclen, bytes, &byteslen)) goto error; if(buflen) *buflen = byteslen; @@ -198,17 +205,17 @@ dec_charbuf(const char *src, size_t srclen, jschar *dst, size_t *dstlenp) { v = (uint8) *src; n = 1; - + if(v & 0x80) { while(v & (0x80 >> n)) { n++; } - + if(n > srclen) goto buffer_too_small; if(n == 1 || n > 6) goto bad_character; - + for(j = 1; j < n; j++) { if((src[j] & 0xC0) != 0x80) goto bad_character; @@ -218,13 +225,13 @@ dec_charbuf(const char *src, size_t srclen, jschar *dst, size_t *dstlenp) if(v >= 0x10000) { v -= 0x10000; - + if(v > 0xFFFFF || dstlen < 2) { *dstlenp = (origDstlen - dstlen); return JS_FALSE; } - + if(dstlen < 2) goto buffer_too_small; if(dst) @@ -263,7 +270,7 @@ dec_string(JSContext* cx, const char* bytes, size_t byteslen) JSString* str = NULL; jschar* chars = NULL; size_t charslen; - + if(!dec_charbuf(bytes, byteslen, NULL, &charslen)) goto error; chars = JS_malloc(cx, (charslen + 1) * sizeof(jschar)); @@ -283,4 +290,4 @@ error: success: return str; -}
\ No newline at end of file +} diff --git a/src/couchdb/priv/couch_js/utf8.h b/apps/couch/c_src/couch_js/utf8.h index 00f6b736..00f6b736 100644 --- a/src/couchdb/priv/couch_js/utf8.h +++ b/apps/couch/c_src/couch_js/utf8.h diff --git a/apps/couch/js/SConscript b/apps/couch/js/SConscript new file mode 100644 index 00000000..db635665 --- /dev/null +++ b/apps/couch/js/SConscript @@ -0,0 +1,23 @@ +# Copyright (c) 2010 Cloudant +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +env = Environment() +env['BUILDERS']['Cat'] = Builder(action = ''' + echo "// DO NOT EDIT THIS FILE BY HAND\\n" > $TARGET && \ + cat $SOURCES >> $TARGET +''') + +## don't Glob() because loop.js must come last +env.Cat('../../../build/main.js', ['json2.js', 'filter.js', 'mimeparse.js', + 'render.js', 'state.js', 'util.js', 'validate.js', 'views.js', 'loop.js']) diff --git a/rel/overlay/var/share/server/filter.js b/apps/couch/js/filter.js index 1e8556a4..1e8556a4 100644 --- a/rel/overlay/var/share/server/filter.js +++ b/apps/couch/js/filter.js diff --git a/rel/overlay/var/share/server/json2.js b/apps/couch/js/json2.js index 39d8f370..39d8f370 100644 --- a/rel/overlay/var/share/server/json2.js +++ b/apps/couch/js/json2.js diff --git a/rel/overlay/var/share/server/loop.js b/apps/couch/js/loop.js index 300151e9..300151e9 100644 --- a/rel/overlay/var/share/server/loop.js +++ b/apps/couch/js/loop.js diff --git a/rel/overlay/var/share/server/mimeparse.js b/apps/couch/js/mimeparse.js index 3642a194..3642a194 100644 --- a/rel/overlay/var/share/server/mimeparse.js +++ b/apps/couch/js/mimeparse.js diff --git a/rel/overlay/var/share/server/render.js b/apps/couch/js/render.js index 9dcfbcd6..9dcfbcd6 100644 --- a/rel/overlay/var/share/server/render.js +++ b/apps/couch/js/render.js diff --git a/rel/overlay/var/share/server/state.js b/apps/couch/js/state.js index 9af9e475..9af9e475 100644 --- a/rel/overlay/var/share/server/state.js +++ b/apps/couch/js/state.js diff --git a/rel/overlay/var/share/server/util.js b/apps/couch/js/util.js index 9cc464c3..9cc464c3 100644 --- a/rel/overlay/var/share/server/util.js +++ b/apps/couch/js/util.js diff --git a/rel/overlay/var/share/server/validate.js b/apps/couch/js/validate.js index 76a14129..76a14129 100644 --- a/rel/overlay/var/share/server/validate.js +++ b/apps/couch/js/validate.js diff --git a/rel/overlay/var/share/server/views.js b/apps/couch/js/views.js index ffe63377..ffe63377 100644 --- a/rel/overlay/var/share/server/views.js +++ b/apps/couch/js/views.js |