Permalink
Browse files

build couchjs with scons

  • Loading branch information...
1 parent 75a44a4 commit 906d543b0e2cb16421702ebe8b878b21415c16a0 @bradnoble bradnoble committed Aug 20, 2010
View
@@ -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@/
View
@@ -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'])
@@ -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'])
@@ -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 @@ open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
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,28 +218,28 @@ 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)
{
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;
Oops, something went wrong.

0 comments on commit 906d543

Please sign in to comment.