From 6a67beb6ef8f7d1bca98877b9f55e1dbbf8cef4f Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 23 Jan 2007 14:23:18 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/Awk.java | 65 +++--- ase/awk/Exception.java | 36 +++- ase/awk/StdAwk.java | 336 ++++++++++++++++++----------- ase/awk/jni.c | 478 +++++++++++++++++++++++++---------------- ase/awk/jni.h | 11 +- ase/awk/run.c | 31 ++- ase/test/awk/Awk.java | 47 ++-- ase/test/awk/awk.c | 17 +- ase/test/awk/t4.awk | 5 +- 9 files changed, 644 insertions(+), 382 deletions(-) diff --git a/ase/awk/Awk.java b/ase/awk/Awk.java index 00df51dd..a24c3826 100644 --- a/ase/awk/Awk.java +++ b/ase/awk/Awk.java @@ -1,5 +1,5 @@ /* - * $Id: Awk.java,v 1.18 2007-01-19 03:23:47 bacon Exp $ + * $Id: Awk.java,v 1.19 2007-01-23 14:23:17 bacon Exp $ */ package ase.awk; @@ -14,6 +14,14 @@ public abstract class Awk public static final int SOURCE_READ = 1; public static final int SOURCE_WRITE = 2; + // depth id + public static final int DEPTH_BLOCK_PARSE = (1 << 0); + public static final int DEPTH_BLOCK_RUN = (1 << 1); + public static final int DEPTH_EXPR_PARSE = (1 << 2); + public static final int DEPTH_EXPR_RUN = (1 << 3); + public static final int DEPTH_REX_BUILD = (1 << 4); + public static final int DEPTH_REX_MATCH = (1 << 5); + static { /* @@ -60,8 +68,11 @@ public abstract class Awk public native void parse () throws Exception; public native void run () throws Exception; - private native int addbfn (String name, int min_args, int max_args); - private native int delbfn (String name); + private native int getmaxdepth (int id); + private native int setmaxdepth (int id, int depth); + + private native void addbfn (String name, int min_args, int max_args) throws Exception; + private native void delbfn (String name) throws Exception; private native int setfilename (long runid, String name); private native int setofilename (long runid, String name); @@ -73,23 +84,15 @@ public abstract class Awk public void addBuiltinFunction ( String name, int min_args, int max_args) throws Exception { - if (addbfn (name, min_args, max_args) == -1) - { - throw new Exception ( - "cannot add the built-in function - " + name); - } + addbfn (name, min_args, max_args); } public void deleteBuiltinFunction (String name) throws Exception { - if (delbfn (name) == -1) - { - throw new Exception ( - "cannot delete the built-in function - " + name); - } + delbfn (name); } - public long builtinFunctionArgumentToLong (long runid, Object obj) + protected long builtinFunctionArgumentToLong (long runid, Object obj) { long n; @@ -125,7 +128,7 @@ public abstract class Awk return n; } - public double builtinFunctionArgumentToDouble (long runid, Object obj) + protected double builtinFunctionArgumentToDouble (long runid, Object obj) { double n; @@ -161,7 +164,7 @@ public abstract class Awk return n; } - public String builtinFunctionArgumentToString (long runid, Object obj) + protected String builtinFunctionArgumentToString (long runid, Object obj) { String str; @@ -173,30 +176,34 @@ public abstract class Awk } /* == console name setters == */ - public void setInputConsoleName (Extio extio, String name) //throws Exception + protected void setConsoleInputName (Extio extio, String name) throws Exception { - /* TODO: setconsolename is not safe. for example, it can + /* TODO: setfilename is not safe. for example, it can * crash the program if runid is invalid. so this wrapper * needs to do some sanity check. */ - //if (setconsolename (runid, name) == -1) - // throw new Exception ("cannot set the consle name"); - setfilename (extio.getRunId(), name); + if (setfilename (extio.getRunId(), name) == -1) + { + throw new Exception ("cannot set console input name"); + } } - public void setOutputConsoleName (Extio extio, String name) + protected void setConsoleOutputName (Extio extio, String name) throws Exception { - // TODO: - setofilename (extio.getRunId(), name); + if (setofilename (extio.getRunId(), name) == -1) + { + throw new Exception ("cannot set console output name"); + } } - /* == recursion depth limiting == */ - protected int getMaxParseDepth () + /* == depth limiting == */ + public int getMaxDepth (int id) { - return 0; + return getmaxdepth (id); } - protected int getMaxRunDepth () + + public void setMaxDepth (int ids, int depth) { - return 0; + setmaxdepth (ids, depth); } /* == source code management == */ diff --git a/ase/awk/Exception.java b/ase/awk/Exception.java index daea926a..26ac8721 100644 --- a/ase/awk/Exception.java +++ b/ase/awk/Exception.java @@ -1,19 +1,49 @@ /* - * $Id: Exception.java,v 1.2 2007-01-21 13:31:30 bacon Exp $ + * $Id: Exception.java,v 1.3 2007-01-23 14:23:18 bacon Exp $ */ package ase.awk; public class Exception extends java.lang.Exception { - Exception () + private int code; + private int line; + + public Exception () { super (); + this.code = 0; + this.line = 0; } - Exception (String msg) + public Exception (String msg) { super (msg); + this.code = 0; + this.line = 0; } + public Exception (String msg, int code) + { + super (msg); + this.code = code; + this.line = 0; + } + + public Exception (String msg, int code, int line) + { + super (msg); + this.code = code; + this.line = line; + } + + public int getCode () + { + return this.code; + } + + public int getLine () + { + return this.line; + } } diff --git a/ase/awk/StdAwk.java b/ase/awk/StdAwk.java index 164e63f3..a1aeade3 100644 --- a/ase/awk/StdAwk.java +++ b/ase/awk/StdAwk.java @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.java,v 1.10 2007-01-21 13:21:13 bacon Exp $ + * $Id: StdAwk.java,v 1.11 2007-01-23 14:23:18 bacon Exp $ */ package ase.awk; @@ -8,12 +8,14 @@ import java.io.*; public abstract class StdAwk extends Awk { - private InputStreamReader src_in = null; - private OutputStreamWriter src_out = null; + private Reader src_in = null; + private Writer src_out = null; private String[] sin = null; private int sin_no = 0; - private String sout = null; + + private String[] sout = null; + private int sout_no = 0; private String[] cin = null; private int cin_no = 0; @@ -23,6 +25,17 @@ public abstract class StdAwk extends Awk private long seed; private java.util.Random random; + private static Reader stdin = null; + private static Writer stdout = null; + + static + { + stdin = new BufferedReader ( + new InputStreamReader (System.in)); + stdout = new BufferedWriter ( + new OutputStreamWriter (System.out)); + } + public StdAwk () throws Exception { super (); @@ -34,36 +47,37 @@ public abstract class StdAwk extends Awk /* == major methods == */ public void parse () throws Exception { - sin = getSourceNames (); sin_no = 0; - sout = getDeparsedSourceName (); + sin = sourceInputNames (); sin_no = 0; + sout = sourceOutputNames (); sout_no = 0; super.parse (); } public void run () throws Exception { - cin = getInputConsoleNames (); cin_no = 0; - cout = getOutputConsoleNames (); cout_no = 0; + cin = consoleInputNames (); cin_no = 0; + cout = consoleOutputNames (); cout_no = 0; super.run (); } /* == source code names == */ - protected abstract String[] getSourceNames (); - protected String getDeparsedSourceName () { return null; } + protected abstract String[] sourceInputNames (); + protected String[] sourceOutputNames () { return null; } /* == console names == */ - protected abstract String[] getInputConsoleNames (); - protected abstract String[] getOutputConsoleNames (); + protected abstract String[] consoleInputNames (); + protected abstract String[] consoleOutputNames (); /* == source code == */ protected int openSource (int mode) { if (mode == SOURCE_READ) { - InputStreamReader isr; + Reader isr; sin_no = 0; - if (sin_no >= sin.length) return 0; - isr = get_input_stream (sin[sin_no]); + if (sin == null || sin_no >= sin.length) return 0; + + isr = get_stream_reader (sin[sin_no]); if (isr == null) return -1; src_in = isr; @@ -72,11 +86,20 @@ public abstract class StdAwk extends Awk } else if (mode == SOURCE_WRITE) { - OutputStreamWriter osw; + Writer osw; + sout_no = 0; + + // when sout is null, the source output is treated + // as if the operation has been successful with + // the writeSource and closeSource method. if (sout == null) return 1; - osw = get_output_stream (sout); + if (sout_no >= sin.length) return 0; + + osw = get_stream_writer (sout[sout_no]); if (osw == null) return -1; + src_out = osw; + sout_no++; return 1; } @@ -87,15 +110,22 @@ public abstract class StdAwk extends Awk { if (mode == SOURCE_READ) { - try { src_in.close (); } - catch (IOException e) { return -1; } + if (src_in != StdAwk.stdin) + { + try { src_in.close (); } + catch (IOException e) { return -1; } + } return 0; } else if (mode == SOURCE_WRITE) { if (src_out == null) return 0; - try { src_out.close (); } - catch (IOException e) { return -1; } + + if (src_out != StdAwk.stdout) + { + try { src_out.close (); } + catch (IOException e) { return -1; } + } return 0; } @@ -108,14 +138,17 @@ public abstract class StdAwk extends Awk int n = src_in.read (buf, 0, len); while (n == -1) { - InputStreamReader isr; - if (sin_no >= sin.length) return 0; + Reader isr; + if (sin == null || sin_no >= sin.length) return 0; - isr = get_input_stream (sin[sin_no]); + isr = get_stream_reader (sin[sin_no]); if (isr == null) return -1; - try { src_in.close (); } - catch (IOException ec) { /* ignore */ } + if (src_in != StdAwk.stdin) + { + try { src_in.close (); } + catch (IOException ec) { /* ignore */ } + } src_in = isr; sin_no++; @@ -134,8 +167,13 @@ public abstract class StdAwk extends Awk protected int writeSource (char[] buf, int len) { if (src_out == null) return len; + + // only the first file is used at the moment. + // this is because the write message doesn't indicate + // the end of the output stream. try { src_out.write (buf, 0, len); } catch (IOException e) { return -1; } + return len; } @@ -148,30 +186,33 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_READ) { - InputStreamReader isr; + /*InputStream*/Reader isr; cin_no = 0; - if (cin_no >= cin.length) return 0; - isr = get_input_stream (cin[cin_no]); + if (cin == null || cin_no >= cin.length) return 0; + isr = get_stream_reader (cin[cin_no]); if (isr == null) return -1; extio.setHandle (isr); - setInputConsoleName (extio, cin[cin_no]); + + try { setConsoleInputName (extio, cin[cin_no]); } + catch (Exception e) { return -1; } cin_no++; return 1; } else if (mode == Extio.MODE_CONSOLE_WRITE) { - OutputStreamWriter osw; + Writer osw; cout_no = 0; - if (cout_no >= cout.length) return 0; - osw = get_output_stream (cout[cout_no]); + if (cout == null || cout_no >= cout.length) return 0; + osw = get_stream_writer (cout[cout_no]); if (osw == null) return -1; extio.setHandle (osw); - setOutputConsoleName (extio, cout[cout_no]); + try { setConsoleOutputName (extio, cout[cout_no]); } + catch (Exception e) { return -1; } cout_no++; return 1; @@ -188,18 +229,26 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_READ) { - InputStreamReader isr = (InputStreamReader)extio.getHandle (); - try { isr.close (); } - catch (IOException e) { return -1; } + Reader isr = (Reader)extio.getHandle (); + + if (isr != StdAwk.stdin) + { + try { isr.close (); } + catch (IOException e) { return -1; } + } return 0; } else if (mode == Extio.MODE_CONSOLE_WRITE) { - OutputStreamWriter osw = (OutputStreamWriter)extio.getHandle (); + Writer osw = (Writer)extio.getHandle (); /* TODO: selective close the stream... * system.out should not be closed??? */ - try { osw.close (); } - catch (IOException e) { return -1; } + + if (osw != StdAwk.stdout) + { + try { osw.close (); } + catch (IOException e) { return -1; } + } return 0; } @@ -212,26 +261,31 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_READ) { - InputStreamReader isr, tmp; + Reader isr, tmp; int n; - isr = (InputStreamReader)extio.getHandle (); + isr = (Reader)extio.getHandle (); try { n = isr.read (buf, 0, len); } catch (IOException e) { return -1; } while (n == -1) { - if (cin_no >= cin.length) return 0; - tmp = get_input_stream (cin[cin_no]); + if (cin == null || cin_no >= cin.length) return 0; + tmp = get_stream_reader (cin[cin_no]); if (tmp == null) return -1; - try { isr.close (); } - catch (IOException e) { /* ignore */ } + if (isr != StdAwk.stdin) + { + try { isr.close (); } + catch (IOException e) { /* ignore */ } + } extio.setHandle (tmp); - setInputConsoleName (extio, cin[cin_no]); - isr = (InputStreamReader)extio.getHandle (); + try { setConsoleInputName (extio, cin[cin_no]); } + catch (Exception e) { return -1; } + + isr = (Reader)extio.getHandle (); cin_no++; try { n = isr.read (buf, 0, len); } @@ -252,11 +306,12 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle (); - // as the write operation below doesn't indicate - // if it has reached the end, console can't be - // switched here unlike read_console. + Writer osw; + + osw = (Writer)extio.getHandle (); + // as the write operation below doesn't + // indicate if it has reached the end, console + // can't be switched here unlike in read_console try { osw.write (buf, 0, len); osw.flush (); } catch (IOException e) { return -1; } @@ -272,10 +327,13 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle (); + Writer osw; + + osw = (Writer)extio.getHandle (); + try { osw.flush (); } catch (IOException e) { return -1; } + return 0; } @@ -288,40 +346,46 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_CONSOLE_READ) { - InputStreamReader isr, tmp; + Reader isr, tmp; - isr = (InputStreamReader)extio.getHandle (); + isr = (Reader)extio.getHandle (); - if (cin_no >= cin.length) return 0; - tmp = get_input_stream (cin[cin_no]); + if (cin == null || cin_no >= cin.length) return 0; + tmp = get_stream_reader (cin[cin_no]); if (tmp == null) return -1; - try { isr.close (); } - catch (IOException e) { /* ignore */ } + if (isr != StdAwk.stdin) + { + try { isr.close (); } + catch (IOException e) { /* ignore */ } + } extio.setHandle (tmp); - setInputConsoleName (extio, cin[cin_no]); + try { setConsoleInputName (extio, cin[cin_no]); } + catch (Exception e) { return -1; } cin_no++; return 1; } else if (mode == Extio.MODE_CONSOLE_WRITE) { - OutputStreamWriter osw, tmp; + Writer osw, tmp; - osw = (OutputStreamWriter)extio.getHandle (); + osw = (Writer)extio.getHandle (); - if (cout_no >= cout.length) return 0; - tmp = get_output_stream (cout[cout_no]); + if (cout == null || cout_no >= cout.length) return 0; + tmp = get_stream_writer (cout[cout_no]); if (tmp == null) return -1; - /* TODO: selectively close the stream... - * system.out should not be closed??? */ - try { osw.close (); } - catch (IOException e) { /* ignore */ } + if (osw != StdAwk.stdout) + { + try { osw.close (); } + catch (IOException e) { /* ignore */ } + } extio.setHandle (tmp); - setOutputConsoleName (extio, cout[cout_no]); + try { setConsoleOutputName (extio, cout[cout_no]); } + catch (Exception e) { return -1;} cout_no++; return 1; @@ -330,39 +394,54 @@ public abstract class StdAwk extends Awk return -1; } - private InputStreamReader get_input_stream (String name) + private Reader get_stream_reader (String name) { - InputStreamReader isr; + Reader isr; if (name == null || name.length() == 0) { - isr = new InputStreamReader (System.in); + //FileInputStream fis; + //fis = new FileInputStream (FileDescriptor.in); + //isr = new BufferedReader (new InputStreamReader (fis)); + + //isr = new BufferedReader ( + // new InputStreamReader (System.in)); + + isr = StdAwk.stdin; } else { FileInputStream fis; try { fis = new FileInputStream (name); } catch (IOException e) { return null; } - isr = new InputStreamReader (fis); + isr = new BufferedReader(new InputStreamReader (fis)); } return isr; } - private OutputStreamWriter get_output_stream (String name) + private Writer get_stream_writer (String name) { - OutputStreamWriter osw; + Writer osw; if (name == null || name.length() == 0) { - osw = new OutputStreamWriter (System.out); + + //FileOutputStream fos; + //fos = new FileOutputStream (FileDescriptor.out); + //osw = new BufferedWriter (new OutputStreamWriter (fos)); + + //osw = new BufferedWriter( + // new OutputStreamWriter (System.out)); + + osw = StdAwk.stdout; } else { FileOutputStream fos; try { fos = new FileOutputStream (name); } catch (IOException e) { return null; } - osw = new OutputStreamWriter (fos); + osw = new BufferedWriter (new OutputStreamWriter (fos)); } return osw; @@ -376,36 +455,36 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_FILE_READ) { FileInputStream fis; - InputStreamReader isr; + Reader isr; try { fis = new FileInputStream (extio.getName()); } catch (IOException e) { return -1; } - isr = new InputStreamReader (fis); + isr = new BufferedReader (new InputStreamReader (fis)); extio.setHandle (isr); return 1; } else if (mode == Extio.MODE_FILE_WRITE) { FileOutputStream fos; - OutputStreamWriter osw; + Writer osw; try { fos = new FileOutputStream (extio.getName()); } catch (IOException e) { return -1; } - osw = new OutputStreamWriter (fos); + osw = new BufferedWriter (new OutputStreamWriter (fos)); extio.setHandle (osw); return 1; } else if (mode == Extio.MODE_FILE_APPEND) { FileOutputStream fos; - OutputStreamWriter osw; + Writer osw; try { fos = new FileOutputStream (extio.getName(), true); } catch (IOException e) { return -1; } - osw = new OutputStreamWriter (fos); + osw = new BufferedWriter (new OutputStreamWriter (fos)); extio.setHandle (osw); return 1; } @@ -419,26 +498,35 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_FILE_READ) { - InputStreamReader isr; - isr = (InputStreamReader)extio.getHandle(); - try { isr.close (); } - catch (IOException e) { return -1; } + Reader isr; + isr = (Reader)extio.getHandle(); + if (isr != StdAwk.stdin) + { + try { isr.close (); } + catch (IOException e) { return -1; } + } return 0; } else if (mode == Extio.MODE_FILE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle(); - try { osw.close (); } - catch (IOException e) { return -1; } + Writer osw; + osw = (Writer)extio.getHandle(); + if (osw != StdAwk.stdout) + { + try { osw.close (); } + catch (IOException e) { return -1; } + } return 0; } else if (mode == Extio.MODE_FILE_APPEND) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle(); - try { osw.close (); } - catch (IOException e) { return -1; } + Writer osw; + osw = (Writer)extio.getHandle(); + if (osw != StdAwk.stdout) + { + try { osw.close (); } + catch (IOException e) { return -1; } + } return 0; } @@ -451,8 +539,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_FILE_READ) { - InputStreamReader isr; - isr = (InputStreamReader)extio.getHandle(); + Reader isr; + isr = (Reader)extio.getHandle(); try { @@ -473,8 +561,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_FILE_WRITE || mode == Extio.MODE_FILE_APPEND) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle(); + Writer osw; + osw = (Writer)extio.getHandle(); try { osw.write (buf, 0, len); } catch (IOException e) { len = -1; } return len; @@ -490,8 +578,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_FILE_WRITE || mode == Extio.MODE_FILE_APPEND) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle (); + Writer osw; + osw = (Writer)extio.getHandle (); try { osw.flush (); } catch (IOException e) { return -1; } return 0; @@ -509,24 +597,24 @@ public abstract class StdAwk extends Awk { Process proc; - InputStreamReader isr; + Reader isr; try { proc = popen (extio.getName()); } catch (IOException e) { return -1; } - isr = new InputStreamReader (proc.getInputStream()); + isr = new BufferedReader (new InputStreamReader (proc.getInputStream())); extio.setHandle (isr); return 1; } else if (mode == Extio.MODE_PIPE_WRITE) { Process proc; - OutputStreamWriter osw; + Writer osw; try { proc = popen (extio.getName()); } catch (IOException e) { return -1; } - osw = new OutputStreamWriter (proc.getOutputStream()); + osw = new BufferedWriter (new OutputStreamWriter (proc.getOutputStream())); extio.setHandle (osw); return 1; } @@ -540,18 +628,24 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_PIPE_READ) { - InputStreamReader isr; - isr = (InputStreamReader)extio.getHandle(); - try { isr.close (); } - catch (IOException e) { return -1; } + Reader isr; + isr = (Reader)extio.getHandle(); + if (isr != StdAwk.stdin) + { + try { isr.close (); } + catch (IOException e) { return -1; } + } return 0; } else if (mode == Extio.MODE_PIPE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle(); - try { osw.close (); } - catch (IOException e) { return -1; } + Writer osw; + osw = (Writer)extio.getHandle(); + if (osw != StdAwk.stdout) + { + try { osw.close (); } + catch (IOException e) { return -1; } + } return 0; } @@ -564,8 +658,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_PIPE_READ) { - InputStreamReader isr; - isr = (InputStreamReader)extio.getHandle(); + Reader isr; + isr = (Reader)extio.getHandle(); try { @@ -585,8 +679,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_PIPE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle(); + Writer osw; + osw = (Writer)extio.getHandle(); try { osw.write (buf, 0, len); } catch (IOException e) { len = -1; } return len; @@ -601,8 +695,8 @@ public abstract class StdAwk extends Awk if (mode == Extio.MODE_PIPE_WRITE) { - OutputStreamWriter osw; - osw = (OutputStreamWriter)extio.getHandle (); + Writer osw; + osw = (Writer)extio.getHandle (); try { osw.flush (); } catch (IOException e) { return -1; } return 0; diff --git a/ase/awk/jni.c b/ase/awk/jni.c index eb63b583..5bb3716f 100644 --- a/ase/awk/jni.c +++ b/ase/awk/jni.c @@ -1,5 +1,5 @@ /* - * $Id: jni.c,v 1.50 2007-01-21 13:21:14 bacon Exp $ + * $Id: jni.c,v 1.51 2007-01-23 14:23:18 bacon Exp $ */ #include @@ -11,7 +11,9 @@ #include #include #include -#include +#include +#include +//#include #include "../etc/printf.c" @@ -28,9 +30,10 @@ #error this module supports ASE_CHAR_IS_WCHAR only #endif -#define CLASS_EXCEPTION "ase/awk/Exception" -#define CLASS_EXTIO "ase/awk/Extio" -#define FIELD_HANDLE "handle" +#define CLASS_OUTOFMEMORYERROR "java/lang/OutOfMemoryError" +#define CLASS_EXCEPTION "ase/awk/Exception" +#define CLASS_EXTIO "ase/awk/Extio" +#define FIELD_HANDLE "handle" #define MSG_SIZE 256 @@ -89,32 +92,32 @@ struct run_data_t jmethodID double_value; }; -static void* __awk_malloc (ase_size_t n, void* custom_data) +static void* awk_malloc (ase_size_t n, void* custom_data) { return malloc (n); } -static void* __awk_realloc (void* ptr, ase_size_t n, void* custom_data) +static void* awk_realloc (void* ptr, ase_size_t n, void* custom_data) { return realloc (ptr, n); } -static void __awk_free (void* ptr, void* custom_data) +static void awk_free (void* ptr, void* custom_data) { free (ptr); } -static ase_real_t __awk_pow (ase_real_t x, ase_real_t y) +static ase_real_t awk_pow (ase_real_t x, ase_real_t y) { return pow (x, y); } -static void __awk_abort (void* custom_data) +static void awk_abort (void* custom_data) { abort (); } -static int __awk_sprintf ( +static int awk_sprintf ( ase_char_t* buf, ase_size_t len, const ase_char_t* fmt, ...) { int n; @@ -135,7 +138,7 @@ static int __awk_sprintf ( return n; } -static void __awk_aprintf (const ase_char_t* fmt, ...) +static void awk_aprintf (const ase_char_t* fmt, ...) { va_list ap; @@ -148,7 +151,7 @@ static void __awk_aprintf (const ase_char_t* fmt, ...) va_end (ap); } -static void __awk_dprintf (const ase_char_t* fmt, ...) +static void awk_dprintf (const ase_char_t* fmt, ...) { va_list ap; va_start (ap, fmt); @@ -162,19 +165,93 @@ static void __awk_dprintf (const ase_char_t* fmt, ...) va_end (ap); } +static void throw_exception ( + JNIEnv* env, const ase_char_t* msg, jint code, jint line) +{ + jclass except_class; + jmethodID except_cons; + jstring except_msg; + jthrowable except_obj; + + except_class = (*env)->FindClass (env, CLASS_EXCEPTION); + if (except_class == NULL) + { + /* the exception to be thrown by FindClass is not cleared. + * 1. this should not happend as the ase.awk.Exception + * class should always be there. + * 2. if it happens, this exception may abort the entire + * program as the exception is not likely to be handled + * explicitly by the java program. */ + return; + } + + except_cons = (*env)->GetMethodID ( + env, except_class, "", "(Ljava/lang/String;II)V"); + if (except_cons == NULL) + { + /* the potential exception to be thrown by the GetMethodID + * method is not cleared here for the same reason as the + * FindClass method above */ + (*env)->DeleteLocalRef (env, except_class); + return; + } + + if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) + { + ase_size_t i, len = ase_awk_strlen(msg); + jchar* tmp = (jchar*) malloc (ASE_SIZEOF(jchar)*len); + if (tmp == NULL) + { + (*env)->DeleteLocalRef (env, except_class); + + except_class = (*env)->FindClass (env, CLASS_OUTOFMEMORYERROR); + if (except_class == NULL) return; + + (*env)->ThrowNew (env, except_class, "out of memory"); + (*env)->DeleteLocalRef (env, except_class); + return; + } + + for (i = 0; i < len; i++) tmp[i] = (jchar)msg[i]; + except_msg = (*env)->NewString (env, tmp, len); + free (tmp); + } + else + { + except_msg = (*env)->NewString (env, msg, ase_awk_strlen(msg)); + } + + if (except_msg == NULL) + { + (*env)->DeleteLocalRef (env, except_class); + return; + } + + except_obj = (*env)->NewObject ( + env, except_class, except_cons, + except_msg, code, line); + + (*env)->DeleteLocalRef (env, except_msg); + (*env)->DeleteLocalRef (env, except_class); + + if (except_obj == NULL) return; + + (*env)->Throw (env, except_obj); + (*env)->DeleteLocalRef (env, except_obj); +} + JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj) { jclass class; - jfieldID fid_handle; - jthrowable except; + jfieldID handle; ase_awk_t* awk; ase_awk_sysfns_t sysfns; int opt, errnum; memset (&sysfns, 0, sizeof(sysfns)); - sysfns.malloc = __awk_malloc; - sysfns.realloc = __awk_realloc; - sysfns.free = __awk_free; + sysfns.malloc = awk_malloc; + sysfns.realloc = awk_realloc; + sysfns.free = awk_free; sysfns.is_upper = iswupper; sysfns.is_lower = iswlower; @@ -192,35 +269,37 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj) sysfns.memcpy = memcpy; sysfns.memset = memset; - sysfns.pow = __awk_pow; - sysfns.sprintf = __awk_sprintf; - sysfns.aprintf = __awk_aprintf; - sysfns.dprintf = __awk_dprintf; - sysfns.abort = __awk_abort; + sysfns.pow = awk_pow; + sysfns.sprintf = awk_sprintf; + sysfns.aprintf = awk_aprintf; + sysfns.dprintf = awk_dprintf; + sysfns.abort = awk_abort; awk = ase_awk_open (&sysfns, &errnum); if (awk == NULL) { - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - (*env)->ThrowNew (env, except, "cannot create awk"); - (*env)->DeleteLocalRef (env, except); + throw_exception ( + env, + ase_awk_geterrstr(errnum), + errnum, + 0); return; } class = (*env)->GetObjectClass(env, obj); - fid_handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); (*env)->DeleteLocalRef (env, class); - if (fid_handle == NULL) + if (handle == NULL) { - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - (*env)->ThrowNew (env, except, "cannot find the handle field"); - (*env)->DeleteLocalRef (env, except); + throw_exception ( + env, + ASE_T("no handle field found"), + ASE_AWK_EINTERN, + 0); return; } - (*env)->SetLongField (env, obj, fid_handle, (jlong)awk); + (*env)->SetLongField (env, obj, handle, (jlong)awk); opt = ASE_AWK_EXPLICIT | ASE_AWK_UNIQUEFN | ASE_AWK_SHADING | ASE_AWK_IMPLICIT | ASE_AWK_SHIFT | ASE_AWK_IDIV | @@ -231,69 +310,50 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj) JNIEXPORT void JNICALL Java_ase_awk_Awk_close (JNIEnv* env, jobject obj) { jclass class; - jfieldID fid_handle; + jfieldID handle; + ase_awk_t* awk; class = (*env)->GetObjectClass(env, obj); - fid_handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); (*env)->DeleteLocalRef (env, class); - if (fid_handle == NULL) - { - /* something wrong. should not happen */ - /* TODO: should it throw an exception??? */ + if (handle == NULL) + { + /* internal error. no handle field */ return; } - ase_awk_close ((ase_awk_t*)(*env)->GetLongField (env, obj, fid_handle)); - (*env)->SetLongField (env, obj, fid_handle, (jlong)0); -} - -static jint __java_get_max_depth (JNIEnv* env, jobject obj, const char* name) -{ - jclass class; - jmethodID mid; - jthrowable thrown; - jint ret; - - class = (*env)->GetObjectClass(env, obj); - mid = (*env)->GetMethodID (env, class, name, "()I"); - (*env)->DeleteLocalRef (env, class); - if (mid == NULL) return -1; - - ret = (*env)->CallIntMethod (env, obj, mid); - thrown = (*env)->ExceptionOccurred (env); - if (thrown) + awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); + if (awk != NULL) { - (*env)->ExceptionClear (env); - ret = -1; + /* the handle is not NULL. close it */ + ase_awk_close (awk); + (*env)->SetLongField (env, obj, handle, (jlong)0); } - - return ret; } JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj) { jclass class; - jfieldID fid_handle; - jthrowable except; - jint depth; + jfieldID handle; ase_awk_t* awk; ase_awk_srcios_t srcios; srcio_data_t srcio_data; class = (*env)->GetObjectClass (env, obj); - fid_handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); (*env)->DeleteLocalRef (env, class); - if (fid_handle == NULL) + if (handle == NULL) { - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - (*env)->ThrowNew (env, except, "cannot find the handle field"); - (*env)->DeleteLocalRef (env, except); + throw_exception ( + env, + ASE_T("no handle field found"), + ASE_AWK_EINTERN, + 0); return; } - awk = (ase_awk_t*) (*env)->GetLongField (env, obj, fid_handle); + awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); srcio_data.env = env; srcio_data.obj = obj; @@ -302,31 +362,14 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj) srcios.out = __write_source; srcios.custom_data = &srcio_data; - depth = __java_get_max_depth (env, obj, "getMaxParseDepth"); - if (depth < 0) depth = 0; - - ase_awk_setmaxdepth ( - awk, - ASE_AWK_DEPTH_BLOCK_PARSE | - ASE_AWK_DEPTH_EXPR_PARSE, - depth); - if (ase_awk_parse (awk, &srcios) == -1) { - char msg[MSG_SIZE]; - int n; + throw_exception ( + env, + ase_awk_geterrmsg(awk), + ase_awk_geterrnum(awk), + ase_awk_geterrlin(awk)); - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - - n = snprintf (msg, sizeof(msg), - "parse error at line %d: %S", - ase_awk_geterrlin(awk), - ase_awk_geterrmsg(awk)); - if (n < 0 || n >= sizeof(msg)) msg[sizeof(msg)-1] = '\0'; - - (*env)->ThrowNew (env, except, msg); - (*env)->DeleteLocalRef (env, except); return; } } @@ -334,27 +377,35 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj) JNIEXPORT void JNICALL Java_ase_awk_Awk_run (JNIEnv* env, jobject obj) { jclass class; - jfieldID fid_handle; - jthrowable except; + jfieldID handle; ase_awk_t* awk; ase_awk_runios_t runios; runio_data_t runio_data; run_data_t run_data; - class = (*env)->GetObjectClass (env, obj); - fid_handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); - (*env)->DeleteLocalRef (env, class); - if (fid_handle == 0) + static int depth_ids[] = { - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - (*env)->ThrowNew (env, except, "cannot find the handle field"); - (*env)->DeleteLocalRef (env, except); + ASE_AWK_DEPTH_BLOCK_PARSE, + ASE_AWK_DEPTH_EXPR_PARSE, + ASE_AWK_DEPTH_REX_BUILD, + ASE_AWK_DEPTH_REX_MATCH + }; + + class = (*env)->GetObjectClass (env, obj); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + (*env)->DeleteLocalRef (env, class); + if (handle == 0) + { + throw_exception ( + env, + ASE_T("no handle field found"), + ASE_AWK_EINTERN, + 0); return; } - awk = (ase_awk_t*) (*env)->GetLongField (env, obj, fid_handle); + awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); run_data.env = env; run_data.obj = obj; @@ -424,25 +475,14 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_run (JNIEnv* env, jobject obj) runios.console = __process_extio; runios.custom_data = &runio_data; - // TODO: - //depth = __java_get_max_depth (env, obj, "getMaxRunDepth"); - // setMaxRunDepth... - if (ase_awk_run (awk, ASE_NULL, &runios, ASE_NULL, ASE_NULL, &run_data) == -1) { - char msg[MSG_SIZE]; - int n; - - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; /* exception thrown */ - - n = snprintf (msg, sizeof(msg), "%S", - ase_awk_geterrstr(ase_awk_geterrnum(awk))); - if (n < 0 || n >= sizeof(msg)) msg[sizeof(msg)-1] = '\0'; - - (*env)->ThrowNew (env, except, msg); - (*env)->DeleteLocalRef (env, except); + throw_exception ( + env, + ase_awk_geterrmsg(awk), + ase_awk_geterrnum(awk), + ase_awk_geterrlin(awk)); (*env)->DeleteLocalRef (env, run_data.integer_class); (*env)->DeleteLocalRef (env, run_data.long_class); @@ -602,7 +642,6 @@ static ase_ssize_t __java_open_extio ( { jclass class; jmethodID mid; - jthrowable thrown; jclass extio_class; jmethodID extio_cons; jobject extio_object; @@ -635,10 +674,9 @@ static ase_ssize_t __java_open_extio ( if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { ase_size_t i, len = ase_awk_strlen(extio->name); - jchar* tmp = (jchar*)malloc (ASE_SIZEOF(jchar)*len); + jchar* tmp = (jchar*) malloc (ASE_SIZEOF(jchar)*len); if (tmp == NULL) { - // TODO: better error handling... (*env)->DeleteLocalRef (env, extio_class); return -1; } @@ -674,11 +712,9 @@ static ase_ssize_t __java_open_extio ( /* execute the method */ ret = (*env)->CallIntMethod (env, obj, mid, extio_object); - thrown = (*env)->ExceptionOccurred (env); - if (thrown) + if ((*env)->ExceptionOccurred(env)) { -/* TODO: remove the next line */ -(*env)->ExceptionDescribe (env); + /* clear the exception */ (*env)->ExceptionClear (env); ret = -1; } @@ -707,7 +743,6 @@ static ase_ssize_t __java_close_extio ( { jclass class; jmethodID mid; - jthrowable thrown; jint ret; class = (*env)->GetObjectClass(env, obj); @@ -719,10 +754,8 @@ static ase_ssize_t __java_close_extio ( } ret = (*env)->CallIntMethod (env, obj, mid, extio->handle); - thrown = (*env)->ExceptionOccurred (env); - if (thrown) + if ((*env)->ExceptionOccurred (env)) { -(*env)->ExceptionDescribe (env); (*env)->ExceptionClear (env); ret = -1; } @@ -990,6 +1023,7 @@ static int __handle_bfn ( jobjectArray args; jobject arg, ret; ase_awk_val_t* v; + ase_char_t msg_nomem[MSG_SIZE]; run_data = ase_awk_getruncustomdata (run); nargs = ase_awk_getnargs (run); @@ -997,18 +1031,19 @@ static int __handle_bfn ( env = run_data->env; obj = run_data->obj; + awk_sprintf ( + msg_nomem, ASE_COUNTOF(msg_nomem), + ASE_T("out of memory in handling %.*s"), + fnl, fnm); + if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { ase_size_t i; jchar* tmp = (jchar*)malloc (ASE_SIZEOF(jchar)*fnl); if (tmp == NULL) { - run->awk->sysfns.sprintf ( - run->errmsg, ASE_COUNTOF(run->errmsg), - ASE_T("out of memory in handling %.*s"), - fnl, fnm); ase_awk_setrunerror ( - run, ASE_AWK_ENOMEM, 0, run->errmsg); + run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1020,14 +1055,17 @@ static int __handle_bfn ( if (name == NULL) { - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + if ((*env)->ExceptionOccurred (env)) + (*env)->ExceptionClear (env); + + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } name_utf = (*env)->GetStringUTFChars (env, name, JNI_FALSE); if (name_utf == NULL) { (*env)->DeleteLocalRef (env, name); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1052,7 +1090,10 @@ static int __handle_bfn ( env, nargs, run_data->object_class, NULL); if (args == NULL) { - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + if ((*env)->ExceptionOccurred (env)) + (*env)->ExceptionClear (env); + + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1091,12 +1132,7 @@ static int __handle_bfn ( if (tmp == NULL) { (*env)->DeleteLocalRef (env, args); - run->awk->sysfns.sprintf ( - run->errmsg, ASE_COUNTOF(run->errmsg), - ASE_T("out of memory in handling %.*s"), - fnl, fnm); - ase_awk_setrunerror ( - run, ASE_AWK_ENOMEM, 0, run->errmsg); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1118,13 +1154,10 @@ static int __handle_bfn ( if (v->type != ASE_AWK_VAL_NIL && arg == NULL) { + if ((*env)->ExceptionOccurred (env)) + (*env)->ExceptionClear (env); (*env)->DeleteLocalRef (env, args); - run->awk->sysfns.sprintf ( - run->errmsg, ASE_COUNTOF(run->errmsg), - ASE_T("out of memory in handling %.*s"), - fnl, fnm); - ase_awk_setrunerror ( - run, ASE_AWK_ENOMEM, 0, run->errmsg); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1133,16 +1166,11 @@ static int __handle_bfn ( } ret = (*env)->CallObjectMethod (env, obj, method, (jlong)run, args); - thrown = (*env)->ExceptionOccurred (env); - if (thrown) + if ((*env)->ExceptionOccurred (env)) { -(*env)->ExceptionDescribe (env); (*env)->ExceptionClear (env); (*env)->DeleteLocalRef (env, args); ase_awk_setrunerrnum (run, ASE_AWK_EBFNIMPL); - - // TODO: - //ase_awk_setrunerror (run, ASE_AWK_EBFNIMPL, "EXCEPTION:...."); return -1; } @@ -1161,7 +1189,7 @@ static int __handle_bfn ( if (v == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1177,7 +1205,7 @@ static int __handle_bfn ( if (v == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1193,7 +1221,7 @@ static int __handle_bfn ( if (v == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1208,7 +1236,7 @@ static int __handle_bfn ( if (v == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1223,7 +1251,7 @@ static int __handle_bfn ( if (v == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1240,7 +1268,7 @@ static int __handle_bfn ( if (ptr == NULL) { (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1253,7 +1281,7 @@ static int __handle_bfn ( { (*env)->ReleaseStringChars (env, ret, ptr); (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1270,7 +1298,7 @@ static int __handle_bfn ( { (*env)->ReleaseStringChars (env, ret, ptr); (*env)->DeleteLocalRef (env, ret); - ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, msg_nomem); return -1; } @@ -1288,7 +1316,7 @@ static int __handle_bfn ( return 0; } -JNIEXPORT jint JNICALL Java_ase_awk_Awk_addbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( JNIEnv* env, jobject obj, jstring name, jint min_args, jint max_args) { jclass class; @@ -1302,12 +1330,26 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_addbfn ( class = (*env)->GetObjectClass(env, obj); handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); (*env)->DeleteLocalRef (env, class); - if (handle == NULL) return -1; + if (handle == NULL) + { + throw_exception ( + env, + ASE_T("no handle field found"), + ASE_AWK_EINTERN, + 0); + return; + } awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); - ptr = (*env)->GetStringChars (env, name, JNI_FALSE); len = (*env)->GetStringLength (env, name); + ptr = (*env)->GetStringChars (env, name, JNI_FALSE); + if (ptr == NULL) + { + if ((*env)->ExceptionOccurred (env)) (*env)->ExceptionClear (env); + throw_exception (env, ASE_T("out of memory"), ASE_AWK_ENOMEM, 0); + return; + } if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { @@ -1317,8 +1359,8 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_addbfn ( if (tmp == ASE_NULL) { (*env)->ReleaseStringChars (env, name, ptr); - ase_awk_seterrnum (awk, ASE_AWK_ENOMEM); - return -1; + throw_exception (env, ASE_T("out of memory"), ASE_AWK_ENOMEM, 0); + return; } for (i = 0; i < len; i++) tmp[i] = (ase_char_t)ptr[i]; @@ -1335,10 +1377,17 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_addbfn ( (*env)->ReleaseStringChars (env, name, ptr); - return n; + if (n == -1) + { + throw_exception ( + env, + ase_awk_geterrmsg(awk), + ase_awk_geterrnum(awk), + ase_awk_geterrlin(awk)); + } } -JNIEXPORT jint JNICALL Java_ase_awk_Awk_delbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_delbfn ( JNIEnv* env, jobject obj, jstring name) { jclass class; @@ -1352,12 +1401,26 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_delbfn ( class = (*env)->GetObjectClass(env, obj); handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); (*env)->DeleteLocalRef (env, class); - if (handle == NULL) return -1; /* should never happen */ + if (handle == NULL) + { + throw_exception ( + env, + ASE_T("no handle field found"), + ASE_AWK_EINTERN, + 0); + return; + } awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); len = (*env)->GetStringLength (env, name); ptr = (*env)->GetStringChars (env, name, JNI_FALSE); + if (ptr == NULL) + { + if ((*env)->ExceptionOccurred (env)) (*env)->ExceptionClear (env); + throw_exception (env, ASE_T("out of memory"), ASE_AWK_ENOMEM, 0); + return; + } if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { @@ -1367,8 +1430,8 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_delbfn ( if (tmp == ASE_NULL) { (*env)->ReleaseStringChars (env, name, ptr); - ase_awk_seterrnum (awk, ASE_AWK_ENOMEM); - return -1; + throw_exception (env, ASE_T("out of memory"), ASE_AWK_ENOMEM, 0); + return; } for (i = 0; i < len; i++) tmp[i] = (ase_char_t)ptr[i]; @@ -1382,7 +1445,46 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_delbfn ( (*env)->ReleaseStringChars (env, name, ptr); - return n; + if (n == -1) + { + throw_exception ( + env, + ase_awk_geterrmsg(awk), + ase_awk_geterrnum(awk), + ase_awk_geterrlin(awk)); + } +} + +JNIEXPORT jint JNICALL Java_ase_awk_Awk_getmaxdepth ( + JNIEnv* env, jobject obj, jint id) +{ + jclass class; + jfieldID handle; + ase_awk_t* awk; + + class = (*env)->GetObjectClass(env, obj); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + (*env)->DeleteLocalRef (env, class); + if (handle == NULL) return 0; /* should never happen */ + + awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); + return (jint)ase_awk_getmaxdepth (awk, id); +} + +JNIEXPORT void JNICALL Java_ase_awk_Awk_setmaxdepth ( + JNIEnv* env, jobject obj, jint ids, jint depth) +{ + jclass class; + jfieldID handle; + ase_awk_t* awk; + + class = (*env)->GetObjectClass(env, obj); + handle = (*env)->GetFieldID (env, class, FIELD_HANDLE, "J"); + (*env)->DeleteLocalRef (env, class); + if (handle == NULL) return; /* should never happen */ + + awk = (ase_awk_t*) (*env)->GetLongField (env, obj, handle); + ase_awk_setmaxdepth (awk, ids, depth); } JNIEXPORT jint JNICALL Java_ase_awk_Awk_setfilename ( @@ -1393,8 +1495,9 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_setfilename ( jsize len; jint n; - ptr = (*env)->GetStringChars (env, name, JNI_FALSE); len = (*env)->GetStringLength (env, name); + ptr = (*env)->GetStringChars (env, name, JNI_FALSE); + if (ptr == NULL) return -1; if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { @@ -1429,8 +1532,9 @@ JNIEXPORT jint JNICALL Java_ase_awk_Awk_setofilename ( jsize len; jint n; - ptr = (*env)->GetStringChars (env, name, JNI_FALSE); len = (*env)->GetStringLength (env, name); + ptr = (*env)->GetStringChars (env, name, JNI_FALSE); + if (ptr == NULL) return -1; if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { @@ -1468,8 +1572,10 @@ JNIEXPORT jobject JNICALL Java_ase_awk_Awk_strtonum ( jobject ret; run_data_t* run_data; - ptr = (*env)->GetStringChars (env, str, JNI_FALSE); len = (*env)->GetStringLength (env, str); + ptr = (*env)->GetStringChars (env, str, JNI_FALSE); + if (ptr == NULL) return NULL; + if (ASE_SIZEOF(jchar) != ASE_SIZEOF(ase_char_t)) { ase_size_t i; @@ -1506,16 +1612,6 @@ JNIEXPORT jobject JNICALL Java_ase_awk_Awk_strtonum ( run_data->double_init, (jdouble)rv); } - /* - { - jthrowable except; - except = (*env)->FindClass (env, CLASS_EXCEPTION); - if (except == NULL) return; - (*env)->ThrowNew (env, except, "cannot create awk"); - (*env)->DeleteLocalRef (env, except); - } - */ - return ret; } diff --git a/ase/awk/jni.h b/ase/awk/jni.h index 563f775a..256e9277 100644 --- a/ase/awk/jni.h +++ b/ase/awk/jni.h @@ -1,5 +1,5 @@ /* - * $Id: jni.h,v 1.14 2006-12-02 16:26:03 bacon Exp $ + * $Id: jni.h,v 1.15 2007-01-23 14:23:18 bacon Exp $ */ #ifndef _ASE_AWK_JNI_H_ @@ -16,11 +16,16 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_close (JNIEnv* env, jobject obj); JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj); JNIEXPORT void JNICALL Java_ase_awk_Awk_run (JNIEnv* env, jobject obj); -JNIEXPORT jint JNICALL Java_ase_awk_Awk_addbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( JNIEnv* env, jobject obj, jstring name, jint min_args, jint max_args); -JNIEXPORT jint JNICALL Java_ase_awk_Awk_delbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_delbfn ( JNIEnv* env, jobject obj, jstring name); +JNIEXPORT jint JNICALL Java_ase_awk_Awk_getmaxdepth ( + JNIEnv* env, jobject obj, jint id); +JNIEXPORT void JNICALL Java_ase_awk_Awk_setmaxdepth ( + JNIEnv* env, jobject obj, jint ids, jint depth); + JNIEXPORT jint JNICALL Java_ase_awk_Awk_setfilename ( JNIEnv* env, jobject obj, jlong runid, jstring name); JNIEXPORT jint JNICALL Java_ase_awk_Awk_setofilename ( diff --git a/ase/awk/run.c b/ase/awk/run.c index 85c67490..8d6290e1 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.320 2007-01-10 14:33:00 bacon Exp $ + * $Id: run.c,v 1.321 2007-01-23 14:23:18 bacon Exp $ */ #include @@ -5238,11 +5238,30 @@ static ase_awk_val_t* __eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde) call->what.afn.name.ptr, call->what.afn.name.len); if (pair == ASE_NULL) { - run->awk->sysfns.sprintf ( - run->errmsg, ASE_COUNTOF(run->errmsg), - ASE_T("function '%.*s' not found"), - call->what.afn.name.len, - call->what.afn.name.ptr); + ase_char_t* fmt = ASE_T("function '%.*s' not found"); + ase_char_t* fmt2 = ASE_T("function '%.*s..' not found"); + ase_size_t len = ase_awk_strlen(fmt); + ase_size_t len2 = ase_awk_strlen(fmt2); + + if (len2 < ASE_COUNTOF(run->errmsg) && + call->what.afn.name.len > ASE_COUNTOF(run->errmsg)-len2) + { + run->awk->sysfns.sprintf ( + run->errmsg, + ASE_COUNTOF(run->errmsg), + fmt2, + ASE_COUNTOF(run->errmsg)-len2, + call->what.afn.name.ptr); + } + else + { + run->awk->sysfns.sprintf ( + run->errmsg, + ASE_COUNTOF(run->errmsg), + fmt, + call->what.afn.name.len, + call->what.afn.name.ptr); + } ase_awk_setrunerror ( run, ASE_AWK_EFNNONE, nde->line, run->errmsg); diff --git a/ase/test/awk/Awk.java b/ase/test/awk/Awk.java index b9ed4ece..e6f1d249 100644 --- a/ase/test/awk/Awk.java +++ b/ase/test/awk/Awk.java @@ -1,5 +1,5 @@ /* - * $Id: Awk.java,v 1.19 2007-01-21 13:21:14 bacon Exp $ + * $Id: Awk.java,v 1.20 2007-01-23 14:23:18 bacon Exp $ */ package ase.test.awk; @@ -13,6 +13,8 @@ public class Awk extends ase.awk.StdAwk addBuiltinFunction ("sin", 1, 1); addBuiltinFunction ("cos", 1, 1); addBuiltinFunction ("tan", 1, 1); + addBuiltinFunction ("srand", 0, 1); + addBuiltinFunction ("rand", 0, 0); addBuiltinFunction ("system", 1, 1); @@ -41,7 +43,7 @@ public class Awk extends ase.awk.StdAwk //return new Short ((short)1001); } - protected String[] getInputConsoleNames () + protected String[] consoleInputNames () { String[] cin = new String[3]; cin[0] = "c1.txt"; @@ -50,7 +52,7 @@ public class Awk extends ase.awk.StdAwk return cin; } - protected String[] getOutputConsoleNames () + protected String[] consoleOutputNames () { String[] cout = new String[1]; cout[0] = ""; @@ -64,28 +66,19 @@ public class Awk extends ase.awk.StdAwk */ } - protected String[] getSourceNames () + protected String[] sourceInputNames () { - String[] cout = new String[1]; - cout[0] = "t.awk"; - return cout; + String[] sin = new String[1]; + sin[0] = "t.awk"; + return sin; } /* - protected String getDeparsedSourceName () + protected String sourceOutputName () { return ""; } */ - protected int getMaxParseDepth () - { - return 50; - } - - protected int getMaxRunDepth () - { - return 50; - } public static void main (String[] args) { @@ -94,17 +87,33 @@ public class Awk extends ase.awk.StdAwk try { awk = new Awk (); + awk.setMaxDepth (Awk.DEPTH_BLOCK_PARSE, 30); + awk.parse (); awk.run (); } catch (ase.awk.Exception e) { - System.out.println ("ase.awk.Exception - " + e.getMessage()); + if (e.getLine() == 0) + { + System.out.println ("ase.awk.Exception - " + e.getMessage()); + } + else + { + System.out.println ( + "ase.awk.Exception at line " + + e.getLine() + " - " + e.getMessage()); + } } finally { - if (awk != null) awk.close (); + if (awk != null) + { + awk.close (); + awk = null; + } } + System.out.println ("==== end of awk ===="); } } diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 010409d5..289d68b7 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.151 2006-12-26 10:25:19 bacon Exp $ + * $Id: awk.c,v 1.152 2007-01-23 14:23:18 bacon Exp $ */ #include @@ -790,15 +790,14 @@ static int __main (int argc, ase_char_t* argv[]) opt = ASE_AWK_IMPLICIT | ASE_AWK_EXPLICIT | - ASE_AWK_UNIQUEAFN | - ASE_AWK_HASHSIGN | + ASE_AWK_UNIQUEFN | ASE_AWK_IDIV | ASE_AWK_SHADING | ASE_AWK_SHIFT | ASE_AWK_EXTIO | /*ASE_AWK_COPROC |*/ ASE_AWK_BLOCKLESS | - ASE_AWK_STRINDEXONE | + ASE_AWK_STRIDXONE | ASE_AWK_STRIPSPACES | ASE_AWK_NEXTOFILE; @@ -884,17 +883,17 @@ static int __main (int argc, ase_char_t* argv[]) return -1; } - ase_awk_setopt (awk, opt); + ase_awk_setoption (awk, opt); srcios.in = process_source; srcios.out = dump_source; srcios.custom_data = &src_io; - ase_awk_setmaxparsedepth ( - awk, ASE_AWK_DEPTH_BLOCK | ASE_AWK_DEPTH_EXPR, 20); - ase_awk_setmaxrundepth ( - awk, ASE_AWK_DEPTH_BLOCK | ASE_AWK_DEPTH_EXPR, 50); + ase_awk_setmaxdepth ( + awk, ASE_AWK_DEPTH_BLOCK_PARSE | ASE_AWK_DEPTH_EXPR_PARSE, 20); + ase_awk_setmaxdepth ( + awk, ASE_AWK_DEPTH_BLOCK_RUN | ASE_AWK_DEPTH_EXPR_RUN, 50); if (ase_awk_parse (awk, &srcios) == -1) { diff --git a/ase/test/awk/t4.awk b/ase/test/awk/t4.awk index 12b4b6fb..707c75f7 100644 --- a/ase/test/awk/t4.awk +++ b/ase/test/awk/t4.awk @@ -1,4 +1,4 @@ -function main () +function main (arg1, arg2, arg3) { local i, k, c; @@ -14,5 +14,8 @@ function main () if (i in abc) j[i] = i; } + print arg1; + print arg2; + print arg3; print "end of program"; }