#include "Pooling.hpp"
#include "String.hpp"
+const char *sqlite3_column_string(sqlite3_stmt *stmt, int n) {
+ return reinterpret_cast<const char *>(sqlite3_column_text(stmt, n));
+}
+
char *sqlite3_column_pooled(CYPool &pool, sqlite3_stmt *stmt, int n) {
- if (const unsigned char *value = sqlite3_column_text(stmt, n))
- return pool.strdup(reinterpret_cast<const char *>(value));
+ if (const char *value = sqlite3_column_string(stmt, n))
+ return pool.strdup(value);
else return NULL;
}
}
/* }}} */
+static JSObjectRef (*JSObjectMakeArray$)(JSContextRef, size_t, const JSValueRef[], JSValueRef *);
+
+static JSObjectRef CYObjectMakeArray(JSContextRef context, size_t length, const JSValueRef values[]) {
+ if (JSObjectMakeArray$ != NULL)
+ return _jsccall(*JSObjectMakeArray$, context, length, values);
+ else {
+ JSObjectRef Array(CYGetCachedObject(context, CYJSString("Array")));
+ JSValueRef value(CYCallAsFunction(context, Array, NULL, length, values));
+ return CYCastJSObject(context, value);
+ }
+}
+
static JSClassRef All_;
static JSClassRef Context_;
static JSClassRef CString_;
return CYMakeType(context, &type);
}
-extern "C" const char *CYBridgeHash(CYPool &pool, CYUTF8String name) {
+extern "C" bool CYBridgeHash(CYPool &pool, CYUTF8String name, const char *&code, unsigned &flags) {
sqlite3_stmt *statement;
_sqlcall(sqlite3_prepare(database_,
"select "
- "\"cache\".\"value\" "
+ "\"cache\".\"code\", "
+ "\"cache\".\"flags\" "
"from \"cache\" "
"where"
" \"cache\".\"system\" & " CY_SYSTEM " == " CY_SYSTEM " and"
_sqlcall(sqlite3_bind_text(statement, 1, name.data, name.size, SQLITE_STATIC));
- const char *value;
+ bool success;
if (_sqlcall(sqlite3_step(statement)) == SQLITE_DONE)
- value = NULL;
- else
- value = sqlite3_column_pooled(pool, statement, 0);
+ success = false;
+ else {
+ success = true;
+ code = sqlite3_column_pooled(pool, statement, 0);
+ flags = sqlite3_column_int(statement, 1);
+ }
_sqlcall(sqlite3_finalize(statement));
- return value;
+ return success;
}
static bool All_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) {
+ if (JSStringIsEqualToUTF8CString(property, "errno"))
+ return true;
+
JSObjectRef global(CYGetGlobalObject(context));
JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls"))));
return true;
CYPool pool;
- if (CYBridgeHash(pool, CYPoolUTF8String(pool, context, property)) != NULL)
+ const char *code;
+ unsigned flags;
+ if (CYBridgeHash(pool, CYPoolUTF8String(pool, context, property), code, flags))
return true;
return false;
}
static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+ if (JSStringIsEqualToUTF8CString(property, "errno"))
+ return CYCastJSValue(context, errno);
+
JSObjectRef global(CYGetGlobalObject(context));
JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls"))));
return value;
CYPool pool;
- if (const char *code = CYBridgeHash(pool, CYPoolUTF8String(pool, context, property))) {
- JSValueRef result(_jsccall(JSEvaluateScript, context, CYJSString(CYPoolCode(pool, code)), NULL, NULL, 0));
- JSObjectRef cache(CYGetCachedObject(context, CYJSString("cache")));
- CYSetProperty(context, cache, property, result);
+ const char *code;
+ unsigned flags;
+ if (CYBridgeHash(pool, CYPoolUTF8String(pool, context, property), code, flags)) {
+ CYUTF8String parsed;
+
+ try {
+ parsed = CYPoolCode(pool, code);
+ } catch (const CYException &error) {
+ CYThrow("%s", pool.strcat("error caching ", CYPoolCString(pool, context, property), ": ", error.PoolCString(pool), NULL));
+ }
+
+ JSValueRef result(_jsccall(JSEvaluateScript, context, CYJSString(parsed), NULL, NULL, 0));
+
+ if (flags == 0) {
+ JSObjectRef cache(CYGetCachedObject(context, CYJSString("cache")));
+ CYSetProperty(context, cache, property, result);
+ }
+
return result;
}
return NULL;
} CYCatch(NULL) }
+static JSValueRef All_complete_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ _assert(count == 1);
+ CYPool pool;
+ CYUTF8String prefix(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0])));
+
+ std::vector<JSValueRef> values;
+
+ sqlite3_stmt *statement;
+
+ if (prefix.size == 0)
+ _sqlcall(sqlite3_prepare(database_,
+ "select "
+ "\"cache\".\"name\" "
+ "from \"cache\" "
+ "where"
+ " \"cache\".\"system\" & " CY_SYSTEM " == " CY_SYSTEM
+ , -1, &statement, NULL));
+ else {
+ _sqlcall(sqlite3_prepare(database_,
+ "select "
+ "\"cache\".\"name\" "
+ "from \"cache\" "
+ "where"
+ " \"cache\".\"name\" >= ? and \"cache\".\"name\" < ? and "
+ " \"cache\".\"system\" & " CY_SYSTEM " == " CY_SYSTEM
+ , -1, &statement, NULL));
+
+ _sqlcall(sqlite3_bind_text(statement, 1, prefix.data, prefix.size, SQLITE_STATIC));
+
+ char *after(pool.strndup(prefix.data, prefix.size));
+ ++after[prefix.size - 1];
+ _sqlcall(sqlite3_bind_text(statement, 2, after, prefix.size, SQLITE_STATIC));
+ }
+
+ while (_sqlcall(sqlite3_step(statement)) != SQLITE_DONE)
+ values.push_back(CYCastJSValue(context, CYJSString(sqlite3_column_string(statement, 0))));
+
+ _sqlcall(sqlite3_finalize(statement));
+
+ return CYObjectMakeArray(context, values.size(), values.data());
+} CYCatch(NULL) }
+
static void All_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
JSObjectRef global(CYGetGlobalObject(context));
JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
return Type_callAsFunction_toString(context, object, _this, count, arguments, exception);
}
+static JSStaticFunction All_staticFunctions[2] = {
+ {"cy$complete", &All_complete_callAsFunction, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {NULL, NULL, 0}
+};
+
static JSStaticFunction CString_staticFunctions[6] = {
{"toCYON", &CString_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toJSON", &CYValue_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, 0}
};
-static JSObjectRef (*JSObjectMakeArray$)(JSContextRef, size_t, const JSValueRef[], JSValueRef *);
-
_visible void CYSetArgs(int argc, const char *argv[]) {
JSContextRef context(CYGetJSContext());
JSValueRef args[argc];
for (int i(0); i != argc; ++i)
args[i] = CYCastJSValue(context, argv[i]);
- JSObjectRef array;
- if (JSObjectMakeArray$ != NULL)
- array = _jsccall(*JSObjectMakeArray$, context, argc, args);
- else {
- JSObjectRef Array(CYGetCachedObject(context, CYJSString("Array")));
- JSValueRef value(CYCallAsFunction(context, Array, NULL, argc, args));
- array = CYCastJSObject(context, value);
- }
-
+ JSObjectRef array(CYObjectMakeArray(context, argc, args));
JSObjectRef System(CYGetCachedObject(context, CYJSString("System")));
CYSetProperty(context, System, CYJSString("args"), array);
}
definition = kJSClassDefinitionEmpty;
definition.className = "All";
+ definition.staticFunctions = All_staticFunctions;
definition.hasProperty = &All_hasProperty;
definition.getProperty = &All_getProperty;
definition.getPropertyNames = &All_getPropertyNames;
_assert(slash != NULL);
*slash = '\0';
+ slash = strrchr(lib, '/');
+ if (slash != NULL && strcmp(slash, "/.libs") == 0)
+ *slash = '\0';
+
return lib;
}
static bool CYRunScript(JSGlobalContextRef context, const char *path) {
CYPool pool;
- CYUTF8String code(CYPoolFileUTF8String(pool, path));
+ CYUTF8String code(CYPoolFileUTF8String(pool, pool.strcat(CYPoolLibraryPath(pool), path, NULL)));
if (code.data == NULL)
return false;
CYArrayPush(context, alls, cycript);
- CYRunScript(context, "libcycript.cy");
+ CYRunScript(context, "/libcycript.cy");
}
static JSGlobalContextRef context_;