#include #if ANDROID #include #endif #include #include #include #include #include #include "ecl_boot.h" #if ANDROID #define ECL_TAG "ecl-native" #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ECL_TAG, __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ECL_TAG, __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, ECL_TAG, __VA_ARGS__)) #define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ECL_TAG, __VA_ARGS__)) #else #define LOGI(...) #define LOGW(...) #define LOGE(...) #endif #define jni_ecl_read_from_string(x) si_string_to_object(1, x) /* * Class: org_lisp_ecl_EmbeddedCommonLisp * Method: start * Signature: ()V */ JNIEXPORT void JNICALL Java_org_lisp_ecl_EmbeddedCommonLisp_start(JNIEnv *env, jobject this, jstring path) { const char *lisp_dir = (*env)->GetStringUTFChars(env, path, NULL); LOGI("XXX: ECL starting: *default-pathname-defaults* to: %s\n", lisp_dir); ecl_boot(lisp_dir); LOGI("ECL started."); }; /* This was fun to make UTF8 work across Java-C-Lisp boundaries. -evrim, 2014. */ cl_object java_string_to_ecl_string(JNIEnv *env, jstring str) { const jchar *txt = (*env)->GetStringChars(env, str, NULL); jsize len = (*env)->GetStringLength(env, str); cl_object ecl_txt = ecl_alloc_simple_extended_string(len); cl_index i; for (i=0;istring.self[i] = txt[i]; }; (*env)->ReleaseStringChars(env, str, txt); return ecl_txt; } jstring ecl_object_to_java_string(JNIEnv *env, cl_object o) { jstring ret; if (ECL_EXTENDED_STRING_P(o)) { LOGI("ecl->java extended string of fillp: %d, dim: %d", o->string.fillp, o->string.dim); jsize len = o->string.fillp; jchar *arr = malloc(sizeof(jchar)*(len+1)); cl_index i; for (i=0; istring.self[i]; } arr[len] = 0; ret = (*env)->NewString(env, arr, len); free(arr); } else if (ECL_STRINGP(o)) { LOGI("ecl->java base string of len %d: %s", o->base_string.dim, o->base_string.self); ret = (*env)->NewStringUTF(env, (const char*)o->base_string.self); } else { LOGI("ecl->java not a string, coercing"); return ecl_object_to_java_string(env, cl_princ_to_string(o)); } return ret; } /* * Class: org_lisp_ecl_EmbeddedCommonLisp * Method: exec * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_lisp_ecl_EmbeddedCommonLisp_exec(JNIEnv *env, jobject this, jstring str) { jstring ret; cl_object txt = java_string_to_ecl_string(env, str); cl_object result = si_safe_eval(3, jni_ecl_read_from_string(txt), Cnil, OBJNULL); if (result) { ret = ecl_object_to_java_string(env, result); } else { ret = (*env)->NewStringUTF(env, "ERROR in eval"); } return ret; }; #undef jni_ecl_read_from_string /* * Class: org_lisp_ecl_EmbeddedCommonLisp * Method: exec_ * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_lisp_ecl_EmbeddedCommonLisp_exec_(JNIEnv *env, jobject this, jstring str) { jstring ret; const char *cmd = (*env)->GetStringUTFChars(env, str, NULL); cl_object result = si_safe_eval(3, c_string_to_object(cmd), Cnil, OBJNULL); if (result) { cl_object out = si_coerce_to_base_string(cl_princ_to_string(result)); ret = (*env)->NewStringUTF(env, (const char*) out->base_string.self); } else { ret = (*env)->NewStringUTF(env, "ERROR in eval"); } return ret; };