diff --git a/ase/awk/Argument.java b/ase/awk/Argument.java index 2a4ed2c1..fca9978f 100644 --- a/ase/awk/Argument.java +++ b/ase/awk/Argument.java @@ -1,52 +1,72 @@ /* - * $Id: Argument.java,v 1.6 2007/10/21 13:58:47 bacon Exp $ + * $Id: Argument.java,v 1.8 2007/11/02 10:47:51 bacon Exp $ + * + * {License} */ package ase.awk; -public class Argument +public class Argument implements Clearable { protected long runid; - protected long valid; + //protected long valid; + public long valid; /* An instance of the Argument class should not be used * outside the context where it is availble. When it is * referenced that way, the getXXX methods may cause * JVM to crash */ - Argument (long runid, long valid) + Argument (Context ctx, long runid, long valid) { + if (ctx != null) ctx.pushClearable (this); this.runid = runid; this.valid = valid; } + Argument (long runid, long valid) + { + this (null, runid, valid); + } + + public void clear () + { + clearval (this.runid, this.valid); + } + public long getIntValue () { + if (this.valid == 0) return 0; return getintval (this.runid, this.valid); } public double getRealValue () { + if (this.valid == 0) return 0.0; return getrealval (this.runid, this.valid); } public String getStringValue () throws Exception { + if (this.valid == 0) return ""; return getstrval (this.runid, this.valid); } public boolean isIndexed () { + if (this.valid == 0) return false; return isindexed (this.runid, this.valid); } public Argument getIndexed (String idx) throws Exception { + if (this.valid == 0) return null; return getindexed (this.runid, this.valid, idx); } public Argument getIndexed (long idx) throws Exception { + if (this.valid == 0) return null; return getIndexed (Long.toString(idx)); } @@ -55,4 +75,6 @@ public class Argument protected native String getstrval (long runid, long valid) throws Exception; protected native boolean isindexed (long runid, long valid); protected native Argument getindexed (long runid, long valid, String idx) throws Exception; + + protected native void clearval (long runid, long valid); } diff --git a/ase/awk/Clearable.java b/ase/awk/Clearable.java new file mode 100644 index 00000000..5cfabd2b --- /dev/null +++ b/ase/awk/Clearable.java @@ -0,0 +1,13 @@ +/* + * $Id: Clearable.java,v 1.1 2007/11/02 05:49:19 bacon Exp $ + * + * {License} + */ + +package ase.awk; + +public interface Clearable +{ + public void clear (); +} + diff --git a/ase/awk/Context.java b/ase/awk/Context.java index ec6e57a4..39b1cc7b 100644 --- a/ase/awk/Context.java +++ b/ase/awk/Context.java @@ -1,5 +1,7 @@ /* - * $Id: Context.java,v 1.9 2007/11/01 14:01:00 bacon Exp $ + * $Id: Context.java,v 1.10 2007/11/02 05:49:19 bacon Exp $ + * + * {License} */ package ase.awk; @@ -29,31 +31,31 @@ public class Context protected Awk awk; protected long runid; protected Object custom; - protected Stack returnStack; + protected Stack clearableStack; Context (Awk awk) { this.awk = awk; this.runid = 0; this.custom = null; - this.returnStack = new Stack (); + this.clearableStack = new Stack (); } void clear () { - Return r; - while ((r = popReturn()) != null) r.clear (); + Clearable obj; + while ((obj = popClearable()) != null) obj.clear (); } - void pushReturn (Return ret) + void pushClearable (Clearable obj) { - returnStack.push (ret); + clearableStack.push (obj); } - Return popReturn () + Clearable popClearable () { - if (returnStack.empty()) return null; - return (Return)returnStack.pop (); + if (clearableStack.empty()) return null; + return (Clearable)clearableStack.pop (); } public Awk getAwk () diff --git a/ase/awk/File.java b/ase/awk/File.java index bbeedd96..15d03aa4 100644 --- a/ase/awk/File.java +++ b/ase/awk/File.java @@ -1,5 +1,7 @@ /* - * $Id: File.java,v 1.2 2007/05/26 10:52:48 bacon Exp $ + * $Id: File.java,v 1.3 2007/11/02 05:49:19 bacon Exp $ + * + * {License} */ package ase.awk; diff --git a/ase/awk/IO.java b/ase/awk/IO.java index 131eda56..89945207 100644 --- a/ase/awk/IO.java +++ b/ase/awk/IO.java @@ -1,5 +1,7 @@ /* - * $Id: IO.java,v 1.1 2007/05/26 10:52:48 bacon Exp $ + * $Id: IO.java,v 1.2 2007/11/02 05:49:19 bacon Exp $ + * + * {License} */ package ase.awk; diff --git a/ase/awk/Pipe.java b/ase/awk/Pipe.java index f4f6d445..51c12ad5 100644 --- a/ase/awk/Pipe.java +++ b/ase/awk/Pipe.java @@ -1,5 +1,7 @@ /* - * $Id: Pipe.java,v 1.2 2007/05/26 10:52:48 bacon Exp $ + * $Id: Pipe.java,v 1.3 2007/11/02 05:49:19 bacon Exp $ + * + * {License} */ package ase.awk; diff --git a/ase/awk/Return.java b/ase/awk/Return.java index 3c25cac7..723475d1 100644 --- a/ase/awk/Return.java +++ b/ase/awk/Return.java @@ -1,10 +1,12 @@ /* - * $Id: Return.java,v 1.6 2007/10/30 15:01:31 bacon Exp $ + * $Id: Return.java,v 1.8 2007/11/02 10:47:51 bacon Exp $ + * + * ${License} */ package ase.awk; -public class Return +public class Return implements Clearable { protected long runid; protected long valid; @@ -16,7 +18,7 @@ public class Return public Return (Context ctx) { - ctx.pushReturn (this); + ctx.pushClearable (this); this.runid = ctx.getId(); this.valid = 0; } @@ -29,116 +31,139 @@ public class Return public boolean isIndexed () { + if (this.runid == 0) return false; return isindexed (this.runid, this.valid); } public void setIntValue (long v) { + if (this.runid == 0) return; setintval (this.runid, this.valid, v); } public void setIntValue (int v) { + if (this.runid == 0) return; setintval (this.runid, this.valid, (long)v); } public void setIntValue (short v) { + if (this.runid == 0) return; setintval (this.runid, this.valid, (long)v); } public void setIntValue (byte v) { + if (this.runid == 0) return; setintval (this.runid, this.valid, (long)v); } public void setRealValue (double v) { + if (this.runid == 0) return; setrealval (this.runid, this.valid, v); } public void setRealValue (float v) { + if (this.runid == 0) return; setrealval (this.runid, this.valid, (double)v); } public void setStringValue (String v) { + if (this.runid == 0) return; setstrval (this.runid, this.valid, v); } public void setIndexedIntValue (String index, long v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, index, v); } public void setIndexedIntValue (String index, int v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, index, (long)v); } public void setIndexedIntValue (String index, short v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, index, (long)v); } public void setIndexedIntValue (String index, byte v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, index, (long)v); } public void setIndexedRealValue (String index, double v) { + if (this.runid == 0) return; setindexedrealval (this.runid, this.valid, index, v); } public void setIndexedRealValue (String index, float v) { + if (this.runid == 0) return; setindexedrealval (this.runid, this.valid, index, (double)v); } public void setIndexedStringValue (String index, String v) { + if (this.runid == 0) return; setindexedstrval (this.runid, this.valid, index, v); } public void setIndexedIntValue (long index, long v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, Long.toString(index), v); } public void setIndexedIntValue (long index, int v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, Long.toString(index), (long)v); } public void setIndexedIntValue (long index, short v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, Long.toString(index), (long)v); } public void setIndexedIntValue (long index, byte v) { + if (this.runid == 0) return; setindexedintval (this.runid, this.valid, Long.toString(index), (long)v); } public void setIndexedRealValue (long index, double v) { + if (this.runid == 0) return; setindexedrealval (this.runid, this.valid, Long.toString(index), v); } public void setIndexedRealValue (long index, float v) { + if (this.runid == 0) return; setindexedrealval (this.runid, this.valid, Long.toString(index), (double)v); } public void setIndexedStringValue (long index, String v) { + if (this.runid == 0) return; setindexedstrval (this.runid, this.valid, Long.toString(index), v); } public void clear () { + if (this.runid == 0) return; clearval (this.runid, this.valid); } diff --git a/ase/awk/func.c b/ase/awk/func.c index 5d27f4d4..a90970be 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.14 2007/10/31 13:56:54 bacon Exp $ + * $Id: func.c,v 1.15 2007/11/02 13:16:48 bacon Exp $ * * {License} */ @@ -1346,7 +1346,8 @@ static int bfn_sprintf ( return -1; } - a0 = ase_awk_makestrval_nodup (run, ptr, len); + /*a0 = ase_awk_makestrval_nodup (run, ptr, len);*/ + a0 = ase_awk_makestrval (run, ptr, len); if (a0 == ASE_NULL) { ase_str_close (&fbu); @@ -1356,7 +1357,8 @@ static int bfn_sprintf ( } ase_str_close (&fbu); - ase_str_forfeit (&out); + /*ase_str_forfeit (&out);*/ + ase_str_close (&out); ase_awk_setretval (run, a0); return 0; } diff --git a/ase/awk/jni-dmc.def b/ase/awk/jni-dmc.def index ea74a8c9..f620b76f 100644 --- a/ase/awk/jni-dmc.def +++ b/ase/awk/jni-dmc.def @@ -22,11 +22,14 @@ EXPORTS Java_ase_awk_Awk_strfgmtime Java_ase_awk_Awk_system Java_ase_awk_Context_stop + Java_ase_awk_Context_getglobal + Java_ase_awk_Context_setglobal Java_ase_awk_Argument_getintval Java_ase_awk_Argument_getrealval Java_ase_awk_Argument_getstrval Java_ase_awk_Argument_isindexed Java_ase_awk_Argument_getindexed + Java_ase_awk_Argument_clearval Java_ase_awk_Return_isindexed Java_ase_awk_Return_setintval Java_ase_awk_Return_setrealval diff --git a/ase/awk/jni.c b/ase/awk/jni.c index b772ffc9..bb7e168c 100644 --- a/ase/awk/jni.c +++ b/ase/awk/jni.c @@ -1,5 +1,5 @@ /* - * $Id: jni.c,v 1.44 2007/11/01 14:01:00 bacon Exp $ + * $Id: jni.c,v 1.46 2007/11/02 10:47:51 bacon Exp $ * * {License} */ @@ -123,6 +123,7 @@ struct run_data_t jmethodID context_clear; + jfieldID argument_valid; jfieldID return_valid; jobject context_object; @@ -713,7 +714,7 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_run (JNIEnv* env, jobject obj, jlong awk run_data.context_init = (*env)->GetMethodID ( env, run_data.context_class, "", "(Lase/awk/Awk;)V"); run_data.argument_init = (*env)->GetMethodID ( - env, run_data.argument_class, "", "(JJ)V"); + env, run_data.argument_class, "", "(Lase/awk/Context;JJ)V"); run_data.return_init = (*env)->GetMethodID ( env, run_data.return_class, "", "(JJ)V"); @@ -737,9 +738,12 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_run (JNIEnv* env, jobject obj, jlong awk ASE_ASSERT (run_data.context_clear != ASE_NULL); + run_data.argument_valid = (*env)->GetFieldID ( + env, run_data.argument_class, FIELD_VALID, "J"); run_data.return_valid = (*env)->GetFieldID ( env, run_data.return_class, FIELD_VALID, "J"); - if (run_data.return_valid == ASE_NULL) + if (run_data.argument_valid == ASE_NULL || + run_data.return_valid == ASE_NULL) { if (is_debug(awk)) (*env)->ExceptionDescribe (env); (*env)->ExceptionClear (env); @@ -1648,8 +1652,8 @@ static int handle_bfn ( } ret = (*env)->NewObject (env, - run_data->return_class, - run_data->return_init, (jlong)run, (jlong)0); + run_data->return_class, run_data->return_init, + (jlong)run, (jlong)0); if (ret == ASE_NULL) { (*env)->DeleteLocalRef (env, name); @@ -1677,9 +1681,16 @@ static int handle_bfn ( { v = ase_awk_getarg (run, i); + /* these arguments are not registered for clearance into + * the context. so ASE_NULL is passed as the first argument + * to the constructor of the Argument class. It is because + * the reference count of these arguments are still positive + * while this function runs. However, if you ever use an + * argument outside the current context, it may cause + * a program failure such as program crash */ arg = (*env)->NewObject (env, run_data->argument_class, run_data->argument_init, - (jlong)run, (jlong)v); + ASE_NULL, (jlong)run, (jlong)v); if (arg == ASE_NULL) { if ((*env)->ExceptionCheck(env)) @@ -1728,8 +1739,11 @@ static int handle_bfn ( /* refdown on ret.valid is needed here */ vi = (*env)->GetLongField (env, ret, run_data->return_valid); - if (vi != 0) ase_awk_refdownval (run, v); - (*env)->SetLongField (env, ret, run_data->return_valid ,(jlong)0); + if (vi != 0) + { + ase_awk_refdownval (run, (ase_awk_val_t*)vi); + (*env)->SetLongField (env, ret, run_data->return_valid ,(jlong)0); + } (*env)->DeleteLocalRef (env, ret); (*env)->DeleteLocalRef (env, name); @@ -1813,7 +1827,8 @@ static int handle_bfn ( (*env)->DeleteLocalRef (env, ret); (*env)->DeleteLocalRef (env, name); - (*env)->CallVoidMethod (env, run_data->context_object, run_data->context_clear); + (*env)->CallVoidMethod (env, + run_data->context_object, run_data->context_clear); if ((*env)->ExceptionCheck(env)) { if (is_debug(awk)) (*env)->ExceptionDescribe (env); @@ -2363,16 +2378,13 @@ JNIEXPORT void JNICALL Java_ase_awk_Context_setglobal (JNIEnv* env, jobject obj, /* invalidate the value field in the return object */ (*env)->SetLongField (env, ret, run_data->return_valid, (jlong)0); -OutputDebugStringW(L"11111111111111111111\n"); if (ase_awk_setglobal(run,id,v) == -1) { -OutputDebugStringW(L"333333333333333333333\n"); if (vi != 0) ase_awk_refdownval (run, v); THROW_RUN_EXCEPTION (env, run); return; } -OutputDebugStringW(L"2222222222222222222222\n"); if (vi != 0) ase_awk_refdownval (run, v); } @@ -2389,9 +2401,12 @@ JNIEXPORT jobject JNICALL Java_ase_awk_Context_getglobal (JNIEnv* env, jobject o g = ase_awk_getglobal(run, id); + ASE_ASSERTX ((*env)->IsSameObject(env,obj,run_data->context_object), + "this object(obj) should be the same object as the context object(run_data->context_object)"); + arg = (*env)->NewObject (env, run_data->argument_class, run_data->argument_init, - (jlong)run, (jlong)g); + obj, (jlong)run, (jlong)g); if (arg == ASE_NULL) { if (is_debug(awk)) (*env)->ExceptionDescribe (env); @@ -2400,6 +2415,11 @@ JNIEXPORT jobject JNICALL Java_ase_awk_Context_getglobal (JNIEnv* env, jobject o return ASE_NULL; } + /* the reference is incremented. this incremented reference is + * decremented in Argument.clear called from Context.clear. + * Note that the context object (obj) is passed to the contrustor of + * the argument class in the call to NewObject above */ + ase_awk_refupval (run, g); return arg; } @@ -2533,9 +2553,15 @@ JNIEXPORT jobject JNICALL Java_ase_awk_Argument_getindexed (JNIEnv* env, jobject arg = (*env)->NewObject (env, run_data->argument_class, run_data->argument_init, - (jlong)run, (jlong)pair->val); + run_data->context_object, (jlong)run, (jlong)pair->val); if (arg == ASE_NULL) goto nomem; + /* the reference is incremented. this incremented reference is + * decremented in Argument.clear called from Context.clear. + * Note that the context object (run_data->context_object) is + * passed to the contrustor of the argument class in the call + * to NewObject above */ + ase_awk_refupval (run, pair->val); return arg; nomem: @@ -2549,6 +2575,19 @@ nomem: return ASE_NULL; } +JNIEXPORT void JNICALL Java_ase_awk_Argument_clearval (JNIEnv* env, jobject obj, jlong runid, jlong valid) +{ + ase_awk_run_t* run = (ase_awk_run_t*)runid; + ase_awk_val_t* val = (ase_awk_val_t*)valid; + run_data_t* run_data; + + run_data = (run_data_t*)ase_awk_getruncustomdata (run); + + if (val != ASE_NULL) ase_awk_refdownval (run, val); + (*env)->SetLongField (env, obj, run_data->argument_valid, (jlong)0); +} + + JNIEXPORT jboolean JNICALL Java_ase_awk_Return_isindexed (JNIEnv* env, jobject obj, jlong runid, jlong valid) { ase_awk_run_t* run = (ase_awk_run_t*)runid; diff --git a/ase/awk/jni.def b/ase/awk/jni.def index 474a2aab..6db25f6c 100644 --- a/ase/awk/jni.def +++ b/ase/awk/jni.def @@ -21,11 +21,14 @@ EXPORTS Java_ase_awk_Awk_strfgmtime Java_ase_awk_Awk_system Java_ase_awk_Context_stop + Java_ase_awk_Context_getglobal + Java_ase_awk_Context_setglobal Java_ase_awk_Argument_getintval Java_ase_awk_Argument_getrealval Java_ase_awk_Argument_getstrval Java_ase_awk_Argument_isindexed Java_ase_awk_Argument_getindexed + Java_ase_awk_Argument_clearval Java_ase_awk_Return_isindexed Java_ase_awk_Return_setintval Java_ase_awk_Return_setrealval diff --git a/ase/awk/jni.h b/ase/awk/jni.h index 8c8a5e1f..0031f947 100644 --- a/ase/awk/jni.h +++ b/ase/awk/jni.h @@ -1,5 +1,5 @@ /* - * $Id: jni.h,v 1.15 2007/10/24 14:17:32 bacon Exp $ + * $Id: jni.h,v 1.16 2007/11/02 05:49:19 bacon Exp $ * * {License} */ @@ -60,12 +60,15 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_system ( JNIEnv* env, jobject obj, jstring cmd); JNIEXPORT void JNICALL Java_ase_awk_Context_stop (JNIEnv* env, jobject obj, jlong runid); +JNIEXPORT jobject JNICALL Java_ase_awk_Context_getglobal (JNIEnv* env, jobject obj, jlong runid, jint id); +JNIEXPORT void JNICALL Java_ase_awk_Context_setglobal (JNIEnv* env, jobject obj, jlong runid, jint id, jobject ret); JNIEXPORT jlong JNICALL Java_ase_awk_Argument_getintval (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT jdouble JNICALL Java_ase_awk_Argument_getrealval (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT jstring JNICALL Java_ase_awk_Argument_getstrval (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT jboolean JNICALL Java_ase_awk_Argument_isindexed (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT jobject JNICALL Java_ase_awk_Argument_getindexed (JNIEnv* env, jobject obj, jlong runid, jlong valid, jstring index); +JNIEXPORT void JNICALL Java_ase_awk_Argument_clearval (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT jboolean JNICALL Java_ase_awk_Return_isindexed (JNIEnv* env, jobject obj, jlong runid, jlong valid); JNIEXPORT void JNICALL Java_ase_awk_Return_setintval (JNIEnv* env, jobject obj, jlong runid, jlong valid, jlong newval); diff --git a/ase/awk/msw-bcc.mak b/ase/awk/msw-bcc.mak index 7daab1c6..b4ee01f8 100644 --- a/ase/awk/msw-bcc.mak +++ b/ase/awk/msw-bcc.mak @@ -57,6 +57,9 @@ OBJ_FILES_JAR = \ $(TMP_DIR)\ase\awk\Awk.class \ $(TMP_DIR)\ase\awk\StdAwk.class \ $(TMP_DIR)\ase\awk\Context.class \ + $(TMP_DIR)\ase\awk\Clearable.class \ + $(TMP_DIR)\ase\awk\Argument.class \ + $(TMP_DIR)\ase\awk\Return.class $(TMP_DIR)\ase\awk\Extio.class \ $(TMP_DIR)\ase\awk\IO.class \ $(TMP_DIR)\ase\awk\Console.class \ @@ -147,6 +150,15 @@ $(TMP_DIR)\ase\awk\StdAwk.class: StdAwk.java $(TMP_DIR)\ase\awk\Context.class: Context.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Context.java +$(TMP_DIR)\ase\awk\Clearable.class: Clearable.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Clearable.java + +$(TMP_DIR)\ase\awk\Argument.class: Argument.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Argument.java + +$(TMP_DIR)\ase\awk\Return.class: Return.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Return.java + $(TMP_DIR)\ase\awk\Extio.class: Extio.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Extio.java diff --git a/ase/awk/msw-cl.mak b/ase/awk/msw-cl.mak index 1d4eb6d7..253225d2 100644 --- a/ase/awk/msw-cl.mak +++ b/ase/awk/msw-cl.mak @@ -64,6 +64,9 @@ OBJ_FILES_JAR = \ $(TMP_DIR)\ase\awk\Awk.class \ $(TMP_DIR)\ase\awk\StdAwk.class \ $(TMP_DIR)\ase\awk\Context.class \ + $(TMP_DIR)\ase\awk\Clearable.class \ + $(TMP_DIR)\ase\awk\Argument.class \ + $(TMP_DIR)\ase\awk\Return.class \ $(TMP_DIR)\ase\awk\Extio.class \ $(TMP_DIR)\ase\awk\IO.class \ $(TMP_DIR)\ase\awk\Console.class \ @@ -156,6 +159,15 @@ $(TMP_DIR)\ase\awk\StdAwk.class: StdAwk.java $(TMP_DIR)\ase\awk\Context.class: Context.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Context.java +$(TMP_DIR)\ase\awk\Clearable.class: Clearable.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Clearable.java + +$(TMP_DIR)\ase\awk\Argument.class: Argument.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Argument.java + +$(TMP_DIR)\ase\awk\Return.class: Return.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Return.java + $(TMP_DIR)\ase\awk\Extio.class: Extio.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Extio.java diff --git a/ase/awk/msw-dmc.mak b/ase/awk/msw-dmc.mak index 57161711..d6ed8c29 100644 --- a/ase/awk/msw-dmc.mak +++ b/ase/awk/msw-dmc.mak @@ -42,6 +42,9 @@ OBJ_FILES_JAR = \ $(TMP_DIR)\ase\awk\Awk.class \ $(TMP_DIR)\ase\awk\StdAwk.class \ $(TMP_DIR)\ase\awk\Context.class \ + $(TMP_DIR)\ase\awk\Clearable.class \ + $(TMP_DIR)\ase\awk\Argument.class \ + $(TMP_DIR)\ase\awk\Return.class $(TMP_DIR)\ase\awk\Extio.class \ $(TMP_DIR)\ase\awk\IO.class \ $(TMP_DIR)\ase\awk\Console.class \ @@ -117,6 +120,15 @@ $(TMP_DIR)\ase\awk\StdAwk.class: StdAwk.java $(TMP_DIR)\ase\awk\Context.class: Context.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Context.java +$(TMP_DIR)\ase\awk\Clearable.class: Clearable.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Clearable.java + +$(TMP_DIR)\ase\awk\Argument.class: Argument.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Argument.java + +$(TMP_DIR)\ase\awk\Return.class: Return.java + $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Return.java + $(TMP_DIR)\ase\awk\Extio.class: Extio.java $(JAVAC) $(JAVACFLAGS) -d $(TMP_DIR) Extio.java diff --git a/ase/awk/val.c b/ase/awk/val.c index c4517958..1f0c4c3f 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.10 2007/10/21 13:58:47 bacon Exp $ + * $Id: val.c,v 1.11 2007/11/02 13:08:58 bacon Exp $ * * {License} */ @@ -135,6 +135,7 @@ ase_awk_val_t* ase_awk_makestrval ( { ase_awk_val_str_t* val; + /* val = (ase_awk_val_str_t*) ASE_AWK_MALLOC ( run->awk, ASE_SIZEOF(ase_awk_val_str_t)); if (val == ASE_NULL) @@ -153,6 +154,24 @@ ase_awk_val_t* ase_awk_makestrval ( ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); return ASE_NULL; } + */ + + val = (ase_awk_val_str_t*) ASE_AWK_MALLOC ( + run->awk, + ASE_SIZEOF(ase_awk_val_str_t) + + (len+1)*ASE_SIZEOF(ase_char_t)); + if (val == ASE_NULL) + { + ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + return ASE_NULL; + } + + val->type = ASE_AWK_VAL_STR; + val->ref = 0; + val->len = len; + val->buf = (ase_char_t*)(val + 1); + /*ase_strxncpy (val->buf, len+1, str, len);*/ + ase_strncpy (val->buf, str, len); #ifdef DEBUG_VAL ase_dprintf (ASE_T("makestrval => %p\n"), val); @@ -187,6 +206,7 @@ ase_awk_val_t* ase_awk_makestrval2 ( { ase_awk_val_str_t* val; + /* val = (ase_awk_val_str_t*) ASE_AWK_MALLOC ( run->awk, ASE_SIZEOF(ase_awk_val_str_t)); if (val == ASE_NULL) @@ -205,6 +225,26 @@ ase_awk_val_t* ase_awk_makestrval2 ( ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); return ASE_NULL; } + */ + + val = (ase_awk_val_str_t*) ASE_AWK_MALLOC ( + run->awk, + ASE_SIZEOF(ase_awk_val_str_t) + + (len1+len2+1)*ASE_SIZEOF(ase_char_t)); + if (val == ASE_NULL) + { + ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + return ASE_NULL; + } + + val->type = ASE_AWK_VAL_STR; + val->ref = 0; + val->len = len1 + len2; + val->buf = (ase_char_t*)(val + 1); + /*ase_strxncpy (val->buf, len1+1, str1, len1); + ase_strxncpy (val->buf[len1], len2+1, str2, len2);*/ + ase_strncpy (val->buf, str1, len1); + ase_strncpy (&val->buf[len1], str2, len2); #ifdef DEBUG_VAL ase_dprintf (ASE_T("makestrval2 => %p\n"), val); @@ -355,7 +395,7 @@ void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache) } else if (val->type == ASE_AWK_VAL_STR) { - ASE_AWK_FREE (run->awk, ((ase_awk_val_str_t*)val)->buf); + /*ASE_AWK_FREE (run->awk, ((ase_awk_val_str_t*)val)->buf);*/ ASE_AWK_FREE (run->awk, val); } else if (val->type == ASE_AWK_VAL_REX) diff --git a/ase/test/awk/AseAwkPanel.java b/ase/test/awk/AseAwkPanel.java index 8b714f5a..eaa1371e 100644 --- a/ase/test/awk/AseAwkPanel.java +++ b/ase/test/awk/AseAwkPanel.java @@ -1,5 +1,5 @@ /* - * $Id: AseAwkPanel.java,v 1.17 2007/11/01 14:01:00 bacon Exp $ + * $Id: AseAwkPanel.java,v 1.20 2007/11/02 13:08:58 bacon Exp $ */ import java.awt.*; @@ -9,12 +9,15 @@ import java.net.URL; import java.net.URLConnection; import java.io.File; import java.io.IOException; +import java.io.FileNotFoundException; import java.io.StringReader; import java.io.StringWriter; import java.io.Reader; import java.io.Writer; import java.io.InputStream; +import java.io.FileInputStream; import java.io.FileOutputStream; +import java.security.MessageDigest; import ase.awk.StdAwk; import ase.awk.Console; @@ -25,6 +28,7 @@ import ase.awk.Return; public class AseAwkPanel extends Panel { /* MsgBox taken from http://www.rgagnon.com/javadetails/java-0242.html */ + class MsgBox extends Dialog implements ActionListener { boolean id = false; @@ -95,17 +99,23 @@ public class AseAwkPanel extends Panel this.awkPanel = awkPanel; addFunction ("sleep", 1, 1); + /* setWord ("sin", "cain"); setWord ("length", "len"); setWord ("OFMT", "ofmt"); + */ } public void sleep (Context ctx, String name, Return ret, Argument[] args) throws ase.awk.Exception { - try { Thread.sleep (args[0].getIntValue() * 1000); } + Argument t = args[0]; + //if (args[0].isIndexed()) t = args[0].getIndexed(0); + + try { Thread.sleep (t.getIntValue() * 1000); } catch (InterruptedException e) {} - //ret.setIntValue (0); - // + + ret.setIntValue (0); + /* ret.setIndexedRealValue (1, 111.23); ret.setIndexedStringValue (2, "1111111"); ret.setIndexedStringValue (3, "22222222"); @@ -115,14 +125,15 @@ public class AseAwkPanel extends Panel Return r = new Return (ctx); r.setStringValue ("[[%.6f]]"); Return r2 = new Return (ctx); - r.setStringValue ("[[%.6f]]"); + r2.setStringValue ("[[%.6f]]"); //ctx.setGlobal (Context.GLOBAL_CONVFMT, ret); Argument g = ctx.getGlobal (Context.GLOBAL_CONVFMT); ctx.setGlobal (Context.GLOBAL_CONVFMT, r2); - System.out.println (g.getStringValue()); + System.out.println (g.getStringValue()); g = ctx.getGlobal (Context.GLOBAL_CONVFMT); - System.out.println (g.getStringValue()); + System.out.println (g.getStringValue()); + */ } protected int openSource (int mode) @@ -289,6 +300,7 @@ public class AseAwkPanel extends Panel private TextArea conOut; private TextField entryPoint; private TextField jniLib; + private Label statusLabel; private boolean jniLibLoaded = false; @@ -348,12 +360,17 @@ public class AseAwkPanel extends Panel }; public AseAwkPanel () + { + prepareUserInterface (); + prepareNativeInterface (); + } + + private void prepareUserInterface () { jniLib = new TextField (); Font font = new Font ("Monospaced", Font.PLAIN, 14); - srcIn = new TextArea (); srcOut = new TextArea (); conIn = new TextArea (); @@ -459,13 +476,17 @@ public class AseAwkPanel extends Panel mainLayout.setVgap (2); setLayout (mainLayout); - + statusLabel = new Label ("Ready"); + statusLabel.setBackground (Color.GREEN); + add (topPanel, BorderLayout.NORTH); add (centerPanel, BorderLayout.CENTER); add (leftPanel, BorderLayout.WEST); + add (statusLabel, BorderLayout.SOUTH); + } - //////////////////////////////////////////////////////////// - + public void prepareNativeInterface () + { String osname = System.getProperty ("os.name").toLowerCase(); URL url = this.getClass().getResource ( @@ -486,15 +507,16 @@ public class AseAwkPanel extends Panel { base = "http://" + base.substring(6).replace('\\', '/'); String jniUrl = base + "/lib/aseawk_jni.dll"; + String md5Url = jniUrl + ".md5"; String userHome = System.getProperty("user.home"); path = userHome + "\\aseawk_jni.dll"; try { - copyNative (jniUrl, path); + downloadNative (md5Url, jniUrl, path); } - catch (IOException e) + catch (Exception e) { showMessage ("Cannot download native library - " + e.getMessage()); path = "ERROR - Not Available"; @@ -592,22 +614,30 @@ public class AseAwkPanel extends Panel } } + statusLabel.setText ("Parsing..."); awk.parse (); String main = entryPoint.getText().trim(); + + statusLabel.setText ("Running..."); if (main.length() > 0) awk.run (main); else awk.run (); + statusLabel.setText ("Done..."); } catch (ase.awk.Exception e) { + String msg; int line = e.getLine(); int code = e.getCode(); - if (line <= 0) - showMessage ("An exception occurred - [" + code + "] " + e.getMessage()); - else - showMessage ("An exception occurred - [" + code + "] " + e.getMessage() + " at line " + line); + if (line <= 0) + msg = "An exception occurred - [" + code + "] " + e.getMessage(); + else + msg = "An exception occurred - [" + code + "] " + e.getMessage() + " at line " + line; + + statusLabel.setText (msg); + showMessage (msg); return; } finally @@ -626,11 +656,91 @@ public class AseAwkPanel extends Panel } - private void copyNative (String sourceURL, String destFile) throws IOException + private String getFileMD5 (String file) throws Exception + { + MessageDigest md = MessageDigest.getInstance("MD5"); + FileInputStream fis = null; + + try + { + fis = new FileInputStream (file); + + int n; + byte[] b = new byte[1024]; + while ((n = fis.read(b)) != -1) + { + md.update (b, 0, n); + } + } + catch (FileNotFoundException e) { return ""; } + catch (IOException e) { throw e; } + finally + { + if (fis != null) + { + try { fis.close (); } + catch (IOException e) {} + fis = null; + } + } + + StringBuffer buf = new StringBuffer (); + byte[] d = md.digest (); + for (int i = 0; i < d.length; i++) + { + String x = Integer.toHexString((d[i] & 0x00FF)); + if (x.length() == 1) buf.append ('0'); + buf.append (x); + } + return buf.toString(); + } + + private void downloadNative (String md5URL, String sourceURL, String destFile) throws Exception { InputStream is = null; FileOutputStream fos = null; + String sumRemote = null; + /* download the checksum file */ + try + { + URL url = new URL (md5URL); + URLConnection conn = url.openConnection (); + + is = url.openStream (); + + int n, total = 0; + byte[] b = new byte[32]; + while ((n = is.read(b, total, 32-total)) != -1) + { + total += n; + if (total >= 32) + { + sumRemote = new String (b); + break; + } + } + } + catch (IOException e) { throw e; } + finally + { + if (is != null) + { + try { is.close (); } + catch (IOException e) {} + is = null; + } + } + + if (sumRemote != null) + { + /* if the checksum matches the checksum of the local file, + * the native library file doesn't have to be downloaded */ + String sumLocal = getFileMD5 (destFile); + if (sumRemote.equalsIgnoreCase(sumLocal)) return; + } + + /* download the actual file */ try { URL url = new URL(sourceURL); @@ -653,13 +763,15 @@ public class AseAwkPanel extends Panel { try { is.close (); } catch (IOException e) {} + is = null; } if (fos != null) { try { fos.close (); } catch (IOException e) {} + fos = null; } } - } + } }