/* * $Id: Awk.java,v 1.13 2007/08/26 14:33:38 bacon Exp $ * * {License} */ package ase.awk; import java.io.*; public abstract class Awk { // mode for open_source & close_source 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); // options public static final int OPTION_IMPLICIT = (1 << 0); public static final int OPTION_EXPLICIT = (1 << 1); public static final int OPTION_UNIQUEFN = (1 << 2); public static final int OPTION_SHADING = (1 << 3); public static final int OPTION_SHIFT = (1 << 4); public static final int OPTION_IDIV = (1 << 5); public static final int OPTION_STRCONCAT = (1 << 6); public static final int OPTION_EXTIO = (1 << 7); public static final int OPTION_COPROC = (1 << 8); public static final int OPTION_BLOCKLESS = (1 << 9); public static final int OPTION_ASEONE = (1 << 10); public static final int OPTION_STRIPSPACES = (1 << 11); public static final int OPTION_NEXTOFILE = (1 << 12); public static final int OPTION_CRLF = (1 << 13); public static final int OPTION_ARGSTOMAIN = (1 << 14); protected final static Reader stdin = new BufferedReader (new InputStreamReader (System.in)); protected final static Writer stdout = new BufferedWriter (new OutputStreamWriter (System.out)); private long handle; public Awk () throws Exception { this.handle = 0; open (); } /* == just in case == */ protected void finalize () throws Throwable { if (handle != 0) close (); super.finalize (); } /* == native methods == */ private native void open () throws Exception; public native void close (); public native void parse () throws Exception; public native void run (String main, String[] args) throws Exception; private native int getmaxdepth (int id); private native void setmaxdepth (int id, int depth); private native int getoption (); private native void setoption (int opt); private native boolean getdebug (); private native void setdebug (boolean debug); private native void setword (String ow, String nw); private native void addbfn ( String name, int min_args, int max_args) throws Exception; private native void delbfn (String name) throws Exception; native void setfilename ( long runid, String name) throws Exception; native void setofilename ( long runid, String name) throws Exception; private native Object strtonum ( long runid, String str) throws Exception; private native String valtostr ( long runid, Object obj) throws Exception; protected native String strftime (String fmt, long sec); protected native String strfgmtime (String fmt, long sec); protected native int system (String cmd); /* == simpler run methods == */ public void run (String main) throws Exception { run (main, null); } public void run (String[] args) throws Exception { run (null, args); } public void run () throws Exception { run (null, null); } /* == builtin functions == */ public void addFunction ( String name, int min_args, int max_args) throws Exception { addbfn (name, min_args, max_args); } public void deleteFunction (String name) throws Exception { delbfn (name); } protected long builtinFunctionArgumentToLong ( long runid, Object obj) throws Exception { long n; if (obj == null) n = 0; else { if (obj instanceof String) obj = strtonum (runid, (String)obj); if (obj instanceof Long) { n = ((Long)obj).longValue (); } else if (obj instanceof Double) { n = ((Double)obj).longValue (); } else if (obj instanceof Integer) { n = ((Integer)obj).longValue (); } else if (obj instanceof Short) { n = ((Short)obj).longValue (); } else if (obj instanceof Float) { n = ((Float)obj).longValue (); } else n = 0; } return n; } protected double builtinFunctionArgumentToDouble ( long runid, Object obj) throws Exception { double n; if (obj == null) n = 0.0; else { if (obj instanceof String) obj = strtonum (runid, (String)obj); if (obj instanceof Long) { n = ((Long)obj).doubleValue (); } else if (obj instanceof Double) { n = ((Double)obj).doubleValue (); } else if (obj instanceof Integer) { n = ((Integer)obj).doubleValue (); } else if (obj instanceof Short) { n = ((Short)obj).doubleValue (); } else if (obj instanceof Float) { n = ((Float)obj).doubleValue (); } else n = 0.0; } return n; } protected String builtinFunctionArgumentToString ( long runid, Object obj) throws Exception { String str; if (obj == null) str = ""; else if (obj instanceof String) str = (String)obj; else str = valtostr (runid, obj); return str; } /* == console name setters == */ protected void setConsoleInputName ( Extio extio, String name) throws Exception { /* 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. */ setfilename (extio.getRunId(), name); } protected void setConsoleOutputName ( Extio extio, String name) throws Exception { setofilename (extio.getRunId(), name); } /* == depth limiting == */ public int getMaxDepth (int id) { return getmaxdepth (id); } public void setMaxDepth (int ids, int depth) { setmaxdepth (ids, depth); } /* == option == */ public int getOption () { return getoption (); } public void setOption (int opt) { setoption (opt); } /* == debug == */ public boolean getDebug () { return getdebug (); } public void setDebug (boolean debug) { setdebug (debug); } public void setWord (String ow, String nw) { setword (ow, nw); } public void unsetWord (String ow) { setword (ow, null); } public void unsetAllWords () { setword (null, null); } /* == source code management == */ protected abstract int openSource (int mode); protected abstract int closeSource (int mode); protected abstract int readSource (char[] buf, int len); protected abstract int writeSource (char[] buf, int len); /* == external io interface == */ protected int openExtio (Extio extio) { switch (extio.getType()) { case Extio.TYPE_CONSOLE: { Console con = new Console (this, extio); int n = openConsole (con); extio.setHandle (con); return n; } case Extio.TYPE_FILE: { File file = new File (this, extio); int n = openFile (file); extio.setHandle (file); return n; } case Extio.TYPE_PIPE: { Pipe pipe = new Pipe (this, extio); int n = openPipe (pipe); extio.setHandle (pipe); return n; } } return -1; } protected int closeExtio (Extio extio) { switch (extio.getType()) { case Extio.TYPE_CONSOLE: return closeConsole ( (Console)extio.getHandle()); case Extio.TYPE_FILE: return closeFile ((File)extio.getHandle()); case Extio.TYPE_PIPE: return closePipe ((Pipe)extio.getHandle()); } return -1; } protected int readExtio (Extio extio, char[] buf, int len) { // this check is needed because 0 is used to indicate // the end of the stream. java streams can return 0 // if the data given is 0 bytes and it didn't reach // the end of the stream. if (len <= 0) return -1; switch (extio.getType()) { case Extio.TYPE_CONSOLE: { return readConsole ( (Console)extio.getHandle(), buf, len); } case Extio.TYPE_FILE: { return readFile ( (File)extio.getHandle(), buf, len); } case Extio.TYPE_PIPE: { return readPipe ( (Pipe)extio.getHandle(), buf, len); } } return -1; } protected int writeExtio (Extio extio, char[] buf, int len) { if (len <= 0) return -1; switch (extio.getType()) { case Extio.TYPE_CONSOLE: { return writeConsole ( (Console)extio.getHandle(), buf, len); } case Extio.TYPE_FILE: { return writeFile ( (File)extio.getHandle(), buf, len); } case Extio.TYPE_PIPE: { return writePipe ( (Pipe)extio.getHandle(), buf, len); } } return -1; } protected int flushExtio (Extio extio) { switch (extio.getType()) { case Extio.TYPE_CONSOLE: { return flushConsole ((Console)extio.getHandle()); } case Extio.TYPE_FILE: { return flushFile ((File)extio.getHandle()); } case Extio.TYPE_PIPE: { return flushPipe ((Pipe)extio.getHandle()); } } return -1; } protected int nextExtio (Extio extio) { int type = extio.getType (); switch (extio.getType()) { case Extio.TYPE_CONSOLE: { return nextConsole ((Console)extio.getHandle()); } } return -1; } protected abstract int openConsole (Console con); protected abstract int closeConsole (Console con); protected abstract int readConsole (Console con, char[] buf, int len); protected abstract int writeConsole (Console con, char[] buf, int len); protected abstract int flushConsole (Console con); protected abstract int nextConsole (Console con); protected abstract int openFile (File file); protected abstract int closeFile (File file); protected abstract int readFile (File file, char[] buf, int len); protected abstract int writeFile (File file, char[] buf, int len); protected abstract int flushFile (File file); protected abstract int openPipe (Pipe pipe); protected abstract int closePipe (Pipe pipe); protected abstract int readPipe (Pipe pipe, char[] buf, int len); protected abstract int writePipe (Pipe pipe, char[] buf, int len); protected abstract int flushPipe (Pipe pipe); }