Recovered from cvs revision 2007-04-30 05:47:00
This commit is contained in:
345
ase/awk/Awk.java
345
ase/awk/Awk.java
@ -1,345 +0,0 @@
|
||||
/*
|
||||
* $Id: Awk.java,v 1.1.1.1 2007/03/28 14:05:12 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
package ase.awk;
|
||||
|
||||
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_STRBASEONE = (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);
|
||||
|
||||
private long handle;
|
||||
|
||||
public Awk () throws Exception
|
||||
{
|
||||
this.handle = 0;
|
||||
|
||||
open ();
|
||||
}
|
||||
|
||||
/* == just in case == */
|
||||
protected void finalize () throws Throwable
|
||||
{
|
||||
super.finalize ();
|
||||
if (handle != 0) close ();
|
||||
}
|
||||
|
||||
/* == 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 addbfn (
|
||||
String name, int min_args, int max_args) throws Exception;
|
||||
private native void delbfn (String name) throws Exception;
|
||||
|
||||
private native void setfilename (
|
||||
long runid, String name) throws Exception;
|
||||
private 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;
|
||||
|
||||
/* == 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 addBuiltinFunction (
|
||||
String name, int min_args, int max_args) throws Exception
|
||||
{
|
||||
addbfn (name, min_args, max_args);
|
||||
}
|
||||
|
||||
public void deleteBuiltinFunction (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);
|
||||
}
|
||||
|
||||
/* == 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)
|
||||
{
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE) return openConsole (extio);
|
||||
if (type == Extio.TYPE_FILE) return openFile (extio);
|
||||
if (type == Extio.TYPE_PIPE) return openPipe (extio);
|
||||
//if (type == Extio.TYPE_COPROC) return openCoproc (extio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int closeExtio (Extio extio)
|
||||
{
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE) return closeConsole (extio);
|
||||
if (type == Extio.TYPE_FILE) return closeFile (extio);
|
||||
if (type == Extio.TYPE_PIPE) return closePipe (extio);
|
||||
//if (type == Extio.TYPE_COPROC) return closeCoproc (extio);
|
||||
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;
|
||||
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE)
|
||||
return readConsole (extio, buf, len);
|
||||
if (type == Extio.TYPE_FILE)
|
||||
return readFile (extio, buf, len);
|
||||
if (type == Extio.TYPE_PIPE)
|
||||
return readPipe (extio, buf, len);
|
||||
//if (type == Extio.TYPE_COPROC)
|
||||
// return readCoproc (extio, buf, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int writeExtio (Extio extio, char[] buf, int len)
|
||||
{
|
||||
if (len <= 0) return -1;
|
||||
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE)
|
||||
return writeConsole (extio, buf, len);
|
||||
if (type == Extio.TYPE_FILE)
|
||||
return writeFile (extio, buf, len);
|
||||
if (type == Extio.TYPE_PIPE)
|
||||
return writePipe (extio, buf, len);
|
||||
//if (type == Extio.TYPE_COPROC)
|
||||
// return writeCoproc (extio, buf, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int flushExtio (Extio extio)
|
||||
{
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE) return flushConsole (extio);
|
||||
if (type == Extio.TYPE_FILE) return flushFile (extio);
|
||||
if (type == Extio.TYPE_PIPE) return flushPipe (extio);
|
||||
//if (type == Extio.TYPE_COPROC) return flushCoproc (extio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int nextExtio (Extio extio)
|
||||
{
|
||||
int type = extio.getType ();
|
||||
if (type == Extio.TYPE_CONSOLE) return nextConsole (extio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected abstract int openConsole (Extio extio);
|
||||
protected abstract int closeConsole (Extio extio);
|
||||
protected abstract int readConsole (Extio extio, char[] buf, int len);
|
||||
protected abstract int writeConsole (Extio extio, char[] buf, int len);
|
||||
protected abstract int flushConsole (Extio extio);
|
||||
protected abstract int nextConsole (Extio extio);
|
||||
|
||||
protected abstract int openFile (Extio extio);
|
||||
protected abstract int closeFile (Extio extio);
|
||||
protected abstract int readFile (Extio extio, char[] buf, int len);
|
||||
protected abstract int writeFile (Extio extio, char[] buf, int len);
|
||||
protected abstract int flushFile (Extio extio);
|
||||
|
||||
protected abstract int openPipe (Extio extio);
|
||||
protected abstract int closePipe (Extio extio);
|
||||
protected abstract int readPipe (Extio extio, char[] buf, int len);
|
||||
protected abstract int writePipe (Extio extio, char[] buf, int len);
|
||||
protected abstract int flushPipe (Extio extio);
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* $Id: Exception.java,v 1.1.1.1 2007/03/28 14:05:12 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
package ase.awk;
|
||||
|
||||
public class Exception extends java.lang.Exception
|
||||
{
|
||||
private int code;
|
||||
private int line;
|
||||
|
||||
public Exception ()
|
||||
{
|
||||
super ();
|
||||
this.code = 0;
|
||||
this.line = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* $Id: Extio.java,v 1.1.1.1 2007/03/28 14:05:13 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
package ase.awk;
|
||||
|
||||
public class Extio
|
||||
{
|
||||
public static final int TYPE_PIPE = 0;
|
||||
public static final int TYPE_COPROC = 1;
|
||||
public static final int TYPE_FILE = 2;
|
||||
public static final int TYPE_CONSOLE = 3;
|
||||
|
||||
public static final int MODE_PIPE_READ = 0;
|
||||
public static final int MODE_PIPE_WRITE = 1;
|
||||
|
||||
public static final int MODE_FILE_READ = 0;
|
||||
public static final int MODE_FILE_WRITE = 1;
|
||||
public static final int MODE_FILE_APPEND = 2;
|
||||
|
||||
public static final int MODE_CONSOLE_READ = 0;
|
||||
public static final int MODE_CONSOLE_WRITE = 1;
|
||||
|
||||
private String name;
|
||||
private int type;
|
||||
private int mode;
|
||||
private long run_id;
|
||||
private Object handle;
|
||||
|
||||
protected Extio (String name, int type, int mode, long run_id)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.mode = mode;
|
||||
this.run_id = run_id;
|
||||
this.handle = null;
|
||||
}
|
||||
|
||||
public String getName ()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getType ()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getMode ()
|
||||
{
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public long getRunId ()
|
||||
{
|
||||
return this.run_id;
|
||||
}
|
||||
|
||||
public void setHandle (Object handle)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public Object getHandle ()
|
||||
{
|
||||
return this.handle;
|
||||
}
|
||||
|
||||
protected void finalize () throws Throwable
|
||||
{
|
||||
super.finalize ();
|
||||
}
|
||||
};
|
@ -1,846 +0,0 @@
|
||||
/*
|
||||
* $Id: StdAwk.java,v 1.1.1.1 2007/03/28 14:05:13 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
package ase.awk;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public abstract class StdAwk extends Awk
|
||||
{
|
||||
private Reader src_in = null;
|
||||
private Writer src_out = null;
|
||||
|
||||
private String[] sin = null;
|
||||
private int sin_no = 0;
|
||||
|
||||
private String[] sout = null;
|
||||
private int sout_no = 0;
|
||||
|
||||
private String[] cin = null;
|
||||
private int cin_no = 0;
|
||||
private String[] cout = null;
|
||||
private int cout_no = 0;
|
||||
|
||||
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 ();
|
||||
|
||||
seed = System.currentTimeMillis();
|
||||
random = new java.util.Random (seed);
|
||||
}
|
||||
|
||||
/* == major methods == */
|
||||
public void parse () throws Exception
|
||||
{
|
||||
sin = sourceInputNames (); sin_no = 0;
|
||||
sout = sourceOutputNames (); sout_no = 0;
|
||||
super.parse ();
|
||||
}
|
||||
|
||||
public void run (String main, String[] args) throws Exception
|
||||
{
|
||||
cin = consoleInputNames (); cin_no = 0;
|
||||
cout = consoleOutputNames (); cout_no = 0;
|
||||
super.run (main, args);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* == source code names == */
|
||||
protected abstract String[] sourceInputNames ();
|
||||
protected String[] sourceOutputNames () { return null; }
|
||||
|
||||
/* == console names == */
|
||||
protected abstract String[] consoleInputNames ();
|
||||
protected abstract String[] consoleOutputNames ();
|
||||
|
||||
/* == source code == */
|
||||
protected int openSource (int mode)
|
||||
{
|
||||
if (mode == SOURCE_READ)
|
||||
{
|
||||
Reader isr;
|
||||
sin_no = 0;
|
||||
|
||||
if (sin == null || sin_no >= sin.length) return 0;
|
||||
|
||||
isr = get_stream_reader (sin[sin_no]);
|
||||
if (isr == null) return -1;
|
||||
|
||||
src_in = isr;
|
||||
sin_no++;
|
||||
return 1;
|
||||
}
|
||||
else if (mode == SOURCE_WRITE)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int closeSource (int mode)
|
||||
{
|
||||
if (mode == SOURCE_READ)
|
||||
{
|
||||
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;
|
||||
|
||||
if (src_out != StdAwk.stdout)
|
||||
{
|
||||
try { src_out.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int readSource (char[] buf, int len)
|
||||
{
|
||||
try {
|
||||
int n = src_in.read (buf, 0, len);
|
||||
while (n == -1)
|
||||
{
|
||||
Reader isr;
|
||||
if (sin == null || sin_no >= sin.length) return 0;
|
||||
|
||||
isr = get_stream_reader (sin[sin_no]);
|
||||
if (isr == null) return -1;
|
||||
|
||||
if (src_in != StdAwk.stdin)
|
||||
{
|
||||
try { src_in.close (); }
|
||||
catch (IOException ec) { /* ignore */ }
|
||||
}
|
||||
|
||||
src_in = isr;
|
||||
sin_no++;
|
||||
|
||||
n = src_in.read (buf, 0, len);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* == console interface == */
|
||||
protected int openConsole (Extio extio)
|
||||
{
|
||||
//System.err.println ("[openConsole called.... name: " + extio.getName() + " mode: " + extio.getMode());
|
||||
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_READ)
|
||||
{
|
||||
/*InputStream*/Reader isr;
|
||||
cin_no = 0;
|
||||
|
||||
if (cin == null || cin_no >= cin.length) return 0;
|
||||
isr = get_stream_reader (cin[cin_no]);
|
||||
if (isr == null) return -1;
|
||||
|
||||
extio.setHandle (isr);
|
||||
|
||||
try { setConsoleInputName (extio, cin[cin_no]); }
|
||||
catch (Exception e) { return -1; }
|
||||
|
||||
cin_no++;
|
||||
return 1;
|
||||
}
|
||||
else if (mode == Extio.MODE_CONSOLE_WRITE)
|
||||
{
|
||||
Writer osw;
|
||||
cout_no = 0;
|
||||
|
||||
if (cout == null || cout_no >= cout.length) return 0;
|
||||
|
||||
osw = get_stream_writer (cout[cout_no]);
|
||||
if (osw == null) return -1;
|
||||
|
||||
extio.setHandle (osw);
|
||||
try { setConsoleOutputName (extio, cout[cout_no]); }
|
||||
catch (Exception e) { return -1; }
|
||||
|
||||
cout_no++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int closeConsole (Extio extio)
|
||||
{
|
||||
//System.err.println ("[closeConsole called.... name: " + extio.getName() + " mode: " + extio.getMode());
|
||||
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_READ)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Writer osw = (Writer)extio.getHandle ();
|
||||
/* TODO: selective close the stream...
|
||||
* system.out should not be closed??? */
|
||||
|
||||
if (osw != StdAwk.stdout)
|
||||
{
|
||||
try { osw.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int readConsole (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_READ)
|
||||
{
|
||||
Reader isr, tmp;
|
||||
int n;
|
||||
|
||||
isr = (Reader)extio.getHandle ();
|
||||
|
||||
try { n = isr.read (buf, 0, len); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
while (n == -1)
|
||||
{
|
||||
if (cin == null || cin_no >= cin.length) return 0;
|
||||
tmp = get_stream_reader (cin[cin_no]);
|
||||
if (tmp == null) return -1;
|
||||
|
||||
if (isr != StdAwk.stdin)
|
||||
{
|
||||
try { isr.close (); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
|
||||
extio.setHandle (tmp);
|
||||
try { setConsoleInputName (extio, cin[cin_no]); }
|
||||
catch (Exception e) { return -1; }
|
||||
|
||||
isr = (Reader)extio.getHandle ();
|
||||
cin_no++;
|
||||
|
||||
try { n = isr.read (buf, 0, len); }
|
||||
catch (IOException e) { return -1; }
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int writeConsole (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
//System.err.println ("[writeConsole called name: " + extio.getName() + " mode: " + extio.getMode());
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_WRITE)
|
||||
{
|
||||
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; }
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int flushConsole (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_WRITE)
|
||||
{
|
||||
Writer osw;
|
||||
|
||||
osw = (Writer)extio.getHandle ();
|
||||
|
||||
try { osw.flush (); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int nextConsole (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_CONSOLE_READ)
|
||||
{
|
||||
Reader isr, tmp;
|
||||
|
||||
isr = (Reader)extio.getHandle ();
|
||||
|
||||
if (cin == null || cin_no >= cin.length) return 0;
|
||||
tmp = get_stream_reader (cin[cin_no]);
|
||||
if (tmp == null) return -1;
|
||||
|
||||
if (isr != StdAwk.stdin)
|
||||
{
|
||||
try { isr.close (); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
|
||||
extio.setHandle (tmp);
|
||||
try { setConsoleInputName (extio, cin[cin_no]); }
|
||||
catch (Exception e) { return -1; }
|
||||
|
||||
cin_no++;
|
||||
return 1;
|
||||
}
|
||||
else if (mode == Extio.MODE_CONSOLE_WRITE)
|
||||
{
|
||||
Writer osw, tmp;
|
||||
|
||||
osw = (Writer)extio.getHandle ();
|
||||
|
||||
if (cout == null || cout_no >= cout.length) return 0;
|
||||
tmp = get_stream_writer (cout[cout_no]);
|
||||
if (tmp == null) return -1;
|
||||
|
||||
if (osw != StdAwk.stdout)
|
||||
{
|
||||
try { osw.close (); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
|
||||
extio.setHandle (tmp);
|
||||
try { setConsoleOutputName (extio, cout[cout_no]); }
|
||||
catch (Exception e) { return -1;}
|
||||
|
||||
cout_no++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private Reader get_stream_reader (String name)
|
||||
{
|
||||
Reader isr;
|
||||
|
||||
if (name == null || name.length() == 0)
|
||||
{
|
||||
//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 BufferedReader(new InputStreamReader (fis));
|
||||
}
|
||||
|
||||
return isr;
|
||||
}
|
||||
|
||||
private Writer get_stream_writer (String name)
|
||||
{
|
||||
Writer osw;
|
||||
|
||||
if (name == null || name.length() == 0)
|
||||
{
|
||||
|
||||
//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 BufferedWriter (new OutputStreamWriter (fos));
|
||||
}
|
||||
|
||||
return osw;
|
||||
}
|
||||
|
||||
/* == file interface == */
|
||||
protected int openFile (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_FILE_READ)
|
||||
{
|
||||
FileInputStream fis;
|
||||
Reader isr;
|
||||
|
||||
try { fis = new FileInputStream (extio.getName()); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
isr = new BufferedReader (new InputStreamReader (fis));
|
||||
extio.setHandle (isr);
|
||||
return 1;
|
||||
}
|
||||
else if (mode == Extio.MODE_FILE_WRITE)
|
||||
{
|
||||
FileOutputStream fos;
|
||||
Writer osw;
|
||||
|
||||
try { fos = new FileOutputStream (extio.getName()); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
osw = new BufferedWriter (new OutputStreamWriter (fos));
|
||||
extio.setHandle (osw);
|
||||
return 1;
|
||||
}
|
||||
else if (mode == Extio.MODE_FILE_APPEND)
|
||||
{
|
||||
FileOutputStream fos;
|
||||
Writer osw;
|
||||
|
||||
try { fos = new FileOutputStream (extio.getName(), true); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
osw = new BufferedWriter (new OutputStreamWriter (fos));
|
||||
extio.setHandle (osw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int closeFile (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_FILE_READ)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle();
|
||||
if (osw != StdAwk.stdout)
|
||||
{
|
||||
try { osw.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int readFile (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_FILE_READ)
|
||||
{
|
||||
Reader isr;
|
||||
isr = (Reader)extio.getHandle();
|
||||
|
||||
try
|
||||
{
|
||||
len = isr.read (buf, 0, len);
|
||||
if (len == -1) len = 0;
|
||||
}
|
||||
catch (IOException e) { len = -1; }
|
||||
return len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int writeFile (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_FILE_WRITE ||
|
||||
mode == Extio.MODE_FILE_APPEND)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle();
|
||||
try { osw.write (buf, 0, len); }
|
||||
catch (IOException e) { len = -1; }
|
||||
return len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int flushFile (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_FILE_WRITE ||
|
||||
mode == Extio.MODE_FILE_APPEND)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle ();
|
||||
try { osw.flush (); }
|
||||
catch (IOException e) { return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* == pipe interface == */
|
||||
protected int openPipe (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_PIPE_READ)
|
||||
{
|
||||
|
||||
Process proc;
|
||||
Reader isr;
|
||||
|
||||
try { proc = popen (extio.getName()); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
isr = new BufferedReader (new InputStreamReader (proc.getInputStream()));
|
||||
extio.setHandle (isr);
|
||||
return 1;
|
||||
}
|
||||
else if (mode == Extio.MODE_PIPE_WRITE)
|
||||
{
|
||||
Process proc;
|
||||
Writer osw;
|
||||
|
||||
try { proc = popen (extio.getName()); }
|
||||
catch (IOException e) { return -1; }
|
||||
|
||||
osw = new BufferedWriter (new OutputStreamWriter (proc.getOutputStream()));
|
||||
extio.setHandle (osw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int closePipe (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_PIPE_READ)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle();
|
||||
if (osw != StdAwk.stdout)
|
||||
{
|
||||
try { osw.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int readPipe (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_PIPE_READ)
|
||||
{
|
||||
Reader isr;
|
||||
isr = (Reader)extio.getHandle();
|
||||
|
||||
try
|
||||
{
|
||||
len = isr.read (buf, 0, len);
|
||||
if (len == -1) len = 0;
|
||||
}
|
||||
catch (IOException e) { len = -1; }
|
||||
return len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int writePipe (Extio extio, char[] buf, int len)
|
||||
{
|
||||
int mode = extio.getMode();
|
||||
|
||||
if (mode == Extio.MODE_PIPE_WRITE)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle();
|
||||
try { osw.write (buf, 0, len); }
|
||||
catch (IOException e) { len = -1; }
|
||||
return len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected int flushPipe (Extio extio)
|
||||
{
|
||||
int mode = extio.getMode ();
|
||||
|
||||
if (mode == Extio.MODE_PIPE_WRITE)
|
||||
{
|
||||
Writer osw;
|
||||
osw = (Writer)extio.getHandle ();
|
||||
try { osw.flush (); }
|
||||
catch (IOException e) { return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* == arithmetic built-in functions */
|
||||
public Object sin (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.sin(x));
|
||||
}
|
||||
|
||||
public Object cos (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.cos(x));
|
||||
}
|
||||
|
||||
public Object tan (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.tan(x));
|
||||
}
|
||||
|
||||
public Object atan2 (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double y = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[1]);
|
||||
return new Double (Math.atan2(y,x));
|
||||
}
|
||||
|
||||
public Object log (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.log(x));
|
||||
}
|
||||
|
||||
public Object exp (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.exp(x));
|
||||
}
|
||||
|
||||
public Object sqrt (long runid, Object[] args) throws Exception
|
||||
{
|
||||
double x = builtinFunctionArgumentToDouble (runid, args[0]);
|
||||
return new Double (Math.sqrt(x));
|
||||
}
|
||||
|
||||
public Object rand (long runid, Object[] args)
|
||||
{
|
||||
return new Double (random.nextDouble ());
|
||||
}
|
||||
|
||||
public Object srand (long runid, Object[] args) throws Exception
|
||||
{
|
||||
long prev_seed = seed;
|
||||
|
||||
seed = (args == null || args.length == 0)?
|
||||
System.currentTimeMillis ():
|
||||
builtinFunctionArgumentToLong (runid, args[0]);
|
||||
|
||||
random.setSeed (seed);
|
||||
return new Long (prev_seed);
|
||||
}
|
||||
|
||||
/* miscellaneous built-in functions */
|
||||
public Object system (long runid, Object[] args) throws Exception
|
||||
{
|
||||
String str = builtinFunctionArgumentToString (runid, args[0]);
|
||||
Process proc = null;
|
||||
int n = 0;
|
||||
|
||||
str = builtinFunctionArgumentToString (runid, args[0]);
|
||||
|
||||
try { proc = popen (str); }
|
||||
catch (IOException e) { n = -1; }
|
||||
|
||||
if (proc != null)
|
||||
{
|
||||
InputStream is;
|
||||
byte[] buf = new byte[1024];
|
||||
|
||||
is = proc.getInputStream();
|
||||
|
||||
// TODO; better error handling... program execution.. io redirection???
|
||||
try { while (is.read (buf) != -1) ; }
|
||||
catch (IOException e) { n = -1; };
|
||||
|
||||
try { n = proc.waitFor (); }
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
proc.destroy ();
|
||||
n = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return new Long (n);
|
||||
}
|
||||
|
||||
/* == utility functions == */
|
||||
private Process popen (String command) throws IOException
|
||||
{
|
||||
String full;
|
||||
|
||||
/* TODO: consider OS names and versions */
|
||||
full = System.getenv ("ComSpec");
|
||||
if (full != null)
|
||||
{
|
||||
full = full + " /c " + command;
|
||||
}
|
||||
else
|
||||
{
|
||||
full = System.getenv ("SHELL");
|
||||
if (full != null)
|
||||
{
|
||||
full = "/bin/sh -c \"" + command + "\"";
|
||||
}
|
||||
else full = command;
|
||||
}
|
||||
|
||||
return Runtime.getRuntime().exec (full);
|
||||
}
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="aseawk" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=aseawk - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "aseawk.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "aseawk.mak" CFG="aseawk - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "aseawk - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "aseawk - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "aseawk - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../release/lib"
|
||||
# PROP Intermediate_Dir "release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
MTL=midl.exe
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MT /Za /W3 /GX /O2 /I "..\.." /D "NDEBUG" /D "WIN32" /D "_UNICODE" /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "aseawk - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../debug/lib"
|
||||
# PROP Intermediate_Dir "debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
MTL=midl.exe
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /Za /W3 /Gm /GX /ZI /Od /I "..\.." /D "_DEBUG" /D "WIN32" /D "_UNICODE" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "aseawk - Win32 Release"
|
||||
# Name "aseawk - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\awk.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\err.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\extio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\func.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\map.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\misc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\parse.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rex.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\run.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tab.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tree.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\val.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\awk.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\awk_i.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\extio.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\func.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\map.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\parse.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\run.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tab.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tree.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\val.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@ -1,113 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="aesawk_jni" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=aesawk_jni - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "aseawk_jni.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "aseawk_jni.mak" CFG="aesawk_jni - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "aesawk_jni - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "aesawk_jni - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "aesawk_jni - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../release/lib"
|
||||
# PROP Intermediate_Dir "release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "C:\Program Files\java\jdk1.5.0_09\include" /I "C:\Program Files\java\jdk1.5.0_09\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 asecmn.lib aseawk.lib aseutl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /implib:"release/aseawk_jni.lib" /libpath:"$(OutDir)"
|
||||
|
||||
!ELSEIF "$(CFG)" == "aesawk_jni - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../debug/lib"
|
||||
# PROP Intermediate_Dir "debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "C:\Program Files\java\jdk1.5.0_09\include" /I "C:\Program Files\java\jdk1.5.0_09\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 asecmn.lib aseawk.lib aseutl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /implib:"debug/aseawk_jni.lib" /pdbtype:sept /libpath:"$(OutDir)"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "aesawk_jni - Win32 Release"
|
||||
# Name "aesawk_jni - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jni.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jni.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
256
ase/awk/awk.c
256
ase/awk/awk.c
@ -1,256 +0,0 @@
|
||||
/*
|
||||
* $Id: awk.c,v 1.1.1.1 2007/03/28 14:05:13 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#pragma hdrstop
|
||||
#define Library
|
||||
#endif
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
static void free_afn (void* awk, void* afn);
|
||||
|
||||
ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
|
||||
{
|
||||
ase_awk_t* awk;
|
||||
|
||||
ASE_ASSERT (prmfns != ASE_NULL);
|
||||
|
||||
ASE_ASSERT (prmfns->mmgr.malloc != ASE_NULL &&
|
||||
prmfns->mmgr.free != ASE_NULL);
|
||||
|
||||
ASE_ASSERT (prmfns->ccls.is_upper != ASE_NULL &&
|
||||
prmfns->ccls.is_lower != ASE_NULL &&
|
||||
prmfns->ccls.is_alpha != ASE_NULL &&
|
||||
prmfns->ccls.is_digit != ASE_NULL &&
|
||||
prmfns->ccls.is_xdigit != ASE_NULL &&
|
||||
prmfns->ccls.is_alnum != ASE_NULL &&
|
||||
prmfns->ccls.is_space != ASE_NULL &&
|
||||
prmfns->ccls.is_print != ASE_NULL &&
|
||||
prmfns->ccls.is_graph != ASE_NULL &&
|
||||
prmfns->ccls.is_cntrl != ASE_NULL &&
|
||||
prmfns->ccls.is_punct != ASE_NULL &&
|
||||
prmfns->ccls.to_upper != ASE_NULL &&
|
||||
prmfns->ccls.to_lower != ASE_NULL);
|
||||
|
||||
ASE_ASSERT (prmfns->misc.pow != ASE_NULL &&
|
||||
prmfns->misc.sprintf != ASE_NULL &&
|
||||
prmfns->misc.dprintf != ASE_NULL);
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
|
||||
awk = (ase_awk_t*) malloc (ASE_SIZEOF(ase_awk_t));
|
||||
#else
|
||||
awk = (ase_awk_t*) prmfns->mmgr.malloc (
|
||||
prmfns->mmgr.custom_data, ASE_SIZEOF(ase_awk_t));
|
||||
#endif
|
||||
if (awk == ASE_NULL) return ASE_NULL;
|
||||
|
||||
/* it uses the built-in ase_awk_memset because awk is not
|
||||
* fully initialized yet */
|
||||
ase_memset (awk, 0, ASE_SIZEOF(ase_awk_t));
|
||||
ase_memcpy (&awk->prmfns, prmfns, ASE_SIZEOF(awk->prmfns));
|
||||
|
||||
if (ase_str_open (
|
||||
&awk->token.name, 128, &awk->prmfns.mmgr) == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
/* TODO: initial map size?? */
|
||||
if (ase_awk_map_open (
|
||||
&awk->tree.afns, awk, 256, free_afn, awk) == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&awk->token.name);
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (ase_awk_tab_open (&awk->parse.globals, awk) == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&awk->token.name);
|
||||
ase_awk_map_close (&awk->tree.afns);
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (ase_awk_tab_open (&awk->parse.locals, awk) == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&awk->token.name);
|
||||
ase_awk_map_close (&awk->tree.afns);
|
||||
ase_awk_tab_close (&awk->parse.globals);
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (ase_awk_tab_open (&awk->parse.params, awk) == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&awk->token.name);
|
||||
ase_awk_map_close (&awk->tree.afns);
|
||||
ase_awk_tab_close (&awk->parse.globals);
|
||||
ase_awk_tab_close (&awk->parse.locals);
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
awk->option = 0;
|
||||
awk->errnum = ASE_AWK_ENOERR;
|
||||
awk->errlin = 0;
|
||||
|
||||
awk->parse.nlocals_max = 0;
|
||||
|
||||
awk->tree.nglobals = 0;
|
||||
awk->tree.nbglobals = 0;
|
||||
awk->tree.begin = ASE_NULL;
|
||||
awk->tree.end = ASE_NULL;
|
||||
awk->tree.chain = ASE_NULL;
|
||||
awk->tree.chain_tail = ASE_NULL;
|
||||
awk->tree.chain_size = 0;
|
||||
|
||||
awk->token.prev.type = 0;
|
||||
awk->token.prev.line = 0;
|
||||
awk->token.prev.column = 0;
|
||||
awk->token.type = 0;
|
||||
awk->token.line = 0;
|
||||
awk->token.column = 0;
|
||||
|
||||
awk->src.lex.curc = ASE_CHAR_EOF;
|
||||
awk->src.lex.ungotc_count = 0;
|
||||
awk->src.lex.line = 1;
|
||||
awk->src.lex.column = 1;
|
||||
awk->src.shared.buf_pos = 0;
|
||||
awk->src.shared.buf_len = 0;
|
||||
|
||||
awk->bfn.sys = ASE_NULL;
|
||||
awk->bfn.user = ASE_NULL;
|
||||
|
||||
awk->parse.depth.cur.block = 0;
|
||||
awk->parse.depth.cur.loop = 0;
|
||||
awk->parse.depth.cur.expr = 0;
|
||||
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_BLOCK_PARSE, 0);
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_BLOCK_RUN, 0);
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_EXPR_PARSE, 0);
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_EXPR_RUN, 0);
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_REX_BUILD, 0);
|
||||
ase_awk_setmaxdepth (awk, ASE_AWK_DEPTH_REX_MATCH, 0);
|
||||
|
||||
awk->custom_data = custom_data;
|
||||
return awk;
|
||||
}
|
||||
|
||||
static void free_afn (void* owner, void* afn)
|
||||
{
|
||||
ase_awk_afn_t* f = (ase_awk_afn_t*)afn;
|
||||
|
||||
/* f->name doesn't have to be freed */
|
||||
/*ASE_AWK_FREE ((ase_awk_t*)owner, f->name);*/
|
||||
|
||||
ase_awk_clrpt ((ase_awk_t*)owner, f->body);
|
||||
ASE_AWK_FREE ((ase_awk_t*)owner, f);
|
||||
}
|
||||
|
||||
int ase_awk_close (ase_awk_t* awk)
|
||||
{
|
||||
ase_size_t i;
|
||||
|
||||
if (ase_awk_clear (awk) == -1) return -1;
|
||||
ase_awk_clrbfn (awk);
|
||||
|
||||
ase_awk_map_close (&awk->tree.afns);
|
||||
ase_awk_tab_close (&awk->parse.globals);
|
||||
ase_awk_tab_close (&awk->parse.locals);
|
||||
ase_awk_tab_close (&awk->parse.params);
|
||||
ase_str_close (&awk->token.name);
|
||||
|
||||
for (i = 0; i < ASE_COUNTOF(awk->errstr); i++)
|
||||
{
|
||||
if (awk->errstr[i] != ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (awk, awk->errstr[i]);
|
||||
awk->errstr[i] = ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ASE_AWK_ALLOC, ASE_AWK_FREE, etc can not be used
|
||||
* from the next line onwards */
|
||||
ASE_AWK_FREE (awk, awk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ase_awk_clear (ase_awk_t* awk)
|
||||
{
|
||||
ase_memset (&awk->src.ios, 0, ASE_SIZEOF(awk->src.ios));
|
||||
awk->src.lex.curc = ASE_CHAR_EOF;
|
||||
awk->src.lex.ungotc_count = 0;
|
||||
awk->src.lex.line = 1;
|
||||
awk->src.lex.column = 1;
|
||||
awk->src.shared.buf_pos = 0;
|
||||
awk->src.shared.buf_len = 0;
|
||||
|
||||
ase_awk_tab_clear (&awk->parse.globals);
|
||||
ase_awk_tab_clear (&awk->parse.locals);
|
||||
ase_awk_tab_clear (&awk->parse.params);
|
||||
|
||||
awk->parse.nlocals_max = 0;
|
||||
awk->parse.depth.cur.block = 0;
|
||||
awk->parse.depth.cur.loop = 0;
|
||||
awk->parse.depth.cur.expr = 0;
|
||||
|
||||
/* clear parse trees */
|
||||
awk->tree.ok = 0;
|
||||
awk->tree.nbglobals = 0;
|
||||
awk->tree.nglobals = 0;
|
||||
awk->tree.cur_afn.ptr = ASE_NULL;
|
||||
awk->tree.cur_afn.len = 0;
|
||||
ase_awk_map_clear (&awk->tree.afns);
|
||||
|
||||
if (awk->tree.begin != ASE_NULL)
|
||||
{
|
||||
ASE_ASSERT (awk->tree.begin->next == ASE_NULL);
|
||||
ase_awk_clrpt (awk, awk->tree.begin);
|
||||
awk->tree.begin = ASE_NULL;
|
||||
}
|
||||
|
||||
if (awk->tree.end != ASE_NULL)
|
||||
{
|
||||
ASE_ASSERT (awk->tree.end->next == ASE_NULL);
|
||||
ase_awk_clrpt (awk, awk->tree.end);
|
||||
awk->tree.end = ASE_NULL;
|
||||
}
|
||||
|
||||
while (awk->tree.chain != ASE_NULL)
|
||||
{
|
||||
ase_awk_chain_t* next = awk->tree.chain->next;
|
||||
|
||||
if (awk->tree.chain->pattern != ASE_NULL)
|
||||
ase_awk_clrpt (awk, awk->tree.chain->pattern);
|
||||
if (awk->tree.chain->action != ASE_NULL)
|
||||
ase_awk_clrpt (awk, awk->tree.chain->action);
|
||||
ASE_AWK_FREE (awk, awk->tree.chain);
|
||||
awk->tree.chain = next;
|
||||
}
|
||||
|
||||
awk->tree.chain_tail = ASE_NULL;
|
||||
awk->tree.chain_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ase_awk_getoption (ase_awk_t* awk)
|
||||
{
|
||||
return awk->option;
|
||||
}
|
||||
|
||||
void ase_awk_setoption (ase_awk_t* awk, int opt)
|
||||
{
|
||||
awk->option = opt;
|
||||
}
|
||||
|
||||
void* ase_awk_getcustomdata (ase_awk_t* awk)
|
||||
{
|
||||
return awk->custom_data;
|
||||
}
|
502
ase/awk/awk.h
502
ase/awk/awk.h
@ -1,502 +0,0 @@
|
||||
/*
|
||||
* $Id: awk.h,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#define _ASE_AWK_AWK_H_
|
||||
|
||||
#include <ase/cmn/types.h>
|
||||
#include <ase/cmn/macros.h>
|
||||
|
||||
typedef struct ase_awk_t ase_awk_t;
|
||||
typedef struct ase_awk_run_t ase_awk_run_t;
|
||||
typedef struct ase_awk_val_t ase_awk_val_t;
|
||||
typedef struct ase_awk_map_t ase_awk_map_t;
|
||||
typedef struct ase_awk_extio_t ase_awk_extio_t;
|
||||
|
||||
typedef struct ase_awk_prmfns_t ase_awk_prmfns_t;
|
||||
typedef struct ase_awk_srcios_t ase_awk_srcios_t;
|
||||
typedef struct ase_awk_runios_t ase_awk_runios_t;
|
||||
typedef struct ase_awk_runcbs_t ase_awk_runcbs_t;
|
||||
typedef struct ase_awk_runarg_t ase_awk_runarg_t;
|
||||
|
||||
typedef ase_real_t (*ase_awk_pow_t) (void* custom, ase_real_t x, ase_real_t y);
|
||||
typedef int (*ase_awk_sprintf_t) (
|
||||
void* custom, ase_char_t* buf, ase_size_t size,
|
||||
const ase_char_t* fmt, ...);
|
||||
typedef void (*ase_awk_dprintf_t) (void* custom, const ase_char_t* fmt, ...);
|
||||
|
||||
typedef ase_ssize_t (*ase_awk_io_t) (
|
||||
int cmd, void* arg, ase_char_t* data, ase_size_t count);
|
||||
|
||||
struct ase_awk_extio_t
|
||||
{
|
||||
ase_awk_run_t* run; /* [IN] */
|
||||
int type; /* [IN] console, file, coproc, pipe */
|
||||
int mode; /* [IN] read, write, etc */
|
||||
ase_char_t* name; /* [IN] */
|
||||
void* custom_data; /* [IN] */
|
||||
void* handle; /* [OUT] */
|
||||
|
||||
/* input */
|
||||
struct
|
||||
{
|
||||
ase_char_t buf[2048];
|
||||
ase_size_t pos;
|
||||
ase_size_t len;
|
||||
ase_bool_t eof;
|
||||
ase_bool_t eos;
|
||||
} in;
|
||||
|
||||
/* output */
|
||||
struct
|
||||
{
|
||||
ase_bool_t eof;
|
||||
ase_bool_t eos;
|
||||
} out;
|
||||
|
||||
ase_awk_extio_t* next;
|
||||
};
|
||||
|
||||
struct ase_awk_prmfns_t
|
||||
{
|
||||
ase_mmgr_t mmgr;
|
||||
ase_ccls_t ccls;
|
||||
|
||||
struct
|
||||
{
|
||||
/* utilities */
|
||||
ase_awk_pow_t pow; /* required */
|
||||
ase_awk_sprintf_t sprintf; /* required */
|
||||
ase_awk_dprintf_t dprintf; /* required in the debug mode */
|
||||
|
||||
/* user-defined data passed to the functions above */
|
||||
void* custom_data; /* optional */
|
||||
} misc;
|
||||
};
|
||||
|
||||
struct ase_awk_srcios_t
|
||||
{
|
||||
ase_awk_io_t in;
|
||||
ase_awk_io_t out;
|
||||
void* custom_data;
|
||||
};
|
||||
|
||||
struct ase_awk_runios_t
|
||||
{
|
||||
ase_awk_io_t pipe;
|
||||
ase_awk_io_t coproc;
|
||||
ase_awk_io_t file;
|
||||
ase_awk_io_t console;
|
||||
void* custom_data;
|
||||
};
|
||||
|
||||
struct ase_awk_runcbs_t
|
||||
{
|
||||
void (*on_start) (
|
||||
ase_awk_run_t* run, void* custom_data);
|
||||
|
||||
void (*on_statement) (
|
||||
ase_awk_run_t* run, ase_size_t line, void* custom_data);
|
||||
|
||||
void (*on_return) (
|
||||
ase_awk_run_t* run, ase_awk_val_t* ret, void* custom_data);
|
||||
|
||||
void (*on_end) (
|
||||
ase_awk_run_t* run, int errnum, void* custom_data);
|
||||
|
||||
void* custom_data;
|
||||
};
|
||||
|
||||
struct ase_awk_runarg_t
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
};
|
||||
|
||||
/* io function commands */
|
||||
enum
|
||||
{
|
||||
ASE_AWK_IO_OPEN = 0,
|
||||
ASE_AWK_IO_CLOSE = 1,
|
||||
ASE_AWK_IO_READ = 2,
|
||||
ASE_AWK_IO_WRITE = 3,
|
||||
ASE_AWK_IO_FLUSH = 4,
|
||||
ASE_AWK_IO_NEXT = 5
|
||||
};
|
||||
|
||||
/* various options */
|
||||
enum
|
||||
{
|
||||
/* allow undeclared variables and implicit concatenation */
|
||||
ASE_AWK_IMPLICIT = (1 << 0),
|
||||
|
||||
/* allow explicit variable declaration and the concatenation
|
||||
* operator, a period. */
|
||||
ASE_AWK_EXPLICIT = (1 << 1),
|
||||
|
||||
/* a function name should not coincide to be a variable name */
|
||||
ASE_AWK_UNIQUEFN = (1 << 2),
|
||||
|
||||
/* allow variable shading */
|
||||
ASE_AWK_SHADING = (1 << 3),
|
||||
|
||||
/* support shift operators */
|
||||
ASE_AWK_SHIFT = (1 << 4),
|
||||
|
||||
/* enable the idiv operator (double slashes) */
|
||||
ASE_AWK_IDIV = (1 << 5),
|
||||
|
||||
/* support string concatenation in tokenization.
|
||||
* this option can change the behavior of a certain construct.
|
||||
* getline < "abc" ".def" is treated as if it is getline < "abc.def"
|
||||
* when this option is on. If this option is off, the same expression
|
||||
* is treated as if it is (getline < "abc") ".def". */
|
||||
ASE_AWK_STRCONCAT = (1 << 6),
|
||||
|
||||
/* support getline and print */
|
||||
ASE_AWK_EXTIO = (1 << 7),
|
||||
|
||||
/* support co-process */
|
||||
ASE_AWK_COPROC = (1 << 8),
|
||||
|
||||
/* support blockless patterns */
|
||||
ASE_AWK_BLOCKLESS = (1 << 9),
|
||||
|
||||
/* use 1 as the start index for string operations */
|
||||
ASE_AWK_STRBASEONE = (1 << 10),
|
||||
|
||||
/* strip off leading and trailing spaces when splitting a record
|
||||
* into fields with a regular expression.
|
||||
*
|
||||
* Consider the following program.
|
||||
* BEGIN { FS="[:[:space:]]+"; }
|
||||
* {
|
||||
* print "NF=" NF;
|
||||
* for (i = 0; i < NF; i++) print i " [" $(i+1) "]";
|
||||
* }
|
||||
*
|
||||
* The program splits " a b c " into [a], [b], [c] when this
|
||||
* option is on while into [], [a], [b], [c], [] when it is off.
|
||||
*/
|
||||
ASE_AWK_STRIPSPACES = (1 << 11),
|
||||
|
||||
/* enable the nextoutfile keyword */
|
||||
ASE_AWK_NEXTOFILE = (1 << 12),
|
||||
|
||||
/* cr + lf by default */
|
||||
ASE_AWK_CRLF = (1 << 13)
|
||||
};
|
||||
|
||||
/* error code */
|
||||
enum
|
||||
{
|
||||
ASE_AWK_ENOERR, /* no error */
|
||||
|
||||
ASE_AWK_EINVAL, /* invalid parameter */
|
||||
ASE_AWK_ENOMEM, /* out of memory */
|
||||
ASE_AWK_ENOSUP, /* not supported */
|
||||
ASE_AWK_ENOPER, /* operation not allowed */
|
||||
ASE_AWK_ENODEV, /* function '%.*s' not found */
|
||||
ASE_AWK_ENOSPC, /* no space left on device */
|
||||
ASE_AWK_EMFILE, /* too many open files */
|
||||
ASE_AWK_EMLINK, /* too many links */
|
||||
ASE_AWK_EAGAIN, /* resource temporarily unavailable */
|
||||
ASE_AWK_ENOENT, /* file or data not existing */
|
||||
ASE_AWK_EEXIST, /* file or data exists */
|
||||
ASE_AWK_EFTBIG, /* file or data too big */
|
||||
ASE_AWK_ETBUSY, /* system too busy */
|
||||
ASE_AWK_EISDIR, /* is a directory */
|
||||
ASE_AWK_EIOERR, /* i/o error */
|
||||
|
||||
ASE_AWK_EOPEN, /* cannot open */
|
||||
ASE_AWK_EREAD, /* cannot read */
|
||||
ASE_AWK_EWRITE, /* cannot write */
|
||||
ASE_AWK_ECLOSE, /* cannot close */
|
||||
|
||||
ASE_AWK_EINTERN, /* internal error */
|
||||
ASE_AWK_ERUNTIME, /* run-time error */
|
||||
ASE_AWK_EBLKNST, /* blocke nested too deeply */
|
||||
ASE_AWK_EEXPRNST, /* expression nested too deeply */
|
||||
|
||||
ASE_AWK_ESINOP,
|
||||
ASE_AWK_ESINCL,
|
||||
ASE_AWK_ESINRD,
|
||||
|
||||
ASE_AWK_ESOUTOP,
|
||||
ASE_AWK_ESOUTCL,
|
||||
ASE_AWK_ESOUTWR,
|
||||
|
||||
ASE_AWK_ELXCHR, /* lexer came accross an wrong character */
|
||||
ASE_AWK_ELXUNG, /* lexer failed to unget a character */
|
||||
|
||||
ASE_AWK_EENDSRC, /* unexpected end of source */
|
||||
ASE_AWK_EENDCMT, /* a comment not closed properly */
|
||||
ASE_AWK_EENDSTR, /* a string not closed with a quote */
|
||||
ASE_AWK_EENDREX, /* unexpected end of a regular expression */
|
||||
ASE_AWK_ELBRACE, /* left brace expected */
|
||||
ASE_AWK_ELPAREN, /* left parenthesis expected */
|
||||
ASE_AWK_ERPAREN, /* right parenthesis expected */
|
||||
ASE_AWK_ERBRACK, /* right bracket expected */
|
||||
ASE_AWK_ECOMMA, /* comma expected */
|
||||
ASE_AWK_ESCOLON, /* semicolon expected */
|
||||
ASE_AWK_ECOLON, /* colon expected */
|
||||
ASE_AWK_ESTMEND, /* statement not ending with a semicolon */
|
||||
ASE_AWK_EIN, /* keyword 'in' is expected */
|
||||
ASE_AWK_ENOTVAR, /* not a variable name after 'in' */
|
||||
ASE_AWK_EEXPRES, /* expression expected */
|
||||
|
||||
ASE_AWK_EWHILE, /* keyword 'while' is expected */
|
||||
ASE_AWK_EASSIGN, /* assignment statement expected */
|
||||
ASE_AWK_EIDENT, /* identifier expected */
|
||||
ASE_AWK_EFNNAME, /* not a valid function name */
|
||||
ASE_AWK_EBLKBEG, /* BEGIN requires an action block */
|
||||
ASE_AWK_EBLKEND, /* END requires an action block */
|
||||
ASE_AWK_EDUPBEG, /* duplicate BEGIN */
|
||||
ASE_AWK_EDUPEND, /* duplicate END */
|
||||
ASE_AWK_EBFNRED, /* builtin function redefined */
|
||||
ASE_AWK_EAFNRED, /* function redefined */
|
||||
ASE_AWK_EGBLRED, /* global variable redefined */
|
||||
ASE_AWK_EPARRED, /* parameter redefined */
|
||||
ASE_AWK_EDUPPAR, /* duplicate parameter name */
|
||||
ASE_AWK_EDUPGBL, /* duplicate global variable name */
|
||||
ASE_AWK_EDUPLCL, /* duplicate local variable name */
|
||||
ASE_AWK_EBADPAR, /* not a valid parameter name */
|
||||
ASE_AWK_EBADVAR, /* not a valid variable name */
|
||||
ASE_AWK_EUNDEF, /* undefined identifier */
|
||||
ASE_AWK_ELVALUE, /* l-value required */
|
||||
ASE_AWK_EGBLTM, /* too many global variables */
|
||||
ASE_AWK_ELCLTM, /* too many local variables */
|
||||
ASE_AWK_EPARTM, /* too many parameters */
|
||||
ASE_AWK_EDELETE, /* delete not followed by a variable */
|
||||
ASE_AWK_EBREAK, /* break outside a loop */
|
||||
ASE_AWK_ECONTINUE, /* continue outside a loop */
|
||||
ASE_AWK_ENEXTBEG, /* next illegal in BEGIN block */
|
||||
ASE_AWK_ENEXTEND, /* next illegal in END block */
|
||||
ASE_AWK_ENEXTFBEG, /* nextfile illegal in BEGIN block */
|
||||
ASE_AWK_ENEXTFEND, /* nextfile illegal in END block */
|
||||
ASE_AWK_EPRINTFARG, /* printf not followed by any arguments */
|
||||
ASE_AWK_EPREPST, /* both prefix and postfix increment/decrement
|
||||
operator present */
|
||||
ASE_AWK_EGLNCPS, /* coprocess not supported by getline */
|
||||
|
||||
/* run time error */
|
||||
ASE_AWK_EDIVBY0, /* divide by zero */
|
||||
ASE_AWK_EOPERAND, /* invalid operand */
|
||||
ASE_AWK_EPOSIDX, /* wrong position index */
|
||||
ASE_AWK_EARGTF, /* too few arguments */
|
||||
ASE_AWK_EARGTM, /* too many arguments */
|
||||
ASE_AWK_EFNNONE, /* no such function */
|
||||
ASE_AWK_ENOTIDX, /* variable not indexable */
|
||||
ASE_AWK_ENOTDEL, /* variable not deletable */
|
||||
ASE_AWK_ENOTMAP, /* value not a map */
|
||||
ASE_AWK_ENOTMAPIN, /* right-hand side of 'in' not a map */
|
||||
ASE_AWK_ENOTMAPNILIN, /* right-hand side of 'in' not a map nor nil */
|
||||
ASE_AWK_ENOTREF, /* value not referenceable */
|
||||
ASE_AWK_ENOTASS, /* value not assignable */
|
||||
ASE_AWK_EIDXVALASSMAP, /* indexed value cannot be assigned a map */
|
||||
ASE_AWK_EPOSVALASSMAP, /* a positional cannot be assigned a map */
|
||||
ASE_AWK_EMAPTOSCALAR, /* cannot change a map to a scalar value */
|
||||
ASE_AWK_ESCALARTOMAP, /* cannot change a scalar value to a map */
|
||||
ASE_AWK_EMAPNOTALLOWED, /* a map is not allowed */
|
||||
ASE_AWK_EVALTYPE, /* wrong value type */
|
||||
ASE_AWK_ERDELETE, /* delete called with a wrong target */
|
||||
ASE_AWK_ERNEXTBEG, /* next called from BEGIN */
|
||||
ASE_AWK_ERNEXTEND, /* next called from END */
|
||||
ASE_AWK_ERNEXTFBEG, /* nextfile called from BEGIN */
|
||||
ASE_AWK_ERNEXTFEND, /* nextfile called from END */
|
||||
ASE_AWK_EBFNUSER, /* wrong builtin function implementation */
|
||||
ASE_AWK_EBFNIMPL, /* builtin function handler failed */
|
||||
ASE_AWK_EIOUSER, /* wrong user io handler implementation */
|
||||
ASE_AWK_EIONONE, /* no such io name found */
|
||||
ASE_AWK_EIOIMPL, /* i/o callback returned an error */
|
||||
ASE_AWK_EIONMEM, /* i/o name empty */
|
||||
ASE_AWK_EIONMNL, /* i/o name contains '\0' */
|
||||
ASE_AWK_EFMTARG, /* arguments to format string not sufficient */
|
||||
ASE_AWK_EFMTCNV, /* recursion detected in format conversion */
|
||||
ASE_AWK_ECONVFMTCHR, /* an invalid character found in CONVFMT */
|
||||
ASE_AWK_EOFMTCHR, /* an invalid character found in OFMT */
|
||||
|
||||
/* regular expression error */
|
||||
ASE_AWK_EREXRECUR, /* recursion too deep */
|
||||
ASE_AWK_EREXRPAREN, /* a right parenthesis is expected */
|
||||
ASE_AWK_EREXRBRACKET, /* a right bracket is expected */
|
||||
ASE_AWK_EREXRBRACE, /* a right brace is expected */
|
||||
ASE_AWK_EREXUNBALPAR, /* unbalanced parenthesis */
|
||||
ASE_AWK_EREXCOLON, /* a colon is expected */
|
||||
ASE_AWK_EREXCRANGE, /* invalid character range */
|
||||
ASE_AWK_EREXCCLASS, /* invalid character class */
|
||||
ASE_AWK_EREXBRANGE, /* invalid boundary range */
|
||||
ASE_AWK_EREXEND, /* unexpected end of the pattern */
|
||||
ASE_AWK_EREXGARBAGE, /* garbage after the pattern */
|
||||
|
||||
/* the number of error numbers, internal use only */
|
||||
ASE_AWK_NUMERRNUM
|
||||
};
|
||||
|
||||
/* depth types */
|
||||
enum ase_awk_depth_t
|
||||
{
|
||||
ASE_AWK_DEPTH_BLOCK_PARSE = (1 << 0),
|
||||
ASE_AWK_DEPTH_BLOCK_RUN = (1 << 1),
|
||||
ASE_AWK_DEPTH_EXPR_PARSE = (1 << 2),
|
||||
ASE_AWK_DEPTH_EXPR_RUN = (1 << 3),
|
||||
ASE_AWK_DEPTH_REX_BUILD = (1 << 4),
|
||||
ASE_AWK_DEPTH_REX_MATCH = (1 << 5)
|
||||
};
|
||||
|
||||
/* extio types */
|
||||
enum ase_awk_extio_type_t
|
||||
{
|
||||
/* extio types available */
|
||||
ASE_AWK_EXTIO_PIPE,
|
||||
ASE_AWK_EXTIO_COPROC,
|
||||
ASE_AWK_EXTIO_FILE,
|
||||
ASE_AWK_EXTIO_CONSOLE,
|
||||
|
||||
/* reserved for internal use only */
|
||||
ASE_AWK_EXTIO_NUM
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ASE_AWK_EXTIO_PIPE_READ = 0,
|
||||
ASE_AWK_EXTIO_PIPE_WRITE = 1,
|
||||
|
||||
/*
|
||||
ASE_AWK_EXTIO_COPROC_READ = 0,
|
||||
ASE_AWK_EXTIO_COPROC_WRITE = 1,
|
||||
ASE_AWK_EXTIO_COPROC_RDWR = 2,
|
||||
*/
|
||||
|
||||
ASE_AWK_EXTIO_FILE_READ = 0,
|
||||
ASE_AWK_EXTIO_FILE_WRITE = 1,
|
||||
ASE_AWK_EXTIO_FILE_APPEND = 2,
|
||||
|
||||
ASE_AWK_EXTIO_CONSOLE_READ = 0,
|
||||
ASE_AWK_EXTIO_CONSOLE_WRITE = 1
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data);
|
||||
int ase_awk_close (ase_awk_t* awk);
|
||||
int ase_awk_clear (ase_awk_t* awk);
|
||||
|
||||
void* ase_awk_getcustomdata (ase_awk_t* awk);
|
||||
|
||||
const ase_char_t* ase_awk_geterrstr (ase_awk_t* awk, int num);
|
||||
int ase_awk_seterrstr (ase_awk_t* awk, int num, const ase_char_t* str);
|
||||
|
||||
int ase_awk_geterrnum (ase_awk_t* awk);
|
||||
ase_size_t ase_awk_geterrlin (ase_awk_t* awk);
|
||||
const ase_char_t* ase_awk_geterrmsg (ase_awk_t* awk);
|
||||
void ase_awk_seterrnum (ase_awk_t* awk, int errnum);
|
||||
|
||||
void ase_awk_geterror (
|
||||
ase_awk_t* awk, int* errnum,
|
||||
ase_size_t* errlin, const ase_char_t** errmsg);
|
||||
|
||||
void ase_awk_seterror (
|
||||
ase_awk_t* awk, int errnum, ase_size_t errlin,
|
||||
const ase_cstr_t* errarg, ase_size_t argcnt);
|
||||
|
||||
int ase_awk_getoption (ase_awk_t* awk);
|
||||
void ase_awk_setoption (ase_awk_t* awk, int opt);
|
||||
|
||||
ase_size_t ase_awk_getmaxdepth (ase_awk_t* awk, int type);
|
||||
void ase_awk_setmaxdepth (ase_awk_t* awk, int types, ase_size_t depth);
|
||||
|
||||
int ase_awk_parse (ase_awk_t* awk, ase_awk_srcios_t* srcios);
|
||||
|
||||
/*
|
||||
* ase_awk_run return 0 on success and -1 on failure, generally speaking.
|
||||
* A runtime context is required for it to start running the program.
|
||||
* Once the runtime context is created, the program starts to run.
|
||||
* The context creation failure is reported by the return value -1 of
|
||||
* this function. however, the runtime error after the context creation
|
||||
* is reported differently depending on the use of the callback.
|
||||
* When no callback is specified (i.e. runcbs is ASE_NULL), ase_awk_run
|
||||
* returns -1 on an error and awk->errnum is set accordingly.
|
||||
* However, if a callback is specified (i.e. runcbs is not ASE_NULL),
|
||||
* ase_awk_run returns 0 on both success and failure. Instead, the
|
||||
* on_end handler of the callback is triggered with the relevant
|
||||
* error number. The third parameter to on_end denotes this error number.
|
||||
*/
|
||||
int ase_awk_run (
|
||||
ase_awk_t* awk, const ase_char_t* main,
|
||||
ase_awk_runios_t* runios, ase_awk_runcbs_t* runcbs,
|
||||
ase_awk_runarg_t* runarg, void* custom_data);
|
||||
|
||||
int ase_awk_stop (ase_awk_run_t* run);
|
||||
|
||||
/* functions to access internal stack structure */
|
||||
ase_size_t ase_awk_getnargs (ase_awk_run_t* run);
|
||||
ase_awk_val_t* ase_awk_getarg (ase_awk_run_t* run, ase_size_t idx);
|
||||
ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, ase_size_t idx);
|
||||
int ase_awk_setglobal (ase_awk_run_t* run, ase_size_t idx, ase_awk_val_t* val);
|
||||
void ase_awk_setretval (ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
|
||||
int ase_awk_setfilename (
|
||||
ase_awk_run_t* run, const ase_char_t* name, ase_size_t len);
|
||||
int ase_awk_setofilename (
|
||||
ase_awk_run_t* run, const ase_char_t* name, ase_size_t len);
|
||||
|
||||
ase_awk_t* ase_awk_getrunawk (ase_awk_run_t* awk);
|
||||
void* ase_awk_getruncustomdata (ase_awk_run_t* awk);
|
||||
ase_awk_map_t* ase_awk_getrunnamedvarmap (ase_awk_run_t* awk);
|
||||
|
||||
/* functions to manipulate the run-time error */
|
||||
int ase_awk_getrunerrnum (ase_awk_run_t* run);
|
||||
ase_size_t ase_awk_getrunerrlin (ase_awk_run_t* run);
|
||||
const ase_char_t* ase_awk_getrunerrmsg (ase_awk_run_t* run);
|
||||
void ase_awk_setrunerrnum (ase_awk_run_t* run, int errnum);
|
||||
|
||||
void ase_awk_getrunerror (
|
||||
ase_awk_run_t* run, int* errnum,
|
||||
ase_size_t* errlin, const ase_char_t** errmsg);
|
||||
|
||||
void ase_awk_setrunerror (
|
||||
ase_awk_run_t* run, int errnum, ase_size_t errlin,
|
||||
const ase_cstr_t* errarg, ase_size_t argcnt);
|
||||
|
||||
/* functions to manipulate built-in functions */
|
||||
void* ase_awk_addbfn (
|
||||
ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len,
|
||||
int when_valid, ase_size_t min_args, ase_size_t max_args,
|
||||
const ase_char_t* arg_spec,
|
||||
int (*handler)(ase_awk_run_t*,const ase_char_t*,ase_size_t));
|
||||
|
||||
int ase_awk_delbfn (
|
||||
ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len);
|
||||
|
||||
void ase_awk_clrbfn (ase_awk_t* awk);
|
||||
|
||||
/* record and field functions */
|
||||
int ase_awk_clrrec (ase_awk_run_t* run, ase_bool_t skip_inrec_line);
|
||||
int ase_awk_setrec (ase_awk_run_t* run, ase_size_t idx, const ase_char_t* str, ase_size_t len);
|
||||
|
||||
/* utility functions exported by awk.h */
|
||||
void* ase_awk_malloc (ase_awk_t* awk, ase_size_t size);
|
||||
void ase_awk_free (ase_awk_t* awk, void* ptr);
|
||||
|
||||
ase_long_t ase_awk_strxtolong (
|
||||
ase_awk_t* awk, const ase_char_t* str, ase_size_t len,
|
||||
int base, const ase_char_t** endptr);
|
||||
ase_real_t ase_awk_strxtoreal (
|
||||
ase_awk_t* awk, const ase_char_t* str, ase_size_t len,
|
||||
const ase_char_t** endptr);
|
||||
|
||||
ase_size_t ase_awk_longtostr (
|
||||
ase_long_t value, int radix, const ase_char_t* prefix,
|
||||
ase_char_t* buf, ase_size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
Programs
|
||||
|
||||
pattern { action }
|
||||
function name (parameter-list) { statement }
|
||||
|
||||
Patterns
|
||||
BEGIN
|
||||
END
|
||||
expresion
|
||||
/regular expression/
|
||||
pattern && pattern
|
||||
pattern || pattern
|
||||
!pattern
|
||||
(pattern)
|
||||
pattern, pattern -> range pattern
|
||||
|
||||
Actions
|
||||
break
|
||||
continue
|
||||
delete array-element
|
||||
do statement while (expression)
|
||||
exit [expression]
|
||||
expression
|
||||
if (expression) statement [else statement]
|
||||
input-output statement
|
||||
for (expression; expression; expression) statement
|
||||
for (variable in array) statement
|
||||
next
|
||||
return [expression]
|
||||
while (expression) statement
|
||||
{ statements }
|
||||
|
||||
Variables
|
||||
|
||||
global variables (enabled when awk->opt & XP_AWK_OPT_VARDCL)
|
||||
|
||||
global x;
|
||||
global x, y;
|
||||
|
||||
local variables (enabled when awk->opt & XP_AWK_OPT_VARDCL)
|
||||
|
||||
local x;
|
||||
local x, y;
|
||||
|
||||
function arguments (enabled always)
|
||||
|
||||
function funca (x, y)
|
||||
|
||||
|
||||
local variables in function declaration (enabled when awk->opt & XP_AWK_OPT_FUNCLOCAL)
|
||||
|
||||
function funca (x, y, v1, v2)
|
||||
|
||||
|
||||
variables without any declarations (enabled when awk->opt & XP_AWK_OPT_NAMEDVAR)
|
||||
|
||||
x = 10; // x is put into the global hash table.
|
||||
|
||||
|
||||
Optimization
|
||||
|
||||
constant folding
|
||||
2 * 10 => 20
|
||||
|
||||
loop
|
||||
remove while (0) { ... }
|
||||
|
||||
if
|
||||
remove if (0) {}
|
||||
use else_part only
|
||||
|
338
ase/awk/awk_i.h
338
ase/awk/awk_i.h
@ -1,338 +0,0 @@
|
||||
/*
|
||||
* $Id: awk_i.h,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_AWKI_H_
|
||||
#define _ASE_AWK_AWKI_H_
|
||||
|
||||
#include <ase/cmn/mem.h>
|
||||
#include <ase/cmn/str.h>
|
||||
|
||||
typedef struct ase_awk_chain_t ase_awk_chain_t;
|
||||
typedef struct ase_awk_tree_t ase_awk_tree_t;
|
||||
|
||||
#include <ase/awk/awk.h>
|
||||
#include <ase/awk/rex.h>
|
||||
#include <ase/awk/map.h>
|
||||
#include <ase/awk/tree.h>
|
||||
#include <ase/awk/val.h>
|
||||
#include <ase/awk/func.h>
|
||||
#include <ase/awk/tab.h>
|
||||
#include <ase/awk/parse.h>
|
||||
#include <ase/awk/run.h>
|
||||
#include <ase/awk/extio.h>
|
||||
#include <ase/awk/misc.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996)
|
||||
#pragma warning (disable: 4296)
|
||||
#endif
|
||||
|
||||
#define ASE_AWK_MAX_GLOBALS 9999
|
||||
#define ASE_AWK_MAX_LOCALS 9999
|
||||
#define ASE_AWK_MAX_PARAMS 9999
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
|
||||
#define ASE_AWK_MALLOC(awk,size) malloc (size)
|
||||
#define ASE_AWK_REALLOC(awk,ptr,size) realloc (ptr, size)
|
||||
#define ASE_AWK_FREE(awk,ptr) free (ptr)
|
||||
#else
|
||||
#define ASE_AWK_MALLOC(awk,size) ASE_MALLOC(&(awk)->prmfns.mmgr,size)
|
||||
#define ASE_AWK_REALLOC(awk,ptr,size) ASE_REALLOC(&(awk)->prmfns.mmgr,ptr,size)
|
||||
#define ASE_AWK_FREE(awk,ptr) ASE_FREE(&(awk)->prmfns.mmgr,ptr)
|
||||
#endif
|
||||
|
||||
#define ASE_AWK_ISUPPER(awk,c) ASE_ISUPPER(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISLOWER(awk,c) ASE_ISLOWER(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISALPHA(awk,c) ASE_ISALPHA(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISDIGIT(awk,c) ASE_ISDIGIT(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISXDIGIT(awk,c) ASE_ISXDIGIT(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISALNUM(awk,c) ASE_ISALNUM(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISSPACE(awk,c) ASE_ISSPACE(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISPRINT(awk,c) ASE_ISPRINT(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISGRAPH(awk,c) ASE_ISGRAPH(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISCNTRL(awk,c) ASE_ISCNTRL(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_ISPUNCT(awk,c) ASE_ISPUNCT(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_TOUPPER(awk,c) ASE_TOUPPER(&(awk)->prmfns.ccls,c)
|
||||
#define ASE_AWK_TOLOWER(awk,c) ASE_TOLOWER(&(awk)->prmfns.ccls,c)
|
||||
|
||||
struct ase_awk_tree_t
|
||||
{
|
||||
ase_size_t nglobals; /* total number of globals */
|
||||
ase_size_t nbglobals; /* number of builtin globals */
|
||||
ase_cstr_t cur_afn;
|
||||
ase_awk_map_t afns; /* awk function map */
|
||||
ase_awk_nde_t* begin;
|
||||
ase_awk_nde_t* end;
|
||||
ase_awk_chain_t* chain;
|
||||
ase_awk_chain_t* chain_tail;
|
||||
ase_size_t chain_size; /* number of nodes in the chain */
|
||||
int ok;
|
||||
};
|
||||
|
||||
struct ase_awk_t
|
||||
{
|
||||
ase_awk_prmfns_t prmfns;
|
||||
void* custom_data;
|
||||
|
||||
/* options */
|
||||
int option;
|
||||
|
||||
/* parse tree */
|
||||
ase_awk_tree_t tree;
|
||||
|
||||
/* temporary information that the parser needs */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
int block;
|
||||
int loop;
|
||||
int stmnt; /* statement */
|
||||
} id;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t loop;
|
||||
ase_size_t expr; /* expression */
|
||||
} cur;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t expr;
|
||||
} max;
|
||||
} depth;
|
||||
|
||||
ase_awk_tab_t globals;
|
||||
ase_awk_tab_t locals;
|
||||
ase_awk_tab_t params;
|
||||
ase_size_t nlocals_max;
|
||||
|
||||
ase_awk_nde_t* (*parse_block) (
|
||||
ase_awk_t*,ase_size_t,ase_bool_t);
|
||||
} parse;
|
||||
|
||||
/* source code management */
|
||||
struct
|
||||
{
|
||||
ase_awk_srcios_t ios;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_cint_t curc;
|
||||
ase_cint_t ungotc[5];
|
||||
ase_size_t ungotc_line[5];
|
||||
ase_size_t ungotc_column[5];
|
||||
ase_size_t ungotc_count;
|
||||
|
||||
ase_size_t line;
|
||||
ase_size_t column;
|
||||
} lex;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_char_t buf[512];
|
||||
ase_size_t buf_pos;
|
||||
ase_size_t buf_len;
|
||||
} shared;
|
||||
} src;
|
||||
|
||||
/* token */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
ase_size_t line;
|
||||
ase_size_t column;
|
||||
} prev;
|
||||
|
||||
int type;
|
||||
ase_str_t name;
|
||||
ase_size_t line;
|
||||
ase_size_t column;
|
||||
} token;
|
||||
|
||||
/* builtin functions */
|
||||
struct
|
||||
{
|
||||
ase_awk_bfn_t* sys;
|
||||
ase_awk_bfn_t* user;
|
||||
} bfn;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t expr;
|
||||
} max;
|
||||
} depth;
|
||||
} run;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_size_t build;
|
||||
ase_size_t match;
|
||||
} max;
|
||||
} depth;
|
||||
} rex;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_char_t fmt[1024];
|
||||
} tmp;
|
||||
|
||||
/* housekeeping */
|
||||
int errnum;
|
||||
ase_size_t errlin;
|
||||
ase_char_t errmsg[256];
|
||||
|
||||
ase_char_t* errstr[ASE_AWK_NUMERRNUM];
|
||||
};
|
||||
|
||||
struct ase_awk_chain_t
|
||||
{
|
||||
ase_awk_nde_t* pattern;
|
||||
ase_awk_nde_t* action;
|
||||
ase_awk_chain_t* next;
|
||||
};
|
||||
|
||||
struct ase_awk_run_t
|
||||
{
|
||||
int id;
|
||||
ase_awk_map_t named;
|
||||
|
||||
void** stack;
|
||||
ase_size_t stack_top;
|
||||
ase_size_t stack_base;
|
||||
ase_size_t stack_limit;
|
||||
int exit_level;
|
||||
|
||||
ase_awk_val_int_t* icache[200]; /* TODO: choose the optimal size */
|
||||
ase_awk_val_real_t* rcache[200]; /* TODO: choose the optimal size */
|
||||
ase_awk_val_ref_t* fcache[200]; /* TODO: choose the optimal size */
|
||||
ase_size_t icache_count;
|
||||
ase_size_t rcache_count;
|
||||
ase_size_t fcache_count;
|
||||
|
||||
ase_awk_nde_blk_t* active_block;
|
||||
ase_byte_t* pattern_range_state;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_char_t buf[1024];
|
||||
ase_size_t buf_pos;
|
||||
ase_size_t buf_len;
|
||||
ase_bool_t eof;
|
||||
|
||||
ase_str_t line;
|
||||
ase_awk_val_t* d0; /* $0 */
|
||||
|
||||
ase_size_t maxflds;
|
||||
ase_size_t nflds; /* NF */
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
ase_awk_val_t* val; /* $1 .. $NF */
|
||||
}* flds;
|
||||
|
||||
} inrec;
|
||||
|
||||
struct
|
||||
{
|
||||
void* rs;
|
||||
void* fs;
|
||||
int ignorecase;
|
||||
ase_size_t fnr;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} convfmt;
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} ofmt;
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} ofs;
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} ors;
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} subsep;
|
||||
} global;
|
||||
|
||||
/* extio chain */
|
||||
struct
|
||||
{
|
||||
ase_awk_io_t handler[ASE_AWK_EXTIO_NUM];
|
||||
void* custom_data;
|
||||
ase_awk_extio_t* chain;
|
||||
} extio;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_str_t fmt;
|
||||
ase_str_t out;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len; /* length */
|
||||
ase_size_t inc; /* increment */
|
||||
} tmp;
|
||||
} format;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t expr; /* expression */
|
||||
} cur;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t expr;
|
||||
} max;
|
||||
} depth;
|
||||
|
||||
int errnum;
|
||||
ase_size_t errlin;
|
||||
ase_char_t errmsg[256];
|
||||
|
||||
void* custom_data;
|
||||
|
||||
ase_awk_t* awk;
|
||||
ase_awk_runcbs_t* cbs;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#
|
||||
# OpenVMS MMS/MMK
|
||||
#
|
||||
|
||||
objects = awk.obj,err.obj,tree.obj,str.obj,tab.obj,map.obj,parse.obj,run.obj,rec.obj,val.obj,func.obj,misc.obj,extio.obj,rex.obj
|
||||
|
||||
CFLAGS = /include="../.."
|
||||
#CFLAGS = /pointer_size=long /include="../.."
|
||||
LIBRFLAGS =
|
||||
|
||||
aseawk.olb : $(objects)
|
||||
$(LIBR)/create $(MMS$TARGET) $(objects)
|
||||
# $(LIBR)/replace $(LIBRFLAGS) $(MMS$TARGET),$(objects)
|
||||
|
||||
awk.obj depends_on awk.c
|
||||
err.obj depends_on err.c
|
||||
tree.obj depends_on tree.c
|
||||
str.obj depends_on str.c
|
||||
tab.obj depends_on tab.c
|
||||
map.obj depends_on map.c
|
||||
parse.obj depends_on parse.c
|
||||
run.obj depends_on run.c
|
||||
rec.obj depends_on rec.c
|
||||
val.obj depends_on val.c
|
||||
func.obj depends_on func.c
|
||||
misc.obj depends_on misc.c
|
||||
extio.obj depends_on extio.c
|
||||
rex.obj depends_on rex.c
|
466
ase/awk/err.c
466
ase/awk/err.c
@ -1,466 +0,0 @@
|
||||
/*
|
||||
* $Id: err.c,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
static const ase_char_t* __geterrstr (int errnum)
|
||||
{
|
||||
static const ase_char_t* errstr[] =
|
||||
{
|
||||
ASE_T("no error"),
|
||||
|
||||
ASE_T("invalid parameter"),
|
||||
ASE_T("out of memory"),
|
||||
ASE_T("not supported"),
|
||||
ASE_T("operation not allowed"),
|
||||
ASE_T("no such device"),
|
||||
ASE_T("no space left on device"),
|
||||
ASE_T("too many open files"),
|
||||
ASE_T("too many links"),
|
||||
ASE_T("resource temporarily unavailable"),
|
||||
ASE_T("'%.*s' not existing"),
|
||||
ASE_T("'%.*s' already exists"),
|
||||
ASE_T("file or data too big"),
|
||||
ASE_T("system too busy"),
|
||||
ASE_T("is a directory"),
|
||||
ASE_T("i/o error"),
|
||||
|
||||
ASE_T("cannot open '%.*s'"),
|
||||
ASE_T("cannot read '%.*s'"),
|
||||
ASE_T("cannot write '%.*s'"),
|
||||
ASE_T("cannot close '%.*s'"),
|
||||
|
||||
ASE_T("internal error that should never have happened"),
|
||||
ASE_T("general run-time error"),
|
||||
ASE_T("block nested too deeply"),
|
||||
ASE_T("expressio nested too deeply"),
|
||||
|
||||
ASE_T("cannot open source input"),
|
||||
ASE_T("cannot close source input"),
|
||||
ASE_T("cannot read source input"),
|
||||
|
||||
ASE_T("cannot open source output"),
|
||||
ASE_T("cannot close source output"),
|
||||
ASE_T("cannot write source output"),
|
||||
|
||||
ASE_T("invalid character '%.*s'"),
|
||||
ASE_T("cannot unget character"),
|
||||
|
||||
ASE_T("unexpected end of source"),
|
||||
ASE_T("a comment not closed properly"),
|
||||
ASE_T("a string not closed with a quote"),
|
||||
ASE_T("unexpected end of a regular expression"),
|
||||
ASE_T("a left brace expected n place of '%.*s'"),
|
||||
ASE_T("a left parenthesis expected in place of '%.*s'"),
|
||||
ASE_T("a right parenthesis expected in place of '%.*s'"),
|
||||
ASE_T("a right bracket expected in place of '%.*s'"),
|
||||
ASE_T("a comma expected in place of '%.*s'"),
|
||||
ASE_T("a semicolon expected in place of '%.*s'"),
|
||||
ASE_T("a colon expected in place of '%.*s'"),
|
||||
ASE_T("statement not ending with a semicolon"),
|
||||
ASE_T("'in' expected in place of '%.*s'"),
|
||||
ASE_T("right-hand side of the 'in' operator not a variable"),
|
||||
ASE_T("invalid expression"),
|
||||
|
||||
ASE_T("keyword 'while' expected in place of '%.*s'"),
|
||||
ASE_T("invalid assignment statement"),
|
||||
ASE_T("an identifier expected in place of '%.*s'"),
|
||||
ASE_T("'%.*s' not a valid function name"),
|
||||
ASE_T("BEGIN not followed by a left bracket on the same line"),
|
||||
ASE_T("END not followed by a left bracket on the same line"),
|
||||
ASE_T("duplicate BEGIN"),
|
||||
ASE_T("duplicate END"),
|
||||
ASE_T("built-in function '%.*s' redefined"),
|
||||
ASE_T("function '%.*s' redefined"),
|
||||
ASE_T("global variable '%.*s' redefined"),
|
||||
ASE_T("parameter '%.*s' redefined"),
|
||||
ASE_T("duplicate parameter name '%.*s'"),
|
||||
ASE_T("duplicate global variable '%.*s'"),
|
||||
ASE_T("duplicate local variable '%.*s'"),
|
||||
ASE_T("'%.*s' not a valid parameter name"),
|
||||
ASE_T("'%.*s' not a valid variable name"),
|
||||
ASE_T("undefined identifier '%.*s'"),
|
||||
ASE_T("l-value required"),
|
||||
ASE_T("too many global variables"),
|
||||
ASE_T("too many local variables"),
|
||||
ASE_T("too many parameters"),
|
||||
ASE_T("delete statement not followed by a normal variable"),
|
||||
ASE_T("break statement outside a loop"),
|
||||
ASE_T("continue statement outside a loop"),
|
||||
ASE_T("next statement illegal in the BEGIN block"),
|
||||
ASE_T("next statement illegal in the END block"),
|
||||
ASE_T("nextfile statement illegal in the BEGIN block"),
|
||||
ASE_T("nextfile statement illegal in the END block"),
|
||||
ASE_T("printf not followed by any arguments"),
|
||||
ASE_T("both prefix and postfix increment/decrement operator present"),
|
||||
ASE_T("coprocess not supported by getline"),
|
||||
|
||||
ASE_T("divide by zero"),
|
||||
ASE_T("invalid operand"),
|
||||
ASE_T("wrong position index"),
|
||||
ASE_T("too few arguments"),
|
||||
ASE_T("too many arguments"),
|
||||
ASE_T("function '%.*s' not found"),
|
||||
ASE_T("variable not indexable"),
|
||||
ASE_T("variable '%.*s' not deletable"),
|
||||
ASE_T("value not a map"),
|
||||
ASE_T("right-hand side of the 'in' operator not a map"),
|
||||
ASE_T("right-hand side of the 'in' operator not a map nor nil"),
|
||||
ASE_T("value not referenceable"),
|
||||
ASE_T("value not assignable"),
|
||||
ASE_T("an indexed value cannot be assigned a map"),
|
||||
ASE_T("a positional value cannot be assigned a map"),
|
||||
ASE_T("map '%.*s' not assignable with a scalar"),
|
||||
ASE_T("cannot change a scalar value to a map"),
|
||||
ASE_T("a map is not allowed"),
|
||||
ASE_T("invalid value type"),
|
||||
ASE_T("delete statement called with a wrong target"),
|
||||
ASE_T("next statement called from the BEGIN block"),
|
||||
ASE_T("next statement called from the END block"),
|
||||
ASE_T("nextfile statement called from the BEGIN block"),
|
||||
ASE_T("nextfile statement called from the END block"),
|
||||
ASE_T("wrong implementation of built-in function handler"),
|
||||
ASE_T("built-in function handler returned an error"),
|
||||
ASE_T("wrong implementation of user-defined io handler"),
|
||||
ASE_T("no such io name found"),
|
||||
ASE_T("i/o handler returned an error"),
|
||||
ASE_T("i/o name empty"),
|
||||
ASE_T("i/o name containing a null character"),
|
||||
ASE_T("not sufficient arguments to formatting sequence"),
|
||||
ASE_T("recursion detected in format conversion"),
|
||||
ASE_T("invalid character in CONVFMT"),
|
||||
ASE_T("invalid character in OFMT"),
|
||||
|
||||
ASE_T("recursion too deep in the regular expression"),
|
||||
ASE_T("a right parenthesis expected in the regular expression"),
|
||||
ASE_T("a right bracket expected in the regular expression"),
|
||||
ASE_T("a right brace expected in the regular expression"),
|
||||
ASE_T("unbalanced parenthesis in the regular expression"),
|
||||
ASE_T("a colon expected in the regular expression"),
|
||||
ASE_T("invalid character range in the regular expression"),
|
||||
ASE_T("invalid character class in the regular expression"),
|
||||
ASE_T("invalid boundary range in the regular expression"),
|
||||
ASE_T("unexpected end of the regular expression"),
|
||||
ASE_T("garbage after the regular expression")
|
||||
};
|
||||
|
||||
if (errnum >= 0 && errnum < ASE_COUNTOF(errstr))
|
||||
{
|
||||
return errstr[errnum];
|
||||
}
|
||||
|
||||
return ASE_T("unknown error");
|
||||
}
|
||||
|
||||
const ase_char_t* ase_awk_geterrstr (ase_awk_t* awk, int num)
|
||||
{
|
||||
if (awk != ASE_NULL &&
|
||||
awk->errstr[num] != ASE_NULL) return awk->errstr[num];
|
||||
return __geterrstr (num);
|
||||
}
|
||||
|
||||
int ase_awk_seterrstr (ase_awk_t* awk, int num, const ase_char_t* str)
|
||||
{
|
||||
ase_char_t* dup;
|
||||
|
||||
if (str == ASE_NULL) dup = ASE_NULL;
|
||||
else
|
||||
{
|
||||
dup = ase_strdup (str, &awk->prmfns.mmgr);
|
||||
if (dup == ASE_NULL) return -1;
|
||||
}
|
||||
|
||||
if (awk->errstr[num] != ASE_NULL)
|
||||
ASE_AWK_FREE (awk, awk->errstr[num]);
|
||||
|
||||
else awk->errstr[num] = dup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ase_awk_geterrnum (ase_awk_t* awk)
|
||||
{
|
||||
return awk->errnum;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_geterrlin (ase_awk_t* awk)
|
||||
{
|
||||
return awk->errlin;
|
||||
}
|
||||
|
||||
const ase_char_t* ase_awk_geterrmsg (ase_awk_t* awk)
|
||||
{
|
||||
if (awk->errmsg[0] == ASE_T('\0'))
|
||||
return ase_awk_geterrstr (awk, awk->errnum);
|
||||
return awk->errmsg;
|
||||
}
|
||||
|
||||
void ase_awk_geterror (
|
||||
ase_awk_t* awk, int* errnum,
|
||||
ase_size_t* errlin, const ase_char_t** errmsg)
|
||||
{
|
||||
if (errnum != ASE_NULL) *errnum = awk->errnum;
|
||||
if (errlin != ASE_NULL) *errlin = awk->errlin;
|
||||
if (errmsg != ASE_NULL)
|
||||
{
|
||||
if (awk->errmsg[0] == ASE_T('\0'))
|
||||
*errmsg = ase_awk_geterrstr (awk, awk->errnum);
|
||||
else
|
||||
*errmsg = awk->errmsg;
|
||||
}
|
||||
}
|
||||
|
||||
void ase_awk_seterrnum (ase_awk_t* awk, int errnum)
|
||||
{
|
||||
awk->errnum = errnum;
|
||||
awk->errlin = 0;
|
||||
awk->errmsg[0] = ASE_T('\0');
|
||||
}
|
||||
|
||||
void ase_awk_seterror (
|
||||
ase_awk_t* awk, int errnum, ase_size_t errlin,
|
||||
const ase_cstr_t* errarg, ase_size_t argcnt)
|
||||
{
|
||||
const ase_char_t* errfmt;
|
||||
ase_size_t fmtlen;
|
||||
|
||||
ASE_ASSERT (argcnt <= 5);
|
||||
|
||||
awk->errnum = errnum;
|
||||
awk->errlin = errlin;
|
||||
|
||||
errfmt = ase_awk_geterrstr (awk, errnum);
|
||||
fmtlen = ase_strlen(errfmt);
|
||||
|
||||
switch (argcnt)
|
||||
{
|
||||
case 0:
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
{
|
||||
ase_char_t tmp[ASE_COUNTOF(awk->errmsg)];
|
||||
ase_size_t len, tl;
|
||||
|
||||
if (fmtlen < ASE_COUNTOF(awk->errmsg) &&
|
||||
errarg[0].len + fmtlen >= ASE_COUNTOF(awk->errmsg))
|
||||
{
|
||||
len = ASE_COUNTOF(awk->errmsg) - fmtlen - 3 - 1;
|
||||
tl = ase_strxncpy (tmp, ASE_COUNTOF(tmp), errarg[0].ptr, len);
|
||||
tmp[tl] = ASE_T('.');
|
||||
tmp[tl+1] = ASE_T('.');
|
||||
tmp[tl+2] = ASE_T('.');
|
||||
len += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = errarg[0].len;
|
||||
ase_strxncpy (tmp, ASE_COUNTOF(tmp), errarg[0].ptr, len);
|
||||
}
|
||||
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt, len, tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
case 2:
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr);
|
||||
return;
|
||||
|
||||
case 4:
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr,
|
||||
errarg[3].len, errarg[3].ptr);
|
||||
return;
|
||||
|
||||
case 5:
|
||||
awk->prmfns.misc.sprintf (
|
||||
awk->prmfns.misc.custom_data,
|
||||
awk->errmsg,
|
||||
ASE_COUNTOF(awk->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr,
|
||||
errarg[3].len, errarg[3].ptr,
|
||||
errarg[4].len, errarg[4].ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ase_awk_getrunerrnum (ase_awk_run_t* run)
|
||||
{
|
||||
return run->errnum;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_getrunerrlin (ase_awk_run_t* run)
|
||||
{
|
||||
return run->errlin;
|
||||
}
|
||||
|
||||
const ase_char_t* ase_awk_getrunerrmsg (ase_awk_run_t* run)
|
||||
{
|
||||
if (run->errmsg[0] == ASE_T('\0'))
|
||||
return ase_awk_geterrstr (run->awk, run->errnum);
|
||||
|
||||
return run->errmsg;
|
||||
}
|
||||
|
||||
void ase_awk_setrunerrnum (ase_awk_run_t* run, int errnum)
|
||||
{
|
||||
run->errnum = errnum;
|
||||
run->errlin = 0;
|
||||
run->errmsg[0] = ASE_T('\0');
|
||||
}
|
||||
|
||||
void ase_awk_getrunerror (
|
||||
ase_awk_run_t* run, int* errnum,
|
||||
ase_size_t* errlin, const ase_char_t** errmsg)
|
||||
{
|
||||
if (errnum != ASE_NULL) *errnum = run->errnum;
|
||||
if (errlin != ASE_NULL) *errlin = run->errlin;
|
||||
if (errmsg != ASE_NULL)
|
||||
{
|
||||
if (run->errmsg[0] == ASE_T('\0'))
|
||||
*errmsg = ase_awk_geterrstr (run->awk, run->errnum);
|
||||
else
|
||||
*errmsg = run->errmsg;
|
||||
}
|
||||
}
|
||||
|
||||
void ase_awk_setrunerror (
|
||||
ase_awk_run_t* run, int errnum, ase_size_t errlin,
|
||||
const ase_cstr_t* errarg, ase_size_t argcnt)
|
||||
{
|
||||
const ase_char_t* errfmt;
|
||||
ase_size_t fmtlen;
|
||||
|
||||
ASE_ASSERT (argcnt <= 5);
|
||||
|
||||
run->errnum = errnum;
|
||||
run->errlin = errlin;
|
||||
|
||||
errfmt = ase_awk_geterrstr (run->awk, errnum);
|
||||
fmtlen = ase_strlen (errfmt);
|
||||
|
||||
switch (argcnt)
|
||||
{
|
||||
case 0:
|
||||
/* TODO: convert % to %% if the original % is not
|
||||
* the first % of the %% sequence */
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
{
|
||||
ase_char_t tmp[ASE_COUNTOF(run->errmsg)];
|
||||
ase_size_t len, tl;
|
||||
|
||||
if (fmtlen < ASE_COUNTOF(run->errmsg) &&
|
||||
errarg[0].len + fmtlen >= ASE_COUNTOF(run->errmsg))
|
||||
{
|
||||
len = ASE_COUNTOF(run->errmsg) - fmtlen - 3 - 1;
|
||||
tl = ase_strxncpy (tmp, ASE_COUNTOF(tmp), errarg[0].ptr, len);
|
||||
tmp[tl] = ASE_T('.');
|
||||
tmp[tl+1] = ASE_T('.');
|
||||
tmp[tl+2] = ASE_T('.');
|
||||
len += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = errarg[0].len;
|
||||
ase_strxncpy (tmp, ASE_COUNTOF(tmp), errarg[0].ptr, len);
|
||||
}
|
||||
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt, len, tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
case 2:
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr);
|
||||
return;
|
||||
|
||||
case 4:
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr,
|
||||
errarg[3].len, errarg[3].ptr);
|
||||
return;
|
||||
|
||||
case 5:
|
||||
run->awk->prmfns.misc.sprintf (
|
||||
run->awk->prmfns.misc.custom_data,
|
||||
run->errmsg,
|
||||
ASE_COUNTOF(run->errmsg),
|
||||
errfmt,
|
||||
errarg[0].len, errarg[0].ptr,
|
||||
errarg[1].len, errarg[1].ptr,
|
||||
errarg[2].len, errarg[2].ptr,
|
||||
errarg[3].len, errarg[3].ptr,
|
||||
errarg[4].len, errarg[4].ptr);
|
||||
return;
|
||||
}
|
||||
}
|
951
ase/awk/extio.c
951
ase/awk/extio.c
@ -1,951 +0,0 @@
|
||||
/*
|
||||
* $Id: extio.c,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
enum
|
||||
{
|
||||
MASK_READ = 0x0100,
|
||||
MASK_WRITE = 0x0200,
|
||||
MASK_RDWR = 0x0400,
|
||||
|
||||
MASK_CLEAR = 0x00FF
|
||||
};
|
||||
|
||||
static int in_type_map[] =
|
||||
{
|
||||
/* the order should match the order of the
|
||||
* ASE_AWK_IN_XXX values in tree.h */
|
||||
ASE_AWK_EXTIO_PIPE,
|
||||
ASE_AWK_EXTIO_COPROC,
|
||||
ASE_AWK_EXTIO_FILE,
|
||||
ASE_AWK_EXTIO_CONSOLE
|
||||
};
|
||||
|
||||
static int in_mode_map[] =
|
||||
{
|
||||
/* the order should match the order of the
|
||||
* ASE_AWK_IN_XXX values in tree.h */
|
||||
ASE_AWK_EXTIO_PIPE_READ,
|
||||
0,
|
||||
ASE_AWK_EXTIO_FILE_READ,
|
||||
ASE_AWK_EXTIO_CONSOLE_READ
|
||||
};
|
||||
|
||||
static int in_mask_map[] =
|
||||
{
|
||||
MASK_READ,
|
||||
MASK_RDWR,
|
||||
MASK_READ,
|
||||
MASK_READ
|
||||
};
|
||||
|
||||
static int out_type_map[] =
|
||||
{
|
||||
/* the order should match the order of the
|
||||
* ASE_AWK_OUT_XXX values in tree.h */
|
||||
ASE_AWK_EXTIO_PIPE,
|
||||
ASE_AWK_EXTIO_COPROC,
|
||||
ASE_AWK_EXTIO_FILE,
|
||||
ASE_AWK_EXTIO_FILE,
|
||||
ASE_AWK_EXTIO_CONSOLE
|
||||
};
|
||||
|
||||
static int out_mode_map[] =
|
||||
{
|
||||
/* the order should match the order of the
|
||||
* ASE_AWK_OUT_XXX values in tree.h */
|
||||
ASE_AWK_EXTIO_PIPE_WRITE,
|
||||
0,
|
||||
ASE_AWK_EXTIO_FILE_WRITE,
|
||||
ASE_AWK_EXTIO_FILE_APPEND,
|
||||
ASE_AWK_EXTIO_CONSOLE_WRITE
|
||||
};
|
||||
|
||||
static int out_mask_map[] =
|
||||
{
|
||||
MASK_WRITE,
|
||||
MASK_RDWR,
|
||||
MASK_WRITE,
|
||||
MASK_WRITE,
|
||||
MASK_WRITE
|
||||
};
|
||||
|
||||
int ase_awk_readextio (
|
||||
ase_awk_run_t* run, int in_type,
|
||||
const ase_char_t* name, ase_str_t* buf)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, extio_mode, extio_mask, n, ret;
|
||||
ase_awk_val_t* rs;
|
||||
ase_char_t* rs_ptr;
|
||||
ase_size_t rs_len;
|
||||
ase_size_t line_len = 0;
|
||||
ase_char_t c = ASE_T('\0'), pc;
|
||||
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_type_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mode_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mask_map));
|
||||
|
||||
/* translate the in_type into the relevant extio type and mode */
|
||||
extio_type = in_type_map[in_type];
|
||||
extio_mode = in_mode_map[in_type];
|
||||
extio_mask = in_mask_map[in_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name,name) == 0) break;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
p = (ase_awk_extio_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_extio_t));
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->name = ase_strdup (name, &run->awk->prmfns.mmgr);
|
||||
if (p->name == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->run = run;
|
||||
p->type = (extio_type | extio_mask);
|
||||
p->mode = extio_mode;
|
||||
p->handle = ASE_NULL;
|
||||
p->next = ASE_NULL;
|
||||
p->custom_data = run->extio.custom_data;
|
||||
|
||||
p->in.buf[0] = ASE_T('\0');
|
||||
p->in.pos = 0;
|
||||
p->in.len = 0;
|
||||
p->in.eof = ase_false;
|
||||
p->in.eos = ase_false;
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
|
||||
n = handler (ASE_AWK_IO_OPEN, p, ASE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, p->name);
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
{
|
||||
/* if the error number has not been
|
||||
* set by the user handler */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* chain it */
|
||||
p->next = run->extio.chain;
|
||||
run->extio.chain = p;
|
||||
|
||||
/* usually, n == 0 indicates that it has reached the end
|
||||
* of the input. the user io handler can return 0 for the
|
||||
* open request if it doesn't have any files to open. One
|
||||
* advantage of doing this would be that you can skip the
|
||||
* entire pattern-block matching and exeuction. */
|
||||
if (n == 0)
|
||||
{
|
||||
p->in.eos = ase_true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->in.eos)
|
||||
{
|
||||
/* no more streams. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ready to read a line */
|
||||
ase_str_clear (buf);
|
||||
|
||||
/* get the record separator */
|
||||
rs = ase_awk_getglobal (run, ASE_AWK_GLOBAL_RS);
|
||||
ase_awk_refupval (run, rs);
|
||||
|
||||
if (rs->type == ASE_AWK_VAL_NIL)
|
||||
{
|
||||
rs_ptr = ASE_NULL;
|
||||
rs_len = 0;
|
||||
}
|
||||
else if (rs->type == ASE_AWK_VAL_STR)
|
||||
{
|
||||
rs_ptr = ((ase_awk_val_str_t*)rs)->buf;
|
||||
rs_len = ((ase_awk_val_str_t*)rs)->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs_ptr = ase_awk_valtostr (
|
||||
run, rs, ASE_AWK_VALTOSTR_CLEAR, ASE_NULL, &rs_len);
|
||||
if (rs_ptr == ASE_NULL)
|
||||
{
|
||||
ase_awk_refdownval (run, rs);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
/* call the io handler */
|
||||
while (1)
|
||||
{
|
||||
if (p->in.pos >= p->in.len)
|
||||
{
|
||||
ase_ssize_t n;
|
||||
|
||||
if (p->in.eof)
|
||||
{
|
||||
if (ASE_STR_LEN(buf) == 0) ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
|
||||
n = handler (ASE_AWK_IO_READ,
|
||||
p, p->in.buf, ASE_COUNTOF(p->in.buf));
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
{
|
||||
/* if the error number has not been
|
||||
* set by the user handler */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
}
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
p->in.eof = ase_true;
|
||||
if (ASE_STR_LEN(buf) == 0) ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
p->in.len = n;
|
||||
p->in.pos = 0;
|
||||
}
|
||||
|
||||
pc = c;
|
||||
c = p->in.buf[p->in.pos++];
|
||||
|
||||
if (rs_ptr == ASE_NULL)
|
||||
{
|
||||
/* separate by a new line */
|
||||
if (c == ASE_T('\n'))
|
||||
{
|
||||
if (pc == ASE_T('\r') &&
|
||||
ASE_STR_LEN(buf) > 0)
|
||||
{
|
||||
ASE_STR_LEN(buf) -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (rs_len == 0)
|
||||
{
|
||||
/* separate by a blank line */
|
||||
if (c == ASE_T('\n'))
|
||||
{
|
||||
if (pc == ASE_T('\r') &&
|
||||
ASE_STR_LEN(buf) > 0)
|
||||
{
|
||||
ASE_STR_LEN(buf) -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (line_len == 0 && c == ASE_T('\n'))
|
||||
{
|
||||
if (ASE_STR_LEN(buf) <= 0)
|
||||
{
|
||||
/* if the record is empty when a blank
|
||||
* line is encountered, the line
|
||||
* terminator should not be added to
|
||||
* the record */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* when a blank line is encountered,
|
||||
* it needs to snip off the line
|
||||
* terminator of the previous line */
|
||||
ASE_STR_LEN(buf) -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (rs_len == 1)
|
||||
{
|
||||
if (c == rs_ptr[0]) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const ase_char_t* match_ptr;
|
||||
ase_size_t match_len;
|
||||
|
||||
ASE_ASSERT (run->global.rs != ASE_NULL);
|
||||
|
||||
n = ase_awk_matchrex (
|
||||
run->awk, run->global.rs,
|
||||
((run->global.ignorecase)? ASE_AWK_REX_IGNORECASE: 0),
|
||||
ASE_STR_BUF(buf), ASE_STR_LEN(buf),
|
||||
&match_ptr, &match_len, &run->errnum);
|
||||
if (n == -1)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == 1)
|
||||
{
|
||||
/* the match should be found at the end of
|
||||
* the current buffer */
|
||||
ASE_ASSERT (
|
||||
ASE_STR_BUF(buf) + ASE_STR_LEN(buf) ==
|
||||
match_ptr + match_len);
|
||||
|
||||
ASE_STR_LEN(buf) -= match_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ase_str_ccat (buf, c) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: handle different line terminator like \r\n */
|
||||
if (c == ASE_T('\n')) line_len = 0;
|
||||
else line_len = line_len + 1;
|
||||
}
|
||||
|
||||
if (rs_ptr != ASE_NULL &&
|
||||
rs->type != ASE_AWK_VAL_STR) ASE_AWK_FREE (run->awk, rs_ptr);
|
||||
ase_awk_refdownval (run, rs);
|
||||
|
||||
/* increment NR */
|
||||
if (ret != -1 && ret != 0)
|
||||
{
|
||||
ase_awk_val_t* nr;
|
||||
ase_long_t lv;
|
||||
ase_real_t rv;
|
||||
|
||||
nr = ase_awk_getglobal (run, ASE_AWK_GLOBAL_NR);
|
||||
ase_awk_refupval (run, nr);
|
||||
n = ase_awk_valtonum (run, nr, &lv, &rv);
|
||||
ase_awk_refdownval (run, nr);
|
||||
|
||||
if (n == -1) ret = -1;
|
||||
else
|
||||
{
|
||||
if (n == 1) lv = (ase_long_t)rv;
|
||||
|
||||
nr = ase_awk_makeintval (run, lv + 1);
|
||||
if (nr == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ase_awk_setglobal (
|
||||
run, ASE_AWK_GLOBAL_NR, nr) == -1) ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ase_awk_writeextio_val (
|
||||
ase_awk_run_t* run, int out_type,
|
||||
const ase_char_t* name, ase_awk_val_t* v)
|
||||
{
|
||||
ase_char_t* str;
|
||||
ase_size_t len;
|
||||
int n;
|
||||
|
||||
if (v->type == ASE_AWK_VAL_STR)
|
||||
{
|
||||
str = ((ase_awk_val_str_t*)v)->buf;
|
||||
len = ((ase_awk_val_str_t*)v)->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = ase_awk_valtostr (
|
||||
run, v,
|
||||
ASE_AWK_VALTOSTR_CLEAR | ASE_AWK_VALTOSTR_PRINT,
|
||||
ASE_NULL, &len);
|
||||
if (str == ASE_NULL) return -1;
|
||||
}
|
||||
|
||||
n = ase_awk_writeextio_str (run, out_type, name, str, len);
|
||||
|
||||
if (v->type != ASE_AWK_VAL_STR) ASE_AWK_FREE (run->awk, str);
|
||||
return n;
|
||||
}
|
||||
|
||||
int ase_awk_writeextio_str (
|
||||
ase_awk_run_t* run, int out_type,
|
||||
const ase_char_t* name, ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, extio_mode, extio_mask, n;
|
||||
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_type_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mode_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mask_map));
|
||||
|
||||
/* translate the out_type into the relevant extio type and mode */
|
||||
extio_type = out_type_map[out_type];
|
||||
extio_mode = out_mode_map[out_type];
|
||||
extio_mask = out_mask_map[out_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look for the corresponding extio for name */
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
/* the file "1.tmp", in the following code snippets,
|
||||
* would be opened by the first print statement, but not by
|
||||
* the second print statement. this is because
|
||||
* both ASE_AWK_OUT_FILE and ASE_AWK_OUT_FILE_APPEND are
|
||||
* translated to ASE_AWK_EXTIO_FILE and it is used to
|
||||
* keep track of file handles..
|
||||
*
|
||||
* print "1111" >> "1.tmp"
|
||||
* print "1111" > "1.tmp"
|
||||
*/
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name, name) == 0) break;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* if there is not corresponding extio for name, create one */
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
p = (ase_awk_extio_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_extio_t));
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->name = ase_strdup (name, &run->awk->prmfns.mmgr);
|
||||
if (p->name == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->run = run;
|
||||
p->type = (extio_type | extio_mask);
|
||||
p->mode = extio_mode;
|
||||
p->handle = ASE_NULL;
|
||||
p->next = ASE_NULL;
|
||||
p->custom_data = run->extio.custom_data;
|
||||
|
||||
p->out.eof = ase_false;
|
||||
p->out.eos = ase_false;
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_OPEN, p, ASE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, p->name);
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* chain it */
|
||||
p->next = run->extio.chain;
|
||||
run->extio.chain = p;
|
||||
|
||||
/* usually, n == 0 indicates that it has reached the end
|
||||
* of the input. the user io handler can return 0 for the
|
||||
* open request if it doesn't have any files to open. One
|
||||
* advantage of doing this would be that you can skip the
|
||||
* entire pattern-block matching and exeuction. */
|
||||
if (n == 0)
|
||||
{
|
||||
p->out.eos = ase_true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->out.eos)
|
||||
{
|
||||
/* no more streams */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p->out.eof)
|
||||
{
|
||||
/* it has reached the end of the stream but this function
|
||||
* has been recalled */
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_WRITE, p, str, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
p->out.eof = ase_true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
len -= n;
|
||||
str += n;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ase_awk_flushextio (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, /*extio_mode,*/ extio_mask, n;
|
||||
ase_bool_t ok = ase_false;
|
||||
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_type_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mode_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mask_map));
|
||||
|
||||
/* translate the out_type into the relevant extio type and mode */
|
||||
extio_type = out_type_map[out_type];
|
||||
/*extio_mode = out_mode_map[out_type];*/
|
||||
extio_mask = out_mask_map[out_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look for the corresponding extio for name */
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
(name == ASE_NULL || ase_strcmp(p->name,name) == 0))
|
||||
{
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_FLUSH, p, ASE_NULL, 0);
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ok = ase_true;
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (ok) return 0;
|
||||
|
||||
/* there is no corresponding extio for name */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIONONE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ase_awk_nextextio_read (
|
||||
ase_awk_run_t* run, int in_type, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, /*extio_mode,*/ extio_mask, n;
|
||||
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_type_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mode_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mask_map));
|
||||
|
||||
/* translate the in_type into the relevant extio type and mode */
|
||||
extio_type = in_type_map[in_type];
|
||||
/*extio_mode = in_mode_map[in_type];*/
|
||||
extio_mask = in_mask_map[in_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name,name) == 0) break;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
/* something is totally wrong */
|
||||
ASE_ASSERT (
|
||||
!"should never happen - cannot find the relevant extio entry");
|
||||
ase_awk_setrunerror (run, ASE_AWK_EINTERN, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p->in.eos)
|
||||
{
|
||||
/* no more streams. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_NEXT, p, ASE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* the next stream cannot be opened.
|
||||
* set the eos flags so that the next call to nextextio_read
|
||||
* will return 0 without executing the handler */
|
||||
p->in.eos = ase_true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* as the next stream has been opened successfully,
|
||||
* the eof flag should be cleared if set */
|
||||
p->in.eof = ase_false;
|
||||
|
||||
/* also the previous input buffer must be reset */
|
||||
p->in.pos = 0;
|
||||
p->in.len = 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int ase_awk_nextextio_write (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, /*extio_mode,*/ extio_mask, n;
|
||||
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_type_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mode_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mask_map));
|
||||
|
||||
/* translate the out_type into the relevant extio type and mode */
|
||||
extio_type = out_type_map[out_type];
|
||||
/*extio_mode = out_mode_map[out_type];*/
|
||||
extio_mask = out_mask_map[out_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name,name) == 0) break;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (p == ASE_NULL)
|
||||
{
|
||||
/* something is totally wrong */
|
||||
ASE_ASSERT (!"should never happen - cannot find the relevant extio entry");
|
||||
|
||||
ase_awk_setrunerror (run, ASE_AWK_EINTERN, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p->out.eos)
|
||||
{
|
||||
/* no more streams. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_NEXT, p, ASE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* the next stream cannot be opened.
|
||||
* set the eos flags so that the next call to nextextio_write
|
||||
* will return 0 without executing the handler */
|
||||
p->out.eos = ase_true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* as the next stream has been opened successfully,
|
||||
* the eof flag should be cleared if set */
|
||||
p->out.eof = ase_false;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int ase_awk_closeextio_read (
|
||||
ase_awk_run_t* run, int in_type, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain, * px = ASE_NULL;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, /*extio_mode,*/ extio_mask;
|
||||
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_type_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mode_map));
|
||||
ASE_ASSERT (in_type >= 0 && in_type <= ASE_COUNTOF(in_mask_map));
|
||||
|
||||
/* translate the in_type into the relevant extio type and mode */
|
||||
extio_type = in_type_map[in_type];
|
||||
/*extio_mode = in_mode_map[in_type];*/
|
||||
extio_mask = in_mask_map[in_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOUSER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name, name) == 0)
|
||||
{
|
||||
ase_awk_io_t handler;
|
||||
|
||||
handler = run->extio.handler[p->type & MASK_CLEAR];
|
||||
if (handler != ASE_NULL)
|
||||
{
|
||||
if (handler (ASE_AWK_IO_CLOSE, p, ASE_NULL, 0) <= -1)
|
||||
{
|
||||
/* this is not a run-time error.*/
|
||||
ase_awk_setrunerror (run, ASE_AWK_EIOIMPL, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (px != ASE_NULL) px->next = p->next;
|
||||
else run->extio.chain = p->next;
|
||||
|
||||
ASE_AWK_FREE (run->awk, p->name);
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
px = p;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* the name given is not found */
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIONONE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ase_awk_closeextio_write (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain, * px = ASE_NULL;
|
||||
ase_awk_io_t handler;
|
||||
int extio_type, /*extio_mode,*/ extio_mask;
|
||||
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_type_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mode_map));
|
||||
ASE_ASSERT (out_type >= 0 && out_type <= ASE_COUNTOF(out_mask_map));
|
||||
|
||||
/* translate the out_type into the relevant extio type and mode */
|
||||
extio_type = out_type_map[out_type];
|
||||
/*extio_mode = out_mode_map[out_type];*/
|
||||
extio_mask = out_mask_map[out_type];
|
||||
|
||||
handler = run->extio.handler[extio_type];
|
||||
if (handler == ASE_NULL)
|
||||
{
|
||||
/* no io handler provided */
|
||||
ase_awk_setrunerror (run, ASE_AWK_EIOUSER, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (p->type == (extio_type | extio_mask) &&
|
||||
ase_strcmp (p->name, name) == 0)
|
||||
{
|
||||
ase_awk_io_t handler;
|
||||
|
||||
handler = run->extio.handler[p->type & MASK_CLEAR];
|
||||
if (handler != ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
if (handler (ASE_AWK_IO_CLOSE, p, ASE_NULL, 0) <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (px != ASE_NULL) px->next = p->next;
|
||||
else run->extio.chain = p->next;
|
||||
|
||||
ASE_AWK_FREE (run->awk, p->name);
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
px = p;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIONONE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ase_awk_closeextio (ase_awk_run_t* run, const ase_char_t* name)
|
||||
{
|
||||
ase_awk_extio_t* p = run->extio.chain, * px = ASE_NULL;
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
/* it handles the first that matches the given name
|
||||
* regardless of the extio type */
|
||||
if (ase_strcmp (p->name, name) == 0)
|
||||
{
|
||||
ase_awk_io_t handler;
|
||||
|
||||
handler = run->extio.handler[p->type & MASK_CLEAR];
|
||||
if (handler != ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
if (handler (ASE_AWK_IO_CLOSE, p, ASE_NULL, 0) <= -1)
|
||||
{
|
||||
/* this is not a run-time error.*/
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (px != ASE_NULL) px->next = p->next;
|
||||
else run->extio.chain = p->next;
|
||||
|
||||
ASE_AWK_FREE (run->awk, p->name);
|
||||
ASE_AWK_FREE (run->awk, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
px = p;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIONONE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ase_awk_clearextio (ase_awk_run_t* run)
|
||||
{
|
||||
ase_awk_extio_t* next;
|
||||
ase_awk_io_t handler;
|
||||
int n;
|
||||
|
||||
while (run->extio.chain != ASE_NULL)
|
||||
{
|
||||
handler = run->extio.handler[
|
||||
run->extio.chain->type & MASK_CLEAR];
|
||||
next = run->extio.chain->next;
|
||||
|
||||
if (handler != ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_ENOERR);
|
||||
n = handler (ASE_AWK_IO_CLOSE, run->extio.chain, ASE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (run->errnum == ASE_AWK_ENOERR)
|
||||
ase_awk_setrunerrnum (run, ASE_AWK_EIOIMPL);
|
||||
/* TODO: some warnings need to be shown??? */
|
||||
}
|
||||
}
|
||||
|
||||
ASE_AWK_FREE (run->awk, run->extio.chain->name);
|
||||
ASE_AWK_FREE (run->awk, run->extio.chain);
|
||||
|
||||
run->extio.chain = next;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* $Id: extio.h,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_EXTIO_H_
|
||||
#define _ASE_AWK_EXTIO_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
|
||||
int ase_awk_readextio (
|
||||
ase_awk_run_t* run, int in_type,
|
||||
const ase_char_t* name, ase_str_t* buf);
|
||||
|
||||
int ase_awk_writeextio_val (
|
||||
ase_awk_run_t* run, int out_type,
|
||||
const ase_char_t* name, ase_awk_val_t* v);
|
||||
|
||||
int ase_awk_writeextio_str (
|
||||
ase_awk_run_t* run, int out_type,
|
||||
const ase_char_t* name, ase_char_t* str, ase_size_t len);
|
||||
|
||||
int ase_awk_flushextio (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name);
|
||||
|
||||
int ase_awk_nextextio_read (
|
||||
ase_awk_run_t* run, int in_type, const ase_char_t* name);
|
||||
|
||||
int ase_awk_nextextio_write (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name);
|
||||
|
||||
int ase_awk_closeextio_read (
|
||||
ase_awk_run_t* run, int in_type, const ase_char_t* name);
|
||||
int ase_awk_closeextio_write (
|
||||
ase_awk_run_t* run, int out_type, const ase_char_t* name);
|
||||
int ase_awk_closeextio (ase_awk_run_t* run, const ase_char_t* name);
|
||||
|
||||
void ase_awk_clearextio (ase_awk_run_t* run);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1364
ase/awk/func.c
1364
ase/awk/func.c
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* $Id: func.h,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_FUNC_H_
|
||||
#define _ASE_AWK_FUNC_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
typedef struct ase_awk_bfn_t ase_awk_bfn_t;
|
||||
|
||||
struct ase_awk_bfn_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} name;
|
||||
|
||||
int valid; /* the entry is valid when this option is set */
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t min;
|
||||
ase_size_t max;
|
||||
ase_char_t* spec;
|
||||
} arg;
|
||||
|
||||
int (*handler) (ase_awk_run_t*, const ase_char_t*, ase_size_t);
|
||||
|
||||
ase_awk_bfn_t* next;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_awk_bfn_t* ase_awk_getbfn (
|
||||
ase_awk_t* awk, const ase_char_t* name, ase_size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
2346
ase/awk/jni.c
2346
ase/awk/jni.c
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
||||
LIBRARY "aseawk_jni.dll"
|
||||
|
||||
EXPORTS
|
||||
Java_ase_awk_Awk_open
|
||||
Java_ase_awk_Awk_close
|
||||
Java_ase_awk_Awk_parse
|
||||
Java_ase_awk_Awk_run
|
||||
|
||||
Java_ase_awk_Awk_getmaxdepth
|
||||
Java_ase_awk_Awk_setmaxdepth
|
||||
|
||||
Java_ase_awk_Awk_getoption
|
||||
Java_ase_awk_Awk_setoption
|
||||
|
||||
Java_ase_awk_Awk_getdebug
|
||||
Java_ase_awk_Awk_setdebug
|
||||
|
||||
Java_ase_awk_Awk_addbfn
|
||||
Java_ase_awk_Awk_delbfn
|
||||
Java_ase_awk_Awk_setfilename
|
||||
Java_ase_awk_Awk_setofilename
|
||||
Java_ase_awk_Awk_strtonum
|
||||
Java_ase_awk_Awk_valtostr
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* $Id: jni.h,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_JNI_H_
|
||||
#define _ASE_AWK_JNI_H_
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#include <JavaVM/jni.h>
|
||||
#else
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj);
|
||||
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, jstring mfn, jobjectArray args);
|
||||
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn (
|
||||
JNIEnv* env, jobject obj, jstring name, jint min_args, jint max_args);
|
||||
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_getoption (
|
||||
JNIEnv* env, jobject obj);
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_setoption (
|
||||
JNIEnv* env, jobject obj, jint options);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_ase_awk_Awk_getdebug (
|
||||
JNIEnv* env, jobject obj);
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_setdebug (
|
||||
JNIEnv* env, jobject obj, jboolean debug);
|
||||
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_setfilename (
|
||||
JNIEnv* env, jobject obj, jlong runid, jstring name);
|
||||
JNIEXPORT void JNICALL Java_ase_awk_Awk_setofilename (
|
||||
JNIEnv* env, jobject obj, jlong runid, jstring name);
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_ase_awk_Awk_strtonum (
|
||||
JNIEnv* env, jobject obj, jlong runid, jstring str);
|
||||
JNIEXPORT jstring JNICALL Java_ase_awk_Awk_valtostr (
|
||||
JNIEnv* env, jobject obj, jlong runid, jobject val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,89 +0,0 @@
|
||||
#
|
||||
# $Id: makefile.in,v 1.1.1.1 2007/03/28 14:05:15 bacon Exp $
|
||||
#
|
||||
|
||||
NAME = aseawk
|
||||
|
||||
CC = @CC@
|
||||
AR = ar
|
||||
MAKE = @MAKE@
|
||||
RANLIB = @RANLIB@
|
||||
CFLAGS = @CFLAGS@ -I@abs_top_builddir@/..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
MODE = @BUILDMODE@
|
||||
|
||||
OUT_DIR = ../$(MODE)/lib
|
||||
OUT_FILE = $(OUT_DIR)/lib$(NAME).a
|
||||
|
||||
TMP_DIR = $(MODE)
|
||||
|
||||
OBJ_FILES = \
|
||||
$(TMP_DIR)/awk.o \
|
||||
$(TMP_DIR)/err.o \
|
||||
$(TMP_DIR)/tree.o \
|
||||
$(TMP_DIR)/tab.o \
|
||||
$(TMP_DIR)/map.o \
|
||||
$(TMP_DIR)/parse.o \
|
||||
$(TMP_DIR)/run.o \
|
||||
$(TMP_DIR)/rec.o \
|
||||
$(TMP_DIR)/val.o \
|
||||
$(TMP_DIR)/func.o \
|
||||
$(TMP_DIR)/misc.o \
|
||||
$(TMP_DIR)/extio.o \
|
||||
$(TMP_DIR)/rex.o
|
||||
|
||||
lib: $(OUT_FILE)
|
||||
|
||||
$(OUT_FILE): $(OBJ_FILES) $(OUT_DIR)
|
||||
$(AR) cr $(OUT_FILE) $(OBJ_FILES)
|
||||
if [ "$(RANLIB)" = "ranlib" ]; then ranlib $(OUT_FILE); fi
|
||||
|
||||
$(TMP_DIR)/awk.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c awk.c
|
||||
|
||||
$(TMP_DIR)/err.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c err.c
|
||||
|
||||
$(TMP_DIR)/tree.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c tree.c
|
||||
|
||||
$(TMP_DIR)/tab.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c tab.c
|
||||
|
||||
$(TMP_DIR)/map.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c map.c
|
||||
|
||||
$(TMP_DIR)/parse.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c parse.c
|
||||
|
||||
$(TMP_DIR)/run.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c run.c
|
||||
|
||||
$(TMP_DIR)/rec.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c rec.c
|
||||
|
||||
$(TMP_DIR)/val.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c val.c
|
||||
|
||||
$(TMP_DIR)/func.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c func.c
|
||||
|
||||
$(TMP_DIR)/misc.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c misc.c
|
||||
|
||||
$(TMP_DIR)/extio.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c extio.c
|
||||
|
||||
$(TMP_DIR)/rex.o: $(TMP_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ -c rex.c
|
||||
|
||||
$(OUT_DIR):
|
||||
mkdir -p $(OUT_DIR)
|
||||
|
||||
$(TMP_DIR):
|
||||
mkdir -p $(TMP_DIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(OUT_FILE) $(OBJ_FILES)
|
||||
|
@ -1,47 +0,0 @@
|
||||
OUT = aseawk
|
||||
|
||||
C_SRCS = awk.c err.c tree.c str.c tab.c map.c parse.c \
|
||||
run.c rec.c val.c func.c misc.c extio.c rex.c
|
||||
JNI_SRCS = jni.c
|
||||
JAVA_SRCS = Exception.java Extio.java Awk.java StdAwk.java
|
||||
|
||||
C_OBJS = $(C_SRCS:.c=.o)
|
||||
JNI_OBJS = $(JNI_SRCS:.c=.o)
|
||||
JAVA_OBJS = $(JAVA_SRCS:.java=.class)
|
||||
|
||||
JNI_INCPATH= \
|
||||
-I"$(JAVA_HOME)/include" \
|
||||
-I"$(JAVA_HOME)/include/linux"
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
LD = ld
|
||||
RANLIB = ranlib
|
||||
CFLAGS = -Wall -O2 -D_REENTRANT -D_THREAD_SAFE -fPIC -I../.. $(JNI_INCPATH)
|
||||
LDFLAGS =
|
||||
LIBS =
|
||||
|
||||
JAVAC = javac
|
||||
JAVACFLAGS = -classpath ../..
|
||||
|
||||
all: lib jni
|
||||
|
||||
lib: $(C_OBJS)
|
||||
$(AR) cr lib$(OUT).a $(C_OBJS)
|
||||
|
||||
jni: lib $(JNI_OBJS) $(JAVA_OBJS)
|
||||
$(CC) -shared -o $(OUT)_jni.so $(JNI_OBJS) -lm -L. -l$(OUT)
|
||||
|
||||
#$(CC) -fPIC -shared -static-libgcc -o $(OUT)_jni.so -L. -laseawk -lm libaseawk.a jni.o
|
||||
#$(LD) -fPIC -shared -soname lib$(OUT).so -o $(OUT)_jni.so -L . -l aseawk jni.o
|
||||
|
||||
clean:
|
||||
rm -rf $(C_OBJS) $(JNI_OBJS) $(JAVA_OBJS) lib$(OUT).a lib$(OUT).so *.o
|
||||
|
||||
.SUFFIXES: .c .o .java .class
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.java.class:
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
||||
|
@ -1,41 +0,0 @@
|
||||
OUT = aseawk
|
||||
|
||||
C_SRCS = awk.c err.c tree.c str.c tab.c map.c parse.c \
|
||||
run.c rec.c val.c func.c misc.c extio.c rex.c
|
||||
JNI_SRCS = jni.c
|
||||
JAVA_SRCS = Exception.java Extio.java Awk.java StdAwk.java
|
||||
|
||||
C_OBJS = $(C_SRCS:.c=.o)
|
||||
JNI_OBJS = $(JNI_SRCS:.c=.o)
|
||||
JAVA_OBJS = $(JAVA_SRCS:.java=.class)
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
LD = ld
|
||||
RANLIB = ranlib
|
||||
CFLAGS = -Wall -O2 -D_REENTRANT -D_THREAD_SAFE -I../..
|
||||
LDFLAGS =
|
||||
LIBS =
|
||||
|
||||
JAVAC = javac
|
||||
JAVACFLAGS = -classpath ../..
|
||||
|
||||
all: lib jni
|
||||
|
||||
lib: $(C_OBJS)
|
||||
$(AR) cr lib$(OUT).a $(C_OBJS)
|
||||
ranlib lib$(OUT).a
|
||||
|
||||
jni: lib $(JNI_OBJS) $(JAVA_OBJS)
|
||||
$(CC) -bundle -o $(OUT)_jni.so $(JNI_OBJS) -lm -L. -l$(OUT)
|
||||
|
||||
clean:
|
||||
rm -rf $(C_OBJS) $(JNI_OBJS) $(JAVA_OBJS) lib$(OUT).a lib$(OUT).so *.o
|
||||
|
||||
.SUFFIXES: .c .o .java .class
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.java.class:
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
||||
|
@ -1,54 +0,0 @@
|
||||
OUT = aseawk
|
||||
|
||||
C_SRCS = awk.c err.c tree.c tab.c map.c parse.c \
|
||||
run.c rec.c val.c func.c misc.c extio.c rex.c
|
||||
JNI_SRCS = jni.c
|
||||
JAVA_SRCS = Exception.java Extio.java Awk.java StdAwk.java
|
||||
|
||||
C_OBJS = $(C_SRCS:.c=.obj)
|
||||
JNI_OBJS = $(JNI_SRCS:.c=.obj)
|
||||
JAVA_OBJS = $(JAVA_SRCS:.java=.class)
|
||||
|
||||
JNI_INCPATH = \
|
||||
-I"$(JAVA_HOME)/include" \
|
||||
-I"$(JAVA_HOME)/include/win32"
|
||||
|
||||
CC = bcc32
|
||||
LD = ilink32
|
||||
AR = tlib
|
||||
JAVAC = javac
|
||||
|
||||
CFLAGS_COMMON = -O2 -WM -WU -RT- -w -q -I../.. $(JNI_INCPATH)
|
||||
CFLAGS_RELEASE = $(CFLAGS_COMMON) -DNDEBUG
|
||||
CFLAGS_DEBUG = $(CFLAGS_COMMON) -D_DEBUG #-DDEBUG_REX
|
||||
CFLAGS = $(CFLAGS_DEBUG)
|
||||
#CFLAGS = $(CFLAGS_RELEASE)
|
||||
JAVACFLAGS = -classpath ../..
|
||||
|
||||
LDFLAGS = -Tpd -ap -Gn -c -q
|
||||
STARTUP = c0d32w.obj
|
||||
LIBS = import32.lib cw32mt.lib
|
||||
|
||||
JNI_LDFLAGS = $(LDFLAGS) -L..\cmn -L..\utl
|
||||
JNI_LIBS = $(LIBS) $(OUT).lib asecmn.lib aseutl.lib
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(C_OBJS)
|
||||
$(AR) $(OUT).lib @&&!
|
||||
+-$(**: = &^
|
||||
+-)
|
||||
!
|
||||
|
||||
jni: lib $(JNI_OBJS) $(JAVA_OBJS)
|
||||
$(LD) $(JNI_LDFLAGS) $(STARTUP) $(JNI_OBJS),$(OUT)_jni.dll,,$(JNI_LIBS),jni.def,
|
||||
|
||||
clean:
|
||||
-del $(OBJS) $(OUT).lib $(OUT)_jni.dll *.obj *.class
|
||||
|
||||
.SUFFIXES: .c .obj .java .class
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.java.class:
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
@ -1,45 +0,0 @@
|
||||
OUT = aseawk
|
||||
|
||||
C_SRCS = awk.c err.c tree.c tab.c map.c parse.c \
|
||||
run.c rec.c val.c func.c misc.c extio.c rex.c
|
||||
JNI_SRCS = jni.c
|
||||
JAVA_SRCS = Exception.java Extio.java Awk.java StdAwk.java
|
||||
|
||||
C_OBJS = $(C_SRCS:.c=.obj)
|
||||
JNI_OBJS = $(JNI_SRCS:.c=.obj)
|
||||
JAVA_OBJS = $(JAVA_SRCS:.java=.class)
|
||||
|
||||
JNI_INC = \
|
||||
/I"$(JAVA_HOME)/include" \
|
||||
/I"$(JAVA_HOME)/include\win32"
|
||||
|
||||
CC = cl
|
||||
LD = link
|
||||
JAVAC = javac
|
||||
|
||||
#CFLAGS = /nologo /O2 /MT /W3 /GR- /Za -I../.. $(JNI_INC)
|
||||
CFLAGS = /nologo /O2 /MT /W3 /GR- -I../.. $(JNI_INC)
|
||||
JAVACFLAGS = -classpath ../.. -Xlint:unchecked
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(C_OBJS)
|
||||
$(LD) /lib @<<
|
||||
/nologo /out:$(OUT).lib $(C_OBJS)
|
||||
<<
|
||||
|
||||
jni: lib $(JNI_OBJS) $(JAVA_OBJS)
|
||||
$(LD) /dll /def:jni.def /subsystem:windows /version:0.1 /release @<<
|
||||
/nologo /out:$(OUT)_jni.dll $(JNI_OBJS) /libpath:../cmn /libpath:../utl /implib:tmp.lib user32.lib $(OUT).lib asecmn.lib aseutl.lib
|
||||
<<
|
||||
del tmp.lib tmp.exp
|
||||
|
||||
clean:
|
||||
del $(OBJS) $(OUT).lib $(OUT)_jni.dll *.obj *.class
|
||||
|
||||
.SUFFIXES: .c .obj .java .class
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
.java.class:
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
285
ase/awk/map.c
285
ase/awk/map.c
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* $Id: map.c,v 1.1.1.1 2007/03/28 14:05:16 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
/* TODO: improve the entire map routines.
|
||||
support automatic bucket resizing and remaping, etc. */
|
||||
|
||||
static ase_size_t hash (const ase_char_t* key, ase_size_t key_len);
|
||||
|
||||
#define FREE_PAIR(map,pair) \
|
||||
do { \
|
||||
ASE_AWK_FREE ((map)->awk, (ase_char_t*)(pair)->key); \
|
||||
if ((map)->freeval != ASE_NULL) \
|
||||
(map)->freeval ((map)->owner, (pair)->val); \
|
||||
ASE_AWK_FREE ((map)->awk, pair); \
|
||||
} while (0)
|
||||
|
||||
ase_awk_map_t* ase_awk_map_open (
|
||||
ase_awk_map_t* map, void* owner, ase_size_t capa,
|
||||
void(*freeval)(void*,void*), ase_awk_t* awk)
|
||||
{
|
||||
ASE_ASSERTX (capa > 0, "the initial capacity should be greater than 0");
|
||||
|
||||
if (map == ASE_NULL)
|
||||
{
|
||||
map = (ase_awk_map_t*) ASE_AWK_MALLOC (
|
||||
awk, ASE_SIZEOF(ase_awk_map_t));
|
||||
if (map == ASE_NULL) return ASE_NULL;
|
||||
map->__dynamic = ase_true;
|
||||
}
|
||||
else map->__dynamic = ase_false;
|
||||
|
||||
map->awk = awk;
|
||||
map->buck = (ase_awk_pair_t**)
|
||||
ASE_AWK_MALLOC (awk, ASE_SIZEOF(ase_awk_pair_t*) * capa);
|
||||
if (map->buck == ASE_NULL)
|
||||
{
|
||||
if (map->__dynamic) ASE_AWK_FREE (awk, map);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
map->owner = owner;
|
||||
map->capa = capa;
|
||||
map->size = 0;
|
||||
map->freeval = freeval;
|
||||
while (capa > 0) map->buck[--capa] = ASE_NULL;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void ase_awk_map_close (ase_awk_map_t* map)
|
||||
{
|
||||
ase_awk_map_clear (map);
|
||||
ASE_AWK_FREE (map->awk, map->buck);
|
||||
if (map->__dynamic) ASE_AWK_FREE (map->awk, map);
|
||||
}
|
||||
|
||||
void ase_awk_map_clear (ase_awk_map_t* map)
|
||||
{
|
||||
ase_size_t i;
|
||||
ase_awk_pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < map->capa; i++)
|
||||
{
|
||||
pair = map->buck[i];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
next = pair->next;
|
||||
FREE_PAIR (map, pair);
|
||||
map->size--;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
map->buck[i] = ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_map_getsize (ase_awk_map_t* map)
|
||||
{
|
||||
return map->size;
|
||||
}
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_get (
|
||||
ase_awk_map_t* map, const ase_char_t* key, ase_size_t key_len)
|
||||
{
|
||||
ase_awk_pair_t* pair;
|
||||
ase_size_t hc;
|
||||
|
||||
hc = hash(key,key_len) % map->capa;
|
||||
pair = map->buck[hc];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
|
||||
if (ase_strxncmp (
|
||||
pair->key, pair->key_len,
|
||||
key, key_len) == 0) return pair;
|
||||
|
||||
pair = pair->next;
|
||||
}
|
||||
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_put (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len, void* val)
|
||||
{
|
||||
int n;
|
||||
ase_awk_pair_t* px;
|
||||
|
||||
n = ase_awk_map_putx (map, key, key_len, val, &px);
|
||||
if (n < 0) return ASE_NULL;
|
||||
return px;
|
||||
}
|
||||
|
||||
int ase_awk_map_putx (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len,
|
||||
void* val, ase_awk_pair_t** px)
|
||||
{
|
||||
ase_awk_pair_t* pair;
|
||||
ase_size_t hc;
|
||||
|
||||
hc = hash(key,key_len) % map->capa;
|
||||
pair = map->buck[hc];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
pair->key, pair->key_len, key, key_len) == 0)
|
||||
{
|
||||
if (px != ASE_NULL)
|
||||
*px = ase_awk_map_setpair (map, pair, val);
|
||||
else
|
||||
ase_awk_map_setpair (map, pair, val);
|
||||
|
||||
return 0; /* value changed for the existing key */
|
||||
}
|
||||
pair = pair->next;
|
||||
}
|
||||
|
||||
pair = (ase_awk_pair_t*) ASE_AWK_MALLOC (
|
||||
map->awk, ASE_SIZEOF(ase_awk_pair_t));
|
||||
if (pair == ASE_NULL) return -1; /* error */
|
||||
|
||||
/*pair->key = key;*/
|
||||
|
||||
/* duplicate the key if it is new */
|
||||
pair->key = ase_strxdup (key, key_len, &map->awk->prmfns.mmgr);
|
||||
if (pair->key == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (map->awk, pair);
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
pair->key_len = key_len;
|
||||
pair->val = val;
|
||||
pair->next = map->buck[hc];
|
||||
map->buck[hc] = pair;
|
||||
map->size++;
|
||||
|
||||
if (px != ASE_NULL) *px = pair;
|
||||
return 1; /* new key added */
|
||||
}
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_set (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len, void* val)
|
||||
{
|
||||
ase_awk_pair_t* pair;
|
||||
ase_size_t hc;
|
||||
|
||||
hc = hash(key,key_len) % map->capa;
|
||||
pair = map->buck[hc];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
pair->key, pair->key_len, key, key_len) == 0)
|
||||
{
|
||||
return ase_awk_map_setpair (map, pair, val);
|
||||
}
|
||||
pair = pair->next;
|
||||
}
|
||||
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_getpair (
|
||||
ase_awk_map_t* map, const ase_char_t* key, ase_size_t key_len, void** val)
|
||||
{
|
||||
ase_awk_pair_t* pair;
|
||||
|
||||
pair = ase_awk_map_get (map, key, key_len);
|
||||
if (pair == ASE_NULL) return ASE_NULL;
|
||||
*val = pair->val;
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_setpair (
|
||||
ase_awk_map_t* map, ase_awk_pair_t* pair, void* val)
|
||||
{
|
||||
/* use this function with care */
|
||||
if (pair->val != val)
|
||||
{
|
||||
if (map->freeval != ASE_NULL)
|
||||
{
|
||||
map->freeval (map->owner, pair->val);
|
||||
}
|
||||
pair->val = val;
|
||||
}
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
int ase_awk_map_remove (ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len)
|
||||
{
|
||||
ase_awk_pair_t* pair, * prev;
|
||||
ase_size_t hc;
|
||||
|
||||
hc = hash(key,key_len) % map->capa;
|
||||
pair = map->buck[hc];
|
||||
prev = ASE_NULL;
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
pair->key, pair->key_len, key, key_len) == 0)
|
||||
{
|
||||
if (prev == ASE_NULL)
|
||||
map->buck[hc] = pair->next;
|
||||
else prev->next = pair->next;
|
||||
|
||||
FREE_PAIR (map, pair);
|
||||
map->size--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = pair->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ase_awk_map_walk (ase_awk_map_t* map,
|
||||
int (*walker) (ase_awk_pair_t*,void*), void* arg)
|
||||
{
|
||||
ase_size_t i;
|
||||
ase_awk_pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < map->capa; i++)
|
||||
{
|
||||
pair = map->buck[i];
|
||||
|
||||
while (pair != ASE_NULL)
|
||||
{
|
||||
next = pair->next;
|
||||
if (walker(pair,arg) == -1) return -1;
|
||||
pair = next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ase_size_t hash (const ase_char_t* key, ase_size_t key_len)
|
||||
{
|
||||
ase_size_t n = 0, i;
|
||||
const ase_char_t* end = key + key_len;
|
||||
|
||||
while (key < end)
|
||||
{
|
||||
ase_byte_t* bp = (ase_byte_t*)key;
|
||||
for (i = 0; i < ASE_SIZEOF(*key); i++) n = n * 31 + *bp++;
|
||||
key++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* $Id: map.h,v 1.1.1.1 2007/03/28 14:05:16 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_MAP_H_
|
||||
#define _ASE_AWK_MAP_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Include <ase/awk/awk.h> first
|
||||
#endif
|
||||
|
||||
/*typedef struct ase_awk_map_t ase_awk_map_t;*/
|
||||
typedef struct ase_awk_pair_t ase_awk_pair_t;
|
||||
|
||||
struct ase_awk_pair_t
|
||||
{
|
||||
ase_char_t* key;
|
||||
ase_size_t key_len;
|
||||
void* val;
|
||||
ase_awk_pair_t* next;
|
||||
};
|
||||
|
||||
struct ase_awk_map_t
|
||||
{
|
||||
void* owner;
|
||||
ase_size_t size;
|
||||
ase_size_t capa;
|
||||
ase_awk_pair_t** buck;
|
||||
void (*freeval) (void*,void*);
|
||||
ase_awk_t* awk;
|
||||
ase_bool_t __dynamic;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_awk_map_t* ase_awk_map_open (
|
||||
ase_awk_map_t* map, void* owner, ase_size_t capa,
|
||||
void(*freeval)(void*,void*), ase_awk_t* awk);
|
||||
|
||||
void ase_awk_map_close (ase_awk_map_t* map);
|
||||
|
||||
void ase_awk_map_clear (ase_awk_map_t* map);
|
||||
|
||||
ase_size_t ase_awk_map_getsize (ase_awk_map_t* map);
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_get (
|
||||
ase_awk_map_t* map, const ase_char_t* key, ase_size_t key_len);
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_put (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len, void* val);
|
||||
|
||||
int ase_awk_map_putx (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len,
|
||||
void* val, ase_awk_pair_t** px);
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_set (
|
||||
ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len, void* val);
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_getpair (
|
||||
ase_awk_map_t* map, const ase_char_t* key, ase_size_t key_len, void** val);
|
||||
|
||||
ase_awk_pair_t* ase_awk_map_setpair (
|
||||
ase_awk_map_t* map, ase_awk_pair_t* pair, void* val);
|
||||
|
||||
int ase_awk_map_remove (ase_awk_map_t* map, ase_char_t* key, ase_size_t key_len);
|
||||
|
||||
int ase_awk_map_walk (ase_awk_map_t* map,
|
||||
int (*walker)(ase_awk_pair_t*,void*), void* arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
905
ase/awk/misc.c
905
ase/awk/misc.c
@ -1,905 +0,0 @@
|
||||
/*
|
||||
* $Id: misc.c,v 1.1.1.1 2007/03/28 14:05:16 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
void* ase_awk_malloc (ase_awk_t* awk, ase_size_t size)
|
||||
{
|
||||
return ASE_AWK_MALLOC (awk, size);
|
||||
}
|
||||
|
||||
void ase_awk_free (ase_awk_t* awk, void* ptr)
|
||||
{
|
||||
ASE_AWK_FREE (awk, ptr);
|
||||
}
|
||||
|
||||
ase_long_t ase_awk_strxtolong (
|
||||
ase_awk_t* awk, const ase_char_t* str, ase_size_t len,
|
||||
int base, const ase_char_t** endptr)
|
||||
{
|
||||
ase_long_t n = 0;
|
||||
const ase_char_t* p;
|
||||
const ase_char_t* end;
|
||||
ase_size_t rem;
|
||||
int digit, negative = 0;
|
||||
|
||||
ASE_ASSERT (base < 37);
|
||||
|
||||
p = str;
|
||||
end = str + len;
|
||||
|
||||
/* strip off leading spaces */
|
||||
/*while (ASE_AWK_ISSPACE(awk,*p)) p++;*/
|
||||
|
||||
/* check for a sign */
|
||||
/*while (*p != ASE_T('\0')) */
|
||||
while (p < end)
|
||||
{
|
||||
if (*p == ASE_T('-'))
|
||||
{
|
||||
negative = ~negative;
|
||||
p++;
|
||||
}
|
||||
else if (*p == ASE_T('+')) p++;
|
||||
else break;
|
||||
}
|
||||
|
||||
/* check for a binary/octal/hexadecimal notation */
|
||||
rem = end - p;
|
||||
if (base == 0)
|
||||
{
|
||||
if (rem >= 1 && *p == ASE_T('0'))
|
||||
{
|
||||
p++;
|
||||
|
||||
if (rem == 1) base = 8;
|
||||
else if (*p == ASE_T('x') || *p == ASE_T('X'))
|
||||
{
|
||||
p++; base = 16;
|
||||
}
|
||||
else if (*p == ASE_T('b') || *p == ASE_T('B'))
|
||||
{
|
||||
p++; base = 2;
|
||||
}
|
||||
else base = 8;
|
||||
}
|
||||
else base = 10;
|
||||
}
|
||||
else if (rem >= 2 && base == 16)
|
||||
{
|
||||
if (*p == ASE_T('0') &&
|
||||
(*(p+1) == ASE_T('x') || *(p+1) == ASE_T('X'))) p += 2;
|
||||
}
|
||||
else if (rem >= 2 && base == 2)
|
||||
{
|
||||
if (*p == ASE_T('0') &&
|
||||
(*(p+1) == ASE_T('b') || *(p+1) == ASE_T('B'))) p += 2;
|
||||
}
|
||||
|
||||
/* process the digits */
|
||||
/*while (*p != ASE_T('\0'))*/
|
||||
while (p < end)
|
||||
{
|
||||
if (*p >= ASE_T('0') && *p <= ASE_T('9'))
|
||||
digit = *p - ASE_T('0');
|
||||
else if (*p >= ASE_T('A') && *p <= ASE_T('Z'))
|
||||
digit = *p - ASE_T('A') + 10;
|
||||
else if (*p >= ASE_T('a') && *p <= ASE_T('z'))
|
||||
digit = *p - ASE_T('a') + 10;
|
||||
else break;
|
||||
|
||||
if (digit >= base) break;
|
||||
n = n * base + digit;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (endptr != ASE_NULL) *endptr = p;
|
||||
return (negative)? -n: n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ase_awk_strtoreal is almost a replica of strtod.
|
||||
*
|
||||
* strtod.c --
|
||||
*
|
||||
* Source code for the "strtod" library procedure.
|
||||
*
|
||||
* Copyright (c) 1988-1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994 Sun Microsystems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. The University of California
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
#define MAX_EXPONENT 511
|
||||
|
||||
ase_real_t ase_awk_strtoreal (ase_awk_t* awk, const ase_char_t* str)
|
||||
{
|
||||
/*
|
||||
* Table giving binary powers of 10. Entry is 10^2^i.
|
||||
* Used to convert decimal exponents into floating-point numbers.
|
||||
*/
|
||||
static ase_real_t powers_of_10[] =
|
||||
{
|
||||
10., 100., 1.0e4, 1.0e8, 1.0e16,
|
||||
1.0e32, 1.0e64, 1.0e128, 1.0e256
|
||||
};
|
||||
|
||||
ase_real_t fraction, dbl_exp, * d;
|
||||
const ase_char_t* p;
|
||||
ase_cint_t c;
|
||||
int exp = 0; /* Esseonent read from "EX" field */
|
||||
|
||||
/*
|
||||
* Esseonent that derives from the fractional part. Under normal
|
||||
* circumstatnces, it is the negative of the number of digits in F.
|
||||
* However, if I is very long, the last digits of I get dropped
|
||||
* (otherwise a long I with a large negative exponent could cause an
|
||||
* unnecessary overflow on I alone). In this case, frac_exp is
|
||||
* incremented one for each dropped digit.
|
||||
*/
|
||||
|
||||
int frac_exp;
|
||||
int mant_size; /* Number of digits in mantissa. */
|
||||
int dec_pt; /* Number of mantissa digits BEFORE decimal point */
|
||||
const ase_char_t *pexp; /* Temporarily holds location of exponent in string */
|
||||
int negative = 0, exp_negative = 0;
|
||||
|
||||
p = str;
|
||||
|
||||
/* strip off leading blanks */
|
||||
/*while (ASE_AWK_ISSPACE(awk,*p)) p++;*/
|
||||
|
||||
/* check for a sign */
|
||||
while (*p != ASE_T('\0'))
|
||||
{
|
||||
if (*p == ASE_T('-'))
|
||||
{
|
||||
negative = ~negative;
|
||||
p++;
|
||||
}
|
||||
else if (*p == ASE_T('+')) p++;
|
||||
else break;
|
||||
}
|
||||
|
||||
/* Count the number of digits in the mantissa (including the decimal
|
||||
* point), and also locate the decimal point. */
|
||||
dec_pt = -1;
|
||||
for (mant_size = 0; ; mant_size++)
|
||||
{
|
||||
c = *p;
|
||||
if (!ASE_AWK_ISDIGIT (awk, c))
|
||||
{
|
||||
if ((c != ASE_T('.')) || (dec_pt >= 0)) break;
|
||||
dec_pt = mant_size;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now suck up the digits in the mantissa. Use two integers to
|
||||
* collect 9 digits each (this is faster than using floating-point).
|
||||
* If the mantissa has more than 18 digits, ignore the extras, since
|
||||
* they can't affect the value anyway.
|
||||
*/
|
||||
pexp = p;
|
||||
p -= mant_size;
|
||||
if (dec_pt < 0)
|
||||
{
|
||||
dec_pt = mant_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
mant_size--; /* One of the digits was the point */
|
||||
}
|
||||
|
||||
if (mant_size > 18)
|
||||
{
|
||||
frac_exp = dec_pt - 18;
|
||||
mant_size = 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac_exp = dec_pt - mant_size;
|
||||
}
|
||||
|
||||
if (mant_size == 0)
|
||||
{
|
||||
fraction = 0.0;
|
||||
/*p = str;*/
|
||||
p = pexp;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
int frac1, frac2;
|
||||
frac1 = 0;
|
||||
for ( ; mant_size > 9; mant_size--)
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
if (c == ASE_T('.'))
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
}
|
||||
frac1 = 10 * frac1 + (c - ASE_T('0'));
|
||||
}
|
||||
frac2 = 0;
|
||||
for (; mant_size > 0; mant_size--) {
|
||||
c = *p;
|
||||
p++;
|
||||
if (c == ASE_T('.'))
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
}
|
||||
frac2 = 10*frac2 + (c - ASE_T('0'));
|
||||
}
|
||||
fraction = (1.0e9 * frac1) + frac2;
|
||||
}
|
||||
|
||||
/* Skim off the exponent */
|
||||
p = pexp;
|
||||
if ((*p == ASE_T('E')) || (*p == ASE_T('e')))
|
||||
{
|
||||
p++;
|
||||
if (*p == ASE_T('-'))
|
||||
{
|
||||
exp_negative = 1;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == ASE_T('+')) p++;
|
||||
exp_negative = 0;
|
||||
}
|
||||
if (!ASE_AWK_ISDIGIT (awk, *p))
|
||||
{
|
||||
/* p = pexp; */
|
||||
/* goto done; */
|
||||
goto no_exp;
|
||||
}
|
||||
while (ASE_AWK_ISDIGIT (awk, *p))
|
||||
{
|
||||
exp = exp * 10 + (*p - ASE_T('0'));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
no_exp:
|
||||
if (exp_negative) exp = frac_exp - exp;
|
||||
else exp = frac_exp + exp;
|
||||
|
||||
/*
|
||||
* Generate a floating-point number that represents the exponent.
|
||||
* Do this by processing the exponent one bit at a time to combine
|
||||
* many powers of 2 of 10. Then combine the exponent with the
|
||||
* fraction.
|
||||
*/
|
||||
if (exp < 0)
|
||||
{
|
||||
exp_negative = 1;
|
||||
exp = -exp;
|
||||
}
|
||||
else exp_negative = 0;
|
||||
|
||||
if (exp > MAX_EXPONENT) exp = MAX_EXPONENT;
|
||||
|
||||
dbl_exp = 1.0;
|
||||
|
||||
for (d = powers_of_10; exp != 0; exp >>= 1, d++)
|
||||
{
|
||||
if (exp & 01) dbl_exp *= *d;
|
||||
}
|
||||
|
||||
if (exp_negative) fraction /= dbl_exp;
|
||||
else fraction *= dbl_exp;
|
||||
|
||||
done:
|
||||
return (negative)? -fraction: fraction;
|
||||
}
|
||||
|
||||
ase_real_t ase_awk_strxtoreal (
|
||||
ase_awk_t* awk, const ase_char_t* str, ase_size_t len,
|
||||
const ase_char_t** endptr)
|
||||
{
|
||||
/*
|
||||
* Table giving binary powers of 10. Entry is 10^2^i.
|
||||
* Used to convert decimal exponents into floating-point numbers.
|
||||
*/
|
||||
static ase_real_t powers_of_10[] =
|
||||
{
|
||||
10., 100., 1.0e4, 1.0e8, 1.0e16,
|
||||
1.0e32, 1.0e64, 1.0e128, 1.0e256
|
||||
};
|
||||
|
||||
ase_real_t fraction, dbl_exp, * d;
|
||||
const ase_char_t* p, * end;
|
||||
ase_cint_t c;
|
||||
int exp = 0; /* Esseonent read from "EX" field */
|
||||
|
||||
/*
|
||||
* Esseonent that derives from the fractional part. Under normal
|
||||
* circumstatnces, it is the negative of the number of digits in F.
|
||||
* However, if I is very long, the last digits of I get dropped
|
||||
* (otherwise a long I with a large negative exponent could cause an
|
||||
* unnecessary overflow on I alone). In this case, frac_exp is
|
||||
* incremented one for each dropped digit.
|
||||
*/
|
||||
|
||||
int frac_exp;
|
||||
int mant_size; /* Number of digits in mantissa. */
|
||||
int dec_pt; /* Number of mantissa digits BEFORE decimal point */
|
||||
const ase_char_t *pexp; /* Temporarily holds location of exponent in string */
|
||||
int negative = 0, exp_negative = 0;
|
||||
|
||||
p = str;
|
||||
end = str + len;
|
||||
|
||||
/* Strip off leading blanks and check for a sign */
|
||||
/*while (ASE_AWK_ISSPACE(awk,*p)) p++;*/
|
||||
|
||||
/*while (*p != ASE_T('\0')) */
|
||||
while (p < end)
|
||||
{
|
||||
if (*p == ASE_T('-'))
|
||||
{
|
||||
negative = ~negative;
|
||||
p++;
|
||||
}
|
||||
else if (*p == ASE_T('+')) p++;
|
||||
else break;
|
||||
}
|
||||
|
||||
/* Count the number of digits in the mantissa (including the decimal
|
||||
* point), and also locate the decimal point. */
|
||||
dec_pt = -1;
|
||||
/*for (mant_size = 0; ; mant_size++) */
|
||||
for (mant_size = 0; p < end; mant_size++)
|
||||
{
|
||||
c = *p;
|
||||
if (!ASE_AWK_ISDIGIT (awk, c))
|
||||
{
|
||||
if (c != ASE_T('.') || dec_pt >= 0) break;
|
||||
dec_pt = mant_size;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now suck up the digits in the mantissa. Use two integers to
|
||||
* collect 9 digits each (this is faster than using floating-point).
|
||||
* If the mantissa has more than 18 digits, ignore the extras, since
|
||||
* they can't affect the value anyway.
|
||||
*/
|
||||
pexp = p;
|
||||
p -= mant_size;
|
||||
if (dec_pt < 0)
|
||||
{
|
||||
dec_pt = mant_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
mant_size--; /* One of the digits was the point */
|
||||
}
|
||||
|
||||
if (mant_size > 18) /* TODO: is 18 correct for ase_real_t??? */
|
||||
{
|
||||
frac_exp = dec_pt - 18;
|
||||
mant_size = 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac_exp = dec_pt - mant_size;
|
||||
}
|
||||
|
||||
if (mant_size == 0)
|
||||
{
|
||||
fraction = 0.0;
|
||||
/*p = str;*/
|
||||
p = pexp;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
int frac1, frac2;
|
||||
|
||||
frac1 = 0;
|
||||
for ( ; mant_size > 9; mant_size--)
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
if (c == ASE_T('.'))
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
}
|
||||
frac1 = 10 * frac1 + (c - ASE_T('0'));
|
||||
}
|
||||
|
||||
frac2 = 0;
|
||||
for (; mant_size > 0; mant_size--) {
|
||||
c = *p++;
|
||||
if (c == ASE_T('.'))
|
||||
{
|
||||
c = *p;
|
||||
p++;
|
||||
}
|
||||
frac2 = 10 * frac2 + (c - ASE_T('0'));
|
||||
}
|
||||
fraction = (1.0e9 * frac1) + frac2;
|
||||
}
|
||||
|
||||
/* Skim off the exponent */
|
||||
p = pexp;
|
||||
if (p < end && (*p == ASE_T('E') || *p == ASE_T('e')))
|
||||
{
|
||||
p++;
|
||||
|
||||
if (p < end)
|
||||
{
|
||||
if (*p == ASE_T('-'))
|
||||
{
|
||||
exp_negative = 1;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p == ASE_T('+')) p++;
|
||||
exp_negative = 0;
|
||||
}
|
||||
}
|
||||
else exp_negative = 0;
|
||||
|
||||
if (!(p < end && ASE_AWK_ISDIGIT (awk, *p)))
|
||||
{
|
||||
/*p = pexp;*/
|
||||
/*goto done;*/
|
||||
goto no_exp;
|
||||
}
|
||||
|
||||
while (p < end && ASE_AWK_ISDIGIT (awk, *p))
|
||||
{
|
||||
exp = exp * 10 + (*p - ASE_T('0'));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
no_exp:
|
||||
if (exp_negative) exp = frac_exp - exp;
|
||||
else exp = frac_exp + exp;
|
||||
|
||||
/*
|
||||
* Generate a floating-point number that represents the exponent.
|
||||
* Do this by processing the exponent one bit at a time to combine
|
||||
* many powers of 2 of 10. Then combine the exponent with the
|
||||
* fraction.
|
||||
*/
|
||||
if (exp < 0)
|
||||
{
|
||||
exp_negative = 1;
|
||||
exp = -exp;
|
||||
}
|
||||
else exp_negative = 0;
|
||||
|
||||
if (exp > MAX_EXPONENT) exp = MAX_EXPONENT;
|
||||
|
||||
dbl_exp = 1.0;
|
||||
|
||||
for (d = powers_of_10; exp != 0; exp >>= 1, d++)
|
||||
{
|
||||
if (exp & 01) dbl_exp *= *d;
|
||||
}
|
||||
|
||||
if (exp_negative) fraction /= dbl_exp;
|
||||
else fraction *= dbl_exp;
|
||||
|
||||
done:
|
||||
if (endptr != ASE_NULL) *endptr = p;
|
||||
return (negative)? -fraction: fraction;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_longtostr (
|
||||
ase_long_t value, int radix, const ase_char_t* prefix,
|
||||
ase_char_t* buf, ase_size_t size)
|
||||
{
|
||||
ase_long_t t, rem;
|
||||
ase_size_t len, ret, i;
|
||||
ase_size_t prefix_len;
|
||||
|
||||
prefix_len = (prefix != ASE_NULL)? ase_strlen(prefix): 0;
|
||||
|
||||
t = value;
|
||||
if (t == 0)
|
||||
{
|
||||
/* zero */
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
/* if buf is not given,
|
||||
* return the number of bytes required */
|
||||
return prefix_len + 1;
|
||||
}
|
||||
|
||||
if (size < prefix_len+1)
|
||||
{
|
||||
/* buffer too small */
|
||||
return (ase_size_t)-1;
|
||||
}
|
||||
|
||||
for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
|
||||
buf[prefix_len] = ASE_T('0');
|
||||
if (size > prefix_len+1) buf[prefix_len+1] = ASE_T('\0');
|
||||
return prefix_len+1;
|
||||
}
|
||||
|
||||
/* non-zero values */
|
||||
len = prefix_len;
|
||||
if (t < 0) { t = -t; len++; }
|
||||
while (t > 0) { len++; t /= radix; }
|
||||
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
/* if buf is not given, return the number of bytes required */
|
||||
return len;
|
||||
}
|
||||
|
||||
if (size < len) return (ase_size_t)-1; /* buffer too small */
|
||||
if (size > len) buf[len] = ASE_T('\0');
|
||||
ret = len;
|
||||
|
||||
t = value;
|
||||
if (t < 0) t = -t;
|
||||
|
||||
while (t > 0)
|
||||
{
|
||||
rem = t % radix;
|
||||
if (rem >= 10)
|
||||
buf[--len] = (ase_char_t)rem + ASE_T('a') - 10;
|
||||
else
|
||||
buf[--len] = (ase_char_t)rem + ASE_T('0');
|
||||
t /= radix;
|
||||
}
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
for (i = 1; i <= prefix_len; i++)
|
||||
{
|
||||
buf[i] = prefix[i-1];
|
||||
len--;
|
||||
}
|
||||
buf[--len] = ASE_T('-');
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_strtok (
|
||||
ase_awk_run_t* run, const ase_char_t* s,
|
||||
const ase_char_t* delim, ase_char_t** tok, ase_size_t* tok_len)
|
||||
{
|
||||
return ase_awk_strxntok (
|
||||
run, s, ase_strlen(s),
|
||||
delim, ase_strlen(delim), tok, tok_len);
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_strxtok (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
const ase_char_t* delim, ase_char_t** tok, ase_size_t* tok_len)
|
||||
{
|
||||
return ase_awk_strxntok (
|
||||
run, s, len,
|
||||
delim, ase_strlen(delim), tok, tok_len);
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_strntok (
|
||||
ase_awk_run_t* run, const ase_char_t* s,
|
||||
const ase_char_t* delim, ase_size_t delim_len,
|
||||
ase_char_t** tok, ase_size_t* tok_len)
|
||||
{
|
||||
return ase_awk_strxntok (
|
||||
run, s, ase_strlen(s),
|
||||
delim, delim_len, tok, tok_len);
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_strxntok (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
const ase_char_t* delim, ase_size_t delim_len,
|
||||
ase_char_t** tok, ase_size_t* tok_len)
|
||||
{
|
||||
const ase_char_t* p = s, *d;
|
||||
const ase_char_t* end = s + len;
|
||||
const ase_char_t* sp = ASE_NULL, * ep = ASE_NULL;
|
||||
const ase_char_t* delim_end = delim + delim_len;
|
||||
ase_char_t c;
|
||||
int delim_mode;
|
||||
|
||||
#define __DELIM_NULL 0
|
||||
#define __DELIM_EMPTY 1
|
||||
#define __DELIM_SPACES 2
|
||||
#define __DELIM_NOSPACES 3
|
||||
#define __DELIM_COMPOSITE 4
|
||||
if (delim == ASE_NULL) delim_mode = __DELIM_NULL;
|
||||
else
|
||||
{
|
||||
delim_mode = __DELIM_EMPTY;
|
||||
|
||||
for (d = delim; d < delim_end; d++)
|
||||
{
|
||||
if (ASE_AWK_ISSPACE(run->awk,*d))
|
||||
{
|
||||
if (delim_mode == __DELIM_EMPTY)
|
||||
delim_mode = __DELIM_SPACES;
|
||||
else if (delim_mode == __DELIM_NOSPACES)
|
||||
{
|
||||
delim_mode = __DELIM_COMPOSITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delim_mode == __DELIM_EMPTY)
|
||||
delim_mode = __DELIM_NOSPACES;
|
||||
else if (delim_mode == __DELIM_SPACES)
|
||||
{
|
||||
delim_mode = __DELIM_COMPOSITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: verify the following statement... */
|
||||
if (delim_mode == __DELIM_SPACES &&
|
||||
delim_len == 1 &&
|
||||
delim[0] != ASE_T(' ')) delim_mode = __DELIM_NOSPACES;
|
||||
}
|
||||
|
||||
if (delim_mode == __DELIM_NULL)
|
||||
{
|
||||
/* when ASE_NULL is given as "delim", it trims off the
|
||||
* leading and trailing spaces characters off the source
|
||||
* string "s" eventually. */
|
||||
|
||||
while (p < end && ASE_AWK_ISSPACE(run->awk,*p)) p++;
|
||||
while (p < end)
|
||||
{
|
||||
c = *p;
|
||||
|
||||
if (!ASE_AWK_ISSPACE(run->awk,c))
|
||||
{
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else if (delim_mode == __DELIM_EMPTY)
|
||||
{
|
||||
/* each character in the source string "s" becomes a token. */
|
||||
if (p < end)
|
||||
{
|
||||
c = *p;
|
||||
sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
}
|
||||
else if (delim_mode == __DELIM_SPACES)
|
||||
{
|
||||
/* each token is delimited by space characters. all leading
|
||||
* and trailing spaces are removed. */
|
||||
|
||||
while (p < end && ASE_AWK_ISSPACE(run->awk,*p)) p++;
|
||||
while (p < end)
|
||||
{
|
||||
c = *p;
|
||||
if (ASE_AWK_ISSPACE(run->awk,c)) break;
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
while (p < end && ASE_AWK_ISSPACE(run->awk,*p)) p++;
|
||||
}
|
||||
else if (delim_mode == __DELIM_NOSPACES)
|
||||
{
|
||||
/* each token is delimited by one of charaters
|
||||
* in the delimeter set "delim". */
|
||||
if (run->global.ignorecase)
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
c = ASE_AWK_TOUPPER(run->awk, *p);
|
||||
for (d = delim; d < delim_end; d++)
|
||||
{
|
||||
if (c == ASE_AWK_TOUPPER(run->awk,*d)) goto exit_loop;
|
||||
}
|
||||
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
c = *p;
|
||||
for (d = delim; d < delim_end; d++)
|
||||
{
|
||||
if (c == *d) goto exit_loop;
|
||||
}
|
||||
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* if (delim_mode == __DELIM_COMPOSITE) */
|
||||
{
|
||||
/* each token is delimited by one of non-space charaters
|
||||
* in the delimeter set "delim". however, all space characters
|
||||
* surrounding the token are removed */
|
||||
while (p < end && ASE_AWK_ISSPACE(run->awk,*p)) p++;
|
||||
if (run->global.ignorecase)
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
c = ASE_AWK_TOUPPER(run->awk, *p);
|
||||
if (ASE_AWK_ISSPACE(run->awk,c))
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
for (d = delim; d < delim_end; d++)
|
||||
{
|
||||
if (c == ASE_AWK_TOUPPER(run->awk,*d)) goto exit_loop;
|
||||
}
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
c = *p;
|
||||
if (ASE_AWK_ISSPACE(run->awk,c))
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
for (d = delim; d < delim_end; d++)
|
||||
{
|
||||
if (c == *d) goto exit_loop;
|
||||
}
|
||||
if (sp == ASE_NULL) sp = p;
|
||||
ep = p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit_loop:
|
||||
if (sp == ASE_NULL)
|
||||
{
|
||||
*tok = ASE_NULL;
|
||||
*tok_len = (ase_size_t)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tok = (ase_char_t*)sp;
|
||||
*tok_len = ep - sp + 1;
|
||||
}
|
||||
|
||||
/* if ASE_NULL is returned, this function should not be called anymore */
|
||||
if (p >= end) return ASE_NULL;
|
||||
if (delim_mode == __DELIM_EMPTY ||
|
||||
delim_mode == __DELIM_SPACES) return (ase_char_t*)p;
|
||||
return (ase_char_t*)++p;
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_strxntokbyrex (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
void* rex, ase_char_t** tok, ase_size_t* tok_len, int* errnum)
|
||||
{
|
||||
int n;
|
||||
ase_char_t* match_ptr;
|
||||
ase_size_t match_len, i;
|
||||
ase_size_t left = len;
|
||||
const ase_char_t* ptr = s;
|
||||
const ase_char_t* str_ptr = s;
|
||||
ase_size_t str_len = len;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
n = ase_awk_matchrex (
|
||||
run->awk, rex,
|
||||
((run->global.ignorecase)? ASE_AWK_REX_IGNORECASE: 0),
|
||||
ptr, left, (const ase_char_t**)&match_ptr, &match_len,
|
||||
errnum);
|
||||
if (n == -1) return ASE_NULL;
|
||||
if (n == 0)
|
||||
{
|
||||
/* no match has been found.
|
||||
* return the entire string as a token */
|
||||
*tok = (ase_char_t*)str_ptr;
|
||||
*tok_len = str_len;
|
||||
*errnum = ASE_AWK_ENOERR;
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
ASE_ASSERT (n == 1);
|
||||
|
||||
if (match_len == 0)
|
||||
{
|
||||
ptr++;
|
||||
left--;
|
||||
}
|
||||
else if (run->awk->option & ASE_AWK_STRIPSPACES)
|
||||
{
|
||||
/* match at the beginning of the input string */
|
||||
if (match_ptr == s)
|
||||
{
|
||||
for (i = 0; i < match_len; i++)
|
||||
{
|
||||
if (!ASE_AWK_ISSPACE(run->awk, match_ptr[i]))
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
/* the match that are all spaces at the
|
||||
* beginning of the input string is skipped */
|
||||
ptr += match_len;
|
||||
left -= match_len;
|
||||
str_ptr = s + match_len;
|
||||
str_len -= match_len;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
exit_loop:
|
||||
if (len == 0)
|
||||
{
|
||||
*tok = (ase_char_t*)str_ptr;
|
||||
*tok_len = str_len;
|
||||
*errnum = ASE_AWK_ENOERR;
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
*tok = (ase_char_t*)str_ptr;
|
||||
*tok_len = match_ptr - str_ptr;
|
||||
|
||||
for (i = 0; i < match_len; i++)
|
||||
{
|
||||
if (!ASE_AWK_ISSPACE(run->awk, match_ptr[i]))
|
||||
{
|
||||
*errnum = ASE_AWK_ENOERR;
|
||||
return match_ptr+match_len;
|
||||
}
|
||||
}
|
||||
|
||||
*errnum = ASE_AWK_ENOERR;
|
||||
|
||||
if (run->awk->option & ASE_AWK_STRIPSPACES)
|
||||
{
|
||||
return (match_ptr+match_len >= s+len)?
|
||||
ASE_NULL: (match_ptr+match_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (match_ptr+match_len > s+len)?
|
||||
ASE_NULL: (match_ptr+match_len);
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* $Id: misc.h,v 1.1.1.1 2007/03/28 14:05:16 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_MISC_H_
|
||||
#define _ASE_AWK_MISC_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_char_t* ase_awk_strtok (
|
||||
ase_awk_run_t* run, const ase_char_t* s,
|
||||
const ase_char_t* delim, ase_char_t** tok, ase_size_t* tok_len);
|
||||
|
||||
ase_char_t* ase_awk_strxtok (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
const ase_char_t* delim, ase_char_t** tok, ase_size_t* tok_len);
|
||||
|
||||
ase_char_t* ase_awk_strntok (
|
||||
ase_awk_run_t* run, const ase_char_t* s,
|
||||
const ase_char_t* delim, ase_size_t delim_len,
|
||||
ase_char_t** tok, ase_size_t* tok_len);
|
||||
|
||||
ase_char_t* ase_awk_strxntok (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
const ase_char_t* delim, ase_size_t delim_len,
|
||||
ase_char_t** tok, ase_size_t* tok_len);
|
||||
|
||||
ase_char_t* ase_awk_strxntokbyrex (
|
||||
ase_awk_run_t* run, const ase_char_t* s, ase_size_t len,
|
||||
void* rex, ase_char_t** tok, ase_size_t* tok_len, int* errnum);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
5113
ase/awk/parse.c
5113
ase/awk/parse.c
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* $Id: parse.h,v 1.1.1.1 2007/03/28 14:05:17 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_PARSE_H_
|
||||
#define _ASE_AWK_PARSE_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ase_awk_putsrcstr (ase_awk_t* awk, const ase_char_t* str);
|
||||
int ase_awk_putsrcstrx (
|
||||
ase_awk_t* awk, const ase_char_t* str, ase_size_t len);
|
||||
|
||||
const ase_char_t* ase_awk_getglobalname (
|
||||
ase_awk_t* awk, ase_size_t idx, ase_size_t* len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
449
ase/awk/rec.c
449
ase/awk/rec.c
@ -1,449 +0,0 @@
|
||||
/*
|
||||
* $Id: rec.c,v 1.1.1.1 2007/03/28 14:05:17 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
static int __split_record (ase_awk_run_t* run);
|
||||
static int __recomp_record_fields (
|
||||
ase_awk_run_t* run, ase_size_t lv,
|
||||
const ase_char_t* str, ase_size_t len);
|
||||
|
||||
int ase_awk_setrec (
|
||||
ase_awk_run_t* run, ase_size_t idx,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_awk_val_t* v;
|
||||
|
||||
if (idx == 0)
|
||||
{
|
||||
if (str == ASE_STR_BUF(&run->inrec.line) &&
|
||||
len == ASE_STR_LEN(&run->inrec.line))
|
||||
{
|
||||
if (ase_awk_clrrec (run, ase_true) == -1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ase_awk_clrrec (run, ase_false) == -1) return -1;
|
||||
|
||||
if (ase_str_ncpy (&run->inrec.line, str, len) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_clrrec (run, ase_false);
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
v = ase_awk_makestrval (run, str, len);
|
||||
if (v == ASE_NULL)
|
||||
{
|
||||
ase_awk_clrrec (run, ase_false);
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASE_ASSERT (run->inrec.d0->type == ASE_AWK_VAL_NIL);
|
||||
/* d0 should be cleared before the next line is reached
|
||||
* as it doesn't call ase_awk_refdownval on run->inrec.d0 */
|
||||
run->inrec.d0 = v;
|
||||
ase_awk_refupval (run, v);
|
||||
|
||||
if (__split_record (run) == -1)
|
||||
{
|
||||
ase_awk_clrrec (run, ase_false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__recomp_record_fields (run, idx, str, len) == -1)
|
||||
{
|
||||
ase_awk_clrrec (run, ase_false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* recompose $0 */
|
||||
v = ase_awk_makestrval (run,
|
||||
ASE_STR_BUF(&run->inrec.line),
|
||||
ASE_STR_LEN(&run->inrec.line));
|
||||
if (v == ASE_NULL)
|
||||
{
|
||||
ase_awk_clrrec (run, ase_false);
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ase_awk_refdownval (run, run->inrec.d0);
|
||||
run->inrec.d0 = v;
|
||||
ase_awk_refupval (run, v);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __split_record (ase_awk_run_t* run)
|
||||
{
|
||||
ase_char_t* p, * tok;
|
||||
ase_size_t len, tok_len, nflds;
|
||||
ase_awk_val_t* v, * fs;
|
||||
ase_char_t* fs_ptr, * fs_free;
|
||||
ase_size_t fs_len;
|
||||
int errnum;
|
||||
|
||||
/* inrec should be cleared before __split_record is called */
|
||||
ASE_ASSERT (run->inrec.nflds == 0);
|
||||
|
||||
/* get FS */
|
||||
fs = ase_awk_getglobal (run, ASE_AWK_GLOBAL_FS);
|
||||
if (fs->type == ASE_AWK_VAL_NIL)
|
||||
{
|
||||
fs_ptr = ASE_T(" ");
|
||||
fs_len = 1;
|
||||
fs_free = ASE_NULL;
|
||||
}
|
||||
else if (fs->type == ASE_AWK_VAL_STR)
|
||||
{
|
||||
fs_ptr = ((ase_awk_val_str_t*)fs)->buf;
|
||||
fs_len = ((ase_awk_val_str_t*)fs)->len;
|
||||
fs_free = ASE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs_ptr = ase_awk_valtostr (
|
||||
run, fs, ASE_AWK_VALTOSTR_CLEAR, ASE_NULL, &fs_len);
|
||||
if (fs_ptr == ASE_NULL) return -1;
|
||||
fs_free = fs_ptr;
|
||||
}
|
||||
|
||||
/* scan the input record to count the fields */
|
||||
p = ASE_STR_BUF(&run->inrec.line);
|
||||
len = ASE_STR_LEN(&run->inrec.line);
|
||||
|
||||
nflds = 0;
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (fs_len <= 1)
|
||||
{
|
||||
p = ase_awk_strxntok (run,
|
||||
p, len, fs_ptr, fs_len, &tok, &tok_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = ase_awk_strxntokbyrex (run, p, len,
|
||||
run->global.fs, &tok, &tok_len, &errnum);
|
||||
if (p == ASE_NULL && errnum != ASE_AWK_ENOERR)
|
||||
{
|
||||
if (fs_free != ASE_NULL)
|
||||
ASE_AWK_FREE (run->awk, fs_free);
|
||||
ase_awk_setrunerror (run, errnum, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nflds == 0 && p == ASE_NULL && tok_len == 0)
|
||||
{
|
||||
/* there are no fields. it can just return here
|
||||
* as ase_awk_clrrec has been called before this */
|
||||
if (fs_free != ASE_NULL) ASE_AWK_FREE (run->awk, fs_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASE_ASSERT ((tok != ASE_NULL && tok_len > 0) || tok_len == 0);
|
||||
|
||||
nflds++;
|
||||
len = ASE_STR_LEN(&run->inrec.line) -
|
||||
(p - ASE_STR_BUF(&run->inrec.line));
|
||||
}
|
||||
|
||||
/* allocate space */
|
||||
if (nflds > run->inrec.maxflds)
|
||||
{
|
||||
void* tmp = ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(*run->inrec.flds) * nflds);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
if (fs_free != ASE_NULL) ASE_AWK_FREE (run->awk, fs_free);
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (run->inrec.flds != ASE_NULL)
|
||||
ASE_AWK_FREE (run->awk, run->inrec.flds);
|
||||
run->inrec.flds = tmp;
|
||||
run->inrec.maxflds = nflds;
|
||||
}
|
||||
|
||||
/* scan again and split it */
|
||||
p = ASE_STR_BUF(&run->inrec.line);
|
||||
len = ASE_STR_LEN(&run->inrec.line);
|
||||
|
||||
while (p != ASE_NULL)
|
||||
{
|
||||
if (fs_len <= 1)
|
||||
{
|
||||
p = ase_awk_strxntok (
|
||||
run, p, len, fs_ptr, fs_len, &tok, &tok_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = ase_awk_strxntokbyrex (run, p, len,
|
||||
run->global.fs, &tok, &tok_len, &errnum);
|
||||
if (p == ASE_NULL && errnum != ASE_AWK_ENOERR)
|
||||
{
|
||||
if (fs_free != ASE_NULL)
|
||||
ASE_AWK_FREE (run->awk, fs_free);
|
||||
ase_awk_setrunerror (run, errnum, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ASE_ASSERT ((tok != ASE_NULL && tok_len > 0) || tok_len == 0);
|
||||
|
||||
run->inrec.flds[run->inrec.nflds].ptr = tok;
|
||||
run->inrec.flds[run->inrec.nflds].len = tok_len;
|
||||
run->inrec.flds[run->inrec.nflds].val =
|
||||
ase_awk_makestrval (run, tok, tok_len);
|
||||
|
||||
if (run->inrec.flds[run->inrec.nflds].val == ASE_NULL)
|
||||
{
|
||||
if (fs_free != ASE_NULL) ASE_AWK_FREE (run->awk, fs_free);
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ase_awk_refupval (run, run->inrec.flds[run->inrec.nflds].val);
|
||||
run->inrec.nflds++;
|
||||
|
||||
len = ASE_STR_LEN(&run->inrec.line) -
|
||||
(p - ASE_STR_BUF(&run->inrec.line));
|
||||
}
|
||||
|
||||
if (fs_free != ASE_NULL) ASE_AWK_FREE (run->awk, fs_free);
|
||||
|
||||
/* set the number of fields */
|
||||
v = ase_awk_makeintval (run, (ase_long_t)nflds);
|
||||
if (v == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ase_awk_setglobal (run, ASE_AWK_GLOBAL_NF, v) == -1) return -1;
|
||||
|
||||
ASE_ASSERT (nflds == run->inrec.nflds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ase_awk_clrrec (ase_awk_run_t* run, ase_bool_t skip_inrec_line)
|
||||
{
|
||||
ase_size_t i;
|
||||
int n = 0;
|
||||
|
||||
if (run->inrec.d0 != ase_awk_val_nil)
|
||||
{
|
||||
ase_awk_refdownval (run, run->inrec.d0);
|
||||
run->inrec.d0 = ase_awk_val_nil;
|
||||
}
|
||||
|
||||
if (run->inrec.nflds > 0)
|
||||
{
|
||||
ASE_ASSERT (run->inrec.flds != ASE_NULL);
|
||||
|
||||
for (i = 0; i < run->inrec.nflds; i++)
|
||||
{
|
||||
ASE_ASSERT (run->inrec.flds[i].val != ASE_NULL);
|
||||
ase_awk_refdownval (run, run->inrec.flds[i].val);
|
||||
}
|
||||
run->inrec.nflds = 0;
|
||||
|
||||
if (ase_awk_setglobal (
|
||||
run, ASE_AWK_GLOBAL_NF, ase_awk_val_zero) == -1)
|
||||
{
|
||||
/* first of all, this should never happen.
|
||||
* if it happened, it would return an error
|
||||
* after all the clearance tasks */
|
||||
n = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ASE_ASSERT (run->inrec.nflds == 0);
|
||||
if (!skip_inrec_line) ase_str_clear (&run->inrec.line);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int __recomp_record_fields (
|
||||
ase_awk_run_t* run, ase_size_t lv,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_awk_val_t* v;
|
||||
ase_size_t max, i, nflds;
|
||||
|
||||
/* recomposes the record and the fields when $N has been assigned
|
||||
* a new value and recomputes NF accordingly */
|
||||
|
||||
ASE_ASSERT (lv > 0);
|
||||
max = (lv > run->inrec.nflds)? lv: run->inrec.nflds;
|
||||
|
||||
nflds = run->inrec.nflds;
|
||||
if (max > run->inrec.maxflds)
|
||||
{
|
||||
void* tmp;
|
||||
|
||||
/* if the given field number is greater than the maximum
|
||||
* number of fields that the current record can hold,
|
||||
* the field spaces are resized */
|
||||
|
||||
if (run->awk->prmfns.mmgr.realloc != ASE_NULL)
|
||||
{
|
||||
tmp = ASE_AWK_REALLOC (
|
||||
run->awk, run->inrec.flds,
|
||||
ASE_SIZEOF(*run->inrec.flds) * max);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(*run->inrec.flds) * max);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
if (run->inrec.flds != ASE_NULL)
|
||||
{
|
||||
ase_memcpy (tmp, run->inrec.flds,
|
||||
ASE_SIZEOF(*run->inrec.flds)*run->inrec.maxflds);
|
||||
ASE_AWK_FREE (run->awk, run->inrec.flds);
|
||||
}
|
||||
}
|
||||
|
||||
run->inrec.flds = tmp;
|
||||
run->inrec.maxflds = max;
|
||||
}
|
||||
|
||||
lv = lv - 1; /* adjust the value to 0-based index */
|
||||
|
||||
ase_str_clear (&run->inrec.line);
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
if (ase_str_ncat (
|
||||
&run->inrec.line,
|
||||
run->global.ofs.ptr,
|
||||
run->global.ofs.len) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == lv)
|
||||
{
|
||||
ase_awk_val_t* tmp;
|
||||
|
||||
run->inrec.flds[i].ptr =
|
||||
ASE_STR_BUF(&run->inrec.line) +
|
||||
ASE_STR_LEN(&run->inrec.line);
|
||||
run->inrec.flds[i].len = len;
|
||||
|
||||
if (ase_str_ncat (
|
||||
&run->inrec.line, str, len) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = ase_awk_makestrval (run, str,len);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i < nflds)
|
||||
ase_awk_refdownval (run, run->inrec.flds[i].val);
|
||||
else run->inrec.nflds++;
|
||||
|
||||
run->inrec.flds[i].val = tmp;
|
||||
ase_awk_refupval (run, tmp);
|
||||
}
|
||||
else if (i >= nflds)
|
||||
{
|
||||
run->inrec.flds[i].ptr =
|
||||
ASE_STR_BUF(&run->inrec.line) +
|
||||
ASE_STR_LEN(&run->inrec.line);
|
||||
run->inrec.flds[i].len = 0;
|
||||
|
||||
if (ase_str_cat (
|
||||
&run->inrec.line, ASE_T("")) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ase_awk_refdownval should not be called over
|
||||
* run->inrec.flds[i].val as it is not initialized
|
||||
* to any valid values */
|
||||
/*ase_awk_refdownval (run, run->inrec.flds[i].val);*/
|
||||
run->inrec.flds[i].val = ase_awk_val_zls;
|
||||
ase_awk_refupval (run, ase_awk_val_zls);
|
||||
run->inrec.nflds++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ase_awk_val_str_t* tmp;
|
||||
|
||||
tmp = (ase_awk_val_str_t*)run->inrec.flds[i].val;
|
||||
|
||||
run->inrec.flds[i].ptr =
|
||||
ASE_STR_BUF(&run->inrec.line) +
|
||||
ASE_STR_LEN(&run->inrec.line);
|
||||
run->inrec.flds[i].len = tmp->len;
|
||||
|
||||
if (ase_str_ncat (&run->inrec.line,
|
||||
tmp->buf, tmp->len) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v = ase_awk_getglobal (run, ASE_AWK_GLOBAL_NF);
|
||||
ASE_ASSERT (v->type == ASE_AWK_VAL_INT);
|
||||
|
||||
if (((ase_awk_val_int_t*)v)->val != max)
|
||||
{
|
||||
v = ase_awk_makeintval (run, (ase_long_t)max);
|
||||
if (v == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ase_awk_setglobal (
|
||||
run, ASE_AWK_GLOBAL_NF, v) == -1) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
1880
ase/awk/rex.c
1880
ase/awk/rex.c
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* $Id: rex.h,v 1.1.1.1 2007/03/28 14:05:17 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_REX_H_
|
||||
#define _ASE_AWK_REX_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Regular Esseression Syntax
|
||||
* A regular expression is zero or more branches, separated by '|'.
|
||||
* ......
|
||||
* ......
|
||||
*
|
||||
* Compiled form of a regular expression:
|
||||
*
|
||||
* | expression |
|
||||
* | header | branch | branch | branch |
|
||||
* | nb | el | na | bl | cmd | arg | cmd | arg | na | bl | cmd | arg | na | bl | cmd |
|
||||
*
|
||||
* nb: the number of branches
|
||||
* el: the length of a expression including the length of nb and el
|
||||
* na: the number of atoms
|
||||
* bl: the length of a branch including the length of na and bl
|
||||
* cmd: The command and repetition info encoded together.
|
||||
* Some commands require an argument to follow them but some other don't.
|
||||
* It is encoded as follows:
|
||||
*
|
||||
* Subexpressions can be nested by having the command "GROUP"
|
||||
* and a subexpression as its argument.
|
||||
*
|
||||
* Examples:
|
||||
* a.c -> |1|6|5|ORD_CHAR(no bound)|a|ANY_CHAR(no bound)|ORD_CHAR(no bound)|c|
|
||||
* ab|xy -> |2|10|4|ORD_CHAR(no bound)|a|ORD_CHAR(no bound)|b|4|ORD_CHAR(no bound)|x|ORD_CHAR(no bound)|y|
|
||||
*/
|
||||
|
||||
#define ASE_AWK_REX_NA(code) (*(ase_size_t*)(code))
|
||||
|
||||
#define ASE_AWK_REX_LEN(code) \
|
||||
(*(ase_size_t*)((ase_byte_t*)(code)+ASE_SIZEOF(ase_size_t)))
|
||||
|
||||
enum ase_awk_rex_opt_t
|
||||
{
|
||||
ASE_AWK_REX_IGNORECASE = (1 << 0)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void* ase_awk_buildrex (
|
||||
ase_awk_t* awk, const ase_char_t* ptn,
|
||||
ase_size_t len, int* errnum);
|
||||
|
||||
int ase_awk_matchrex (
|
||||
ase_awk_t* awk, void* code, int option,
|
||||
const ase_char_t* str, ase_size_t len,
|
||||
const ase_char_t** match_ptr, ase_size_t* match_len, int* errnum);
|
||||
|
||||
void ase_awk_freerex (ase_awk_t* awk, void* code);
|
||||
|
||||
ase_bool_t ase_awk_isemptyrex (ase_awk_t* awk, void* code);
|
||||
|
||||
void ase_awk_dprintrex (ase_awk_t* awk, void* rex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
7046
ase/awk/run.c
7046
ase/awk/run.c
File diff suppressed because it is too large
Load Diff
119
ase/awk/run.h
119
ase/awk/run.h
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* $Id: run.h,v 1.1.1.1 2007/03/28 14:05:20 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_RUN_H_
|
||||
#define _ASE_AWK_RUN_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
enum ase_awk_assop_type_t
|
||||
{
|
||||
/* if you change this, you have to change __assop_str in tree.c */
|
||||
ASE_AWK_ASSOP_NONE,
|
||||
ASE_AWK_ASSOP_PLUS, /* += */
|
||||
ASE_AWK_ASSOP_MINUS, /* -= */
|
||||
ASE_AWK_ASSOP_MUL, /* *= */
|
||||
ASE_AWK_ASSOP_DIV, /* /= */
|
||||
ASE_AWK_ASSOP_IDIV, /* //= */
|
||||
ASE_AWK_ASSOP_MOD, /* %= */
|
||||
ASE_AWK_ASSOP_EXP /* **= */
|
||||
};
|
||||
|
||||
enum ase_awk_binop_type_t
|
||||
{
|
||||
/* if you change this, you have to change
|
||||
* __binop_str in tree.c and __binop_func in run.c accordingly. */
|
||||
ASE_AWK_BINOP_LOR,
|
||||
ASE_AWK_BINOP_LAND,
|
||||
ASE_AWK_BINOP_IN,
|
||||
|
||||
ASE_AWK_BINOP_BOR,
|
||||
ASE_AWK_BINOP_BXOR,
|
||||
ASE_AWK_BINOP_BAND,
|
||||
|
||||
ASE_AWK_BINOP_EQ,
|
||||
ASE_AWK_BINOP_NE,
|
||||
ASE_AWK_BINOP_GT,
|
||||
ASE_AWK_BINOP_GE,
|
||||
ASE_AWK_BINOP_LT,
|
||||
ASE_AWK_BINOP_LE,
|
||||
|
||||
ASE_AWK_BINOP_LSHIFT,
|
||||
ASE_AWK_BINOP_RSHIFT,
|
||||
|
||||
ASE_AWK_BINOP_PLUS,
|
||||
ASE_AWK_BINOP_MINUS,
|
||||
ASE_AWK_BINOP_MUL,
|
||||
ASE_AWK_BINOP_DIV,
|
||||
ASE_AWK_BINOP_IDIV,
|
||||
ASE_AWK_BINOP_MOD,
|
||||
ASE_AWK_BINOP_EXP,
|
||||
|
||||
ASE_AWK_BINOP_CONCAT,
|
||||
ASE_AWK_BINOP_MA,
|
||||
ASE_AWK_BINOP_NM
|
||||
};
|
||||
|
||||
enum ase_awk_unrop_type_t
|
||||
{
|
||||
/* if you change this, you have to change
|
||||
* __unrop_str in tree.c accordingly. */
|
||||
ASE_AWK_UNROP_PLUS,
|
||||
ASE_AWK_UNROP_MINUS,
|
||||
ASE_AWK_UNROP_NOT,
|
||||
ASE_AWK_UNROP_BNOT
|
||||
};
|
||||
|
||||
enum ase_awk_incop_type_t
|
||||
{
|
||||
/* if you change this, you have to change
|
||||
* __incop_str in tree.c accordingly. */
|
||||
ASE_AWK_INCOP_PLUS,
|
||||
ASE_AWK_INCOP_MINUS
|
||||
};
|
||||
|
||||
enum ase_awk_global_id_t
|
||||
{
|
||||
/* this table should match __bvtab in parse.c.
|
||||
* in addition, ase_awk_setglobal also counts
|
||||
* on the order of these values */
|
||||
|
||||
ASE_AWK_GLOBAL_ARGC,
|
||||
ASE_AWK_GLOBAL_ARGV,
|
||||
ASE_AWK_GLOBAL_CONVFMT,
|
||||
ASE_AWK_GLOBAL_ENVIRON,
|
||||
ASE_AWK_GLOBAL_FILENAME,
|
||||
ASE_AWK_GLOBAL_FNR,
|
||||
ASE_AWK_GLOBAL_FS,
|
||||
ASE_AWK_GLOBAL_IGNORECASE,
|
||||
ASE_AWK_GLOBAL_NF,
|
||||
ASE_AWK_GLOBAL_NR,
|
||||
ASE_AWK_GLOBAL_OFILENAME,
|
||||
ASE_AWK_GLOBAL_OFMT,
|
||||
ASE_AWK_GLOBAL_OFS,
|
||||
ASE_AWK_GLOBAL_ORS,
|
||||
ASE_AWK_GLOBAL_RLENGTH,
|
||||
ASE_AWK_GLOBAL_RS,
|
||||
ASE_AWK_GLOBAL_RSTART,
|
||||
ASE_AWK_GLOBAL_SUBSEP
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_char_t* ase_awk_format (
|
||||
ase_awk_run_t* run, ase_str_t* out, ase_str_t* fbu,
|
||||
const ase_char_t* fmt, ase_size_t fmt_len,
|
||||
ase_size_t nargs_on_stack, ase_awk_nde_t* args, ase_size_t* len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
239
ase/awk/tab.c
239
ase/awk/tab.c
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* $Id: tab.c,v 1.1.1.1 2007/03/28 14:05:20 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
ase_awk_tab_t* ase_awk_tab_open (ase_awk_tab_t* tab, ase_awk_t* awk)
|
||||
{
|
||||
if (tab == ASE_NULL)
|
||||
{
|
||||
tab = (ase_awk_tab_t*) ASE_AWK_MALLOC (
|
||||
awk, ASE_SIZEOF(ase_awk_tab_t));
|
||||
if (tab == ASE_NULL) return ASE_NULL;
|
||||
tab->__dynamic = ase_true;
|
||||
}
|
||||
else tab->__dynamic = ase_false;
|
||||
|
||||
tab->awk = awk;
|
||||
tab->buf = ASE_NULL;
|
||||
tab->size = 0;
|
||||
tab->capa = 0;
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
void ase_awk_tab_close (ase_awk_tab_t* tab)
|
||||
{
|
||||
ase_awk_tab_clear (tab);
|
||||
if (tab->buf != ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (tab->awk, tab->buf);
|
||||
tab->buf = ASE_NULL;
|
||||
tab->capa = 0;
|
||||
}
|
||||
|
||||
if (tab->__dynamic) ASE_AWK_FREE (tab->awk, tab);
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_getsize (ase_awk_tab_t* tab)
|
||||
{
|
||||
return tab->size;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_getcapa (ase_awk_tab_t* tab)
|
||||
{
|
||||
return tab->capa;
|
||||
}
|
||||
|
||||
ase_awk_tab_t* ase_awk_tab_setcapa (ase_awk_tab_t* tab, ase_size_t capa)
|
||||
{
|
||||
void* tmp;
|
||||
|
||||
if (tab->size > capa)
|
||||
{
|
||||
ase_awk_tab_remove (tab, capa, tab->size - capa);
|
||||
ASE_ASSERT (tab->size <= capa);
|
||||
}
|
||||
|
||||
if (capa > 0)
|
||||
{
|
||||
if (tab->awk->prmfns.mmgr.realloc != ASE_NULL)
|
||||
{
|
||||
tmp = ASE_AWK_REALLOC (tab->awk,
|
||||
tab->buf, ASE_SIZEOF(*tab->buf) * capa);
|
||||
if (tmp == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = ASE_AWK_MALLOC (
|
||||
tab->awk, ASE_SIZEOF(*tab->buf) * capa);
|
||||
if (tmp == ASE_NULL) return ASE_NULL;
|
||||
if (tab->buf != ASE_NULL)
|
||||
{
|
||||
ase_size_t x;
|
||||
x = (capa > tab->capa)? tab->capa: capa;
|
||||
ase_memcpy (
|
||||
tmp, tab->buf,
|
||||
ASE_SIZEOF(*tab->buf) * x);
|
||||
ASE_AWK_FREE (tab->awk, tab->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tab->buf != ASE_NULL) ASE_AWK_FREE (tab->awk, tab->buf);
|
||||
tmp = ASE_NULL;
|
||||
}
|
||||
|
||||
tab->buf = tmp;
|
||||
tab->capa = capa;
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
void ase_awk_tab_clear (ase_awk_tab_t* tab)
|
||||
{
|
||||
ase_size_t i;
|
||||
|
||||
for (i = 0; i < tab->size; i++)
|
||||
{
|
||||
ASE_AWK_FREE (tab->awk, tab->buf[i].name);
|
||||
tab->buf[i].name = ASE_NULL;
|
||||
tab->buf[i].name_len = 0;
|
||||
}
|
||||
|
||||
tab->size = 0;
|
||||
}
|
||||
|
||||
|
||||
ase_size_t ase_awk_tab_insert (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_size_t i;
|
||||
ase_char_t* str_dup;
|
||||
|
||||
str_dup = ase_strxdup (str, len, &tab->awk->prmfns.mmgr);
|
||||
if (str_dup == ASE_NULL) return (ase_size_t)-1;
|
||||
|
||||
if (index >= tab->capa)
|
||||
{
|
||||
ase_size_t capa;
|
||||
|
||||
if (tab->capa <= 0) capa = (index + 1);
|
||||
else
|
||||
{
|
||||
do { capa = tab->capa * 2; } while (index >= capa);
|
||||
}
|
||||
|
||||
if (ase_awk_tab_setcapa(tab,capa) == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (tab->awk, str_dup);
|
||||
return (ase_size_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1];
|
||||
tab->buf[index].name = str_dup;
|
||||
tab->buf[index].name_len = len;
|
||||
|
||||
if (index > tab->size) tab->size = index + 1;
|
||||
else tab->size++;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_remove (
|
||||
ase_awk_tab_t* tab, ase_size_t index, ase_size_t count)
|
||||
{
|
||||
ase_size_t i, j, k;
|
||||
|
||||
if (index >= tab->size) return 0;
|
||||
if (count > tab->size - index) count = tab->size - index;
|
||||
|
||||
i = index;
|
||||
j = index + count;
|
||||
k = index + count;
|
||||
|
||||
while (i < k)
|
||||
{
|
||||
ASE_AWK_FREE (tab->awk, tab->buf[i].name);
|
||||
|
||||
if (j >= tab->size)
|
||||
{
|
||||
tab->buf[i].name = ASE_NULL;
|
||||
tab->buf[i].name_len = 0;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
tab->buf[i].name = tab->buf[j].name;
|
||||
tab->buf[i].name_len = tab->buf[j].name_len;
|
||||
i++; j++;
|
||||
}
|
||||
}
|
||||
|
||||
tab->size -= count;
|
||||
return count;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_add (
|
||||
ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
return ase_awk_tab_insert (tab, tab->size, str, len);
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_find (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_size_t i;
|
||||
|
||||
for (i = index; i < tab->size; i++)
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
tab->buf[i].name, tab->buf[i].name_len,
|
||||
str, len) == 0) return i;
|
||||
}
|
||||
|
||||
return (ase_size_t)-1;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_rfind (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_size_t i;
|
||||
|
||||
if (index >= tab->size) return (ase_size_t)-1;
|
||||
|
||||
for (i = index + 1; i-- > 0; )
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
tab->buf[i].name, tab->buf[i].name_len,
|
||||
str, len) == 0) return i;
|
||||
}
|
||||
|
||||
return (ase_size_t)-1;
|
||||
}
|
||||
|
||||
ase_size_t ase_awk_tab_rrfind (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
ase_size_t i;
|
||||
|
||||
if (index >= tab->size) return (ase_size_t)-1;
|
||||
|
||||
for (i = tab->size - index; i-- > 0; )
|
||||
{
|
||||
if (ase_strxncmp (
|
||||
tab->buf[i].name, tab->buf[i].name_len,
|
||||
str, len) == 0) return i;
|
||||
}
|
||||
|
||||
return (ase_size_t)-1;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* $Id: tab.h,v 1.1.1.1 2007/03/28 14:05:20 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_TAB_H_
|
||||
#define _ASE_AWK_TAB_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
/* TODO: you have to turn this into a hash table.
|
||||
as of now, this is an arrayed table. */
|
||||
|
||||
typedef struct ase_awk_tab_t ase_awk_tab_t;
|
||||
|
||||
struct ase_awk_tab_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_char_t* name;
|
||||
ase_size_t name_len;
|
||||
}* buf;
|
||||
ase_size_t size;
|
||||
ase_size_t capa;
|
||||
ase_awk_t* awk;
|
||||
ase_bool_t __dynamic;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ase_awk_tab_t* ase_awk_tab_open (ase_awk_tab_t* tab, ase_awk_t* awk);
|
||||
void ase_awk_tab_close (ase_awk_tab_t* tab);
|
||||
|
||||
ase_size_t ase_awk_tab_getsize (ase_awk_tab_t* tab);
|
||||
ase_size_t ase_awk_tab_getcapa (ase_awk_tab_t* tab);
|
||||
ase_awk_tab_t* ase_awk_tab_setcapa (ase_awk_tab_t* tab, ase_size_t capa);
|
||||
|
||||
void ase_awk_tab_clear (ase_awk_tab_t* tab);
|
||||
|
||||
ase_size_t ase_awk_tab_insert (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len);
|
||||
|
||||
ase_size_t ase_awk_tab_remove (
|
||||
ase_awk_tab_t* tab, ase_size_t index, ase_size_t count);
|
||||
|
||||
ase_size_t ase_awk_tab_add (
|
||||
ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len);
|
||||
|
||||
ase_size_t ase_awk_tab_find (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len);
|
||||
ase_size_t ase_awk_tab_rfind (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len);
|
||||
ase_size_t ase_awk_tab_rrfind (
|
||||
ase_awk_tab_t* tab, ase_size_t index,
|
||||
const ase_char_t* str, ase_size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1176
ase/awk/tree.c
1176
ase/awk/tree.c
File diff suppressed because it is too large
Load Diff
403
ase/awk/tree.h
403
ase/awk/tree.h
@ -1,403 +0,0 @@
|
||||
/*
|
||||
* $Id: tree.h,v 1.1.1.1 2007/03/28 14:05:20 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_TREE_H_
|
||||
#define _ASE_AWK_TREE_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Never include this file directly. Include <ase/awk/awk.h> instead
|
||||
#endif
|
||||
|
||||
enum ase_awk_nde_type_t
|
||||
{
|
||||
ASE_AWK_NDE_NULL,
|
||||
|
||||
/* statement */
|
||||
ASE_AWK_NDE_BLK,
|
||||
ASE_AWK_NDE_IF,
|
||||
ASE_AWK_NDE_WHILE,
|
||||
ASE_AWK_NDE_DOWHILE,
|
||||
ASE_AWK_NDE_FOR,
|
||||
ASE_AWK_NDE_FOREACH,
|
||||
ASE_AWK_NDE_BREAK,
|
||||
ASE_AWK_NDE_CONTINUE,
|
||||
ASE_AWK_NDE_RETURN,
|
||||
ASE_AWK_NDE_EXIT,
|
||||
ASE_AWK_NDE_NEXT,
|
||||
ASE_AWK_NDE_NEXTFILE,
|
||||
ASE_AWK_NDE_DELETE,
|
||||
ASE_AWK_NDE_PRINT,
|
||||
ASE_AWK_NDE_PRINTF,
|
||||
|
||||
/* expression */
|
||||
/* if you change the following values including their order,
|
||||
* you should change __eval_func of __eval_expression
|
||||
* in run.c accordingly */
|
||||
ASE_AWK_NDE_GRP,
|
||||
ASE_AWK_NDE_ASS,
|
||||
ASE_AWK_NDE_EXP_BIN,
|
||||
ASE_AWK_NDE_EXP_UNR,
|
||||
ASE_AWK_NDE_EXP_INCPRE,
|
||||
ASE_AWK_NDE_EXP_INCPST,
|
||||
ASE_AWK_NDE_CND,
|
||||
ASE_AWK_NDE_BFN,
|
||||
ASE_AWK_NDE_AFN,
|
||||
ASE_AWK_NDE_INT,
|
||||
ASE_AWK_NDE_REAL,
|
||||
ASE_AWK_NDE_STR,
|
||||
ASE_AWK_NDE_REX,
|
||||
|
||||
/* keep this order for the following items otherwise, you may have
|
||||
* to change __eval_incpre and __eval_incpst in run.c as well as
|
||||
* ASE_AWK_VAL_REF_XXX in val.h */
|
||||
ASE_AWK_NDE_NAMED,
|
||||
ASE_AWK_NDE_GLOBAL,
|
||||
ASE_AWK_NDE_LOCAL,
|
||||
ASE_AWK_NDE_ARG,
|
||||
ASE_AWK_NDE_NAMEDIDX,
|
||||
ASE_AWK_NDE_GLOBALIDX,
|
||||
ASE_AWK_NDE_LOCALIDX,
|
||||
ASE_AWK_NDE_ARGIDX,
|
||||
ASE_AWK_NDE_POS,
|
||||
/* ---------------------------------- */
|
||||
|
||||
ASE_AWK_NDE_GETLINE
|
||||
};
|
||||
|
||||
enum ase_awk_in_type_t
|
||||
{
|
||||
/* the order of these values match
|
||||
* __in_type_map and __in_opt_map in extio.c */
|
||||
|
||||
ASE_AWK_IN_PIPE,
|
||||
ASE_AWK_IN_COPROC,
|
||||
ASE_AWK_IN_FILE,
|
||||
ASE_AWK_IN_CONSOLE
|
||||
};
|
||||
|
||||
enum ase_awk_out_type_t
|
||||
{
|
||||
/* the order of these values match
|
||||
* __out_type_map and __out_opt_map in extio.c */
|
||||
|
||||
ASE_AWK_OUT_PIPE,
|
||||
ASE_AWK_OUT_COPROC,
|
||||
ASE_AWK_OUT_FILE,
|
||||
ASE_AWK_OUT_FILE_APPEND,
|
||||
ASE_AWK_OUT_CONSOLE
|
||||
};
|
||||
|
||||
/* afn (awk function defined with the keyword function) */
|
||||
typedef struct ase_awk_afn_t ase_awk_afn_t;
|
||||
typedef struct ase_awk_nde_t ase_awk_nde_t;
|
||||
typedef struct ase_awk_nde_blk_t ase_awk_nde_blk_t;
|
||||
typedef struct ase_awk_nde_grp_t ase_awk_nde_grp_t;
|
||||
typedef struct ase_awk_nde_ass_t ase_awk_nde_ass_t;
|
||||
typedef struct ase_awk_nde_exp_t ase_awk_nde_exp_t;
|
||||
typedef struct ase_awk_nde_cnd_t ase_awk_nde_cnd_t;
|
||||
typedef struct ase_awk_nde_pos_t ase_awk_nde_pos_t;
|
||||
|
||||
#ifndef ASE_AWK_NDE_INT_DEFINED
|
||||
#define ASE_AWK_NDE_INT_DEFINED
|
||||
typedef struct ase_awk_nde_int_t ase_awk_nde_int_t;
|
||||
#endif
|
||||
|
||||
#ifndef ASE_AWK_NDE_REAL_DEFINED
|
||||
#define ASE_AWK_NDE_REAL_DEFINED
|
||||
typedef struct ase_awk_nde_real_t ase_awk_nde_real_t;
|
||||
#endif
|
||||
|
||||
typedef struct ase_awk_nde_str_t ase_awk_nde_str_t;
|
||||
typedef struct ase_awk_nde_rex_t ase_awk_nde_rex_t;
|
||||
typedef struct ase_awk_nde_var_t ase_awk_nde_var_t;
|
||||
typedef struct ase_awk_nde_call_t ase_awk_nde_call_t;
|
||||
typedef struct ase_awk_nde_getline_t ase_awk_nde_getline_t;
|
||||
|
||||
typedef struct ase_awk_nde_if_t ase_awk_nde_if_t;
|
||||
typedef struct ase_awk_nde_while_t ase_awk_nde_while_t;
|
||||
typedef struct ase_awk_nde_for_t ase_awk_nde_for_t;
|
||||
typedef struct ase_awk_nde_foreach_t ase_awk_nde_foreach_t;
|
||||
typedef struct ase_awk_nde_break_t ase_awk_nde_break_t;
|
||||
typedef struct ase_awk_nde_continue_t ase_awk_nde_continue_t;
|
||||
typedef struct ase_awk_nde_return_t ase_awk_nde_return_t;
|
||||
typedef struct ase_awk_nde_exit_t ase_awk_nde_exit_t;
|
||||
typedef struct ase_awk_nde_next_t ase_awk_nde_next_t;
|
||||
typedef struct ase_awk_nde_nextfile_t ase_awk_nde_nextfile_t;
|
||||
typedef struct ase_awk_nde_delete_t ase_awk_nde_delete_t;
|
||||
typedef struct ase_awk_nde_print_t ase_awk_nde_print_t;
|
||||
|
||||
struct ase_awk_afn_t
|
||||
{
|
||||
ase_char_t* name;
|
||||
ase_size_t name_len;
|
||||
ase_size_t nargs;
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
#define ASE_AWK_NDE_HDR \
|
||||
int type; \
|
||||
ase_size_t line; \
|
||||
ase_awk_nde_t* next
|
||||
|
||||
struct ase_awk_nde_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_BLK - block statement including top-level blocks */
|
||||
struct ase_awk_nde_blk_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_size_t nlocals;
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_GRP - expression group */
|
||||
struct ase_awk_nde_grp_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_ASS - assignment */
|
||||
struct ase_awk_nde_ass_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
int opcode;
|
||||
ase_awk_nde_t* left;
|
||||
ase_awk_nde_t* right;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_EXP_BIN, ASE_AWK_NDE_EXP_UNR,
|
||||
* ASE_AWK_NDE_EXP_INCPRE, ASE_AW_NDE_EXP_INCPST */
|
||||
struct ase_awk_nde_exp_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
int opcode;
|
||||
ase_awk_nde_t* left;
|
||||
ase_awk_nde_t* right; /* ASE_NULL for UNR, INCPRE, INCPST */
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_CND */
|
||||
struct ase_awk_nde_cnd_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* test;
|
||||
ase_awk_nde_t* left;
|
||||
ase_awk_nde_t* right;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_POS - positional - $1, $2, $x, etc */
|
||||
struct ase_awk_nde_pos_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* val;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_INT */
|
||||
struct ase_awk_nde_int_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_long_t val;
|
||||
ase_char_t* str;
|
||||
ase_size_t len;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_REAL */
|
||||
struct ase_awk_nde_real_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_real_t val;
|
||||
ase_char_t* str;
|
||||
ase_size_t len;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_STR */
|
||||
struct ase_awk_nde_str_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_char_t* buf;
|
||||
ase_size_t len;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_REX */
|
||||
struct ase_awk_nde_rex_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_char_t* buf;
|
||||
ase_size_t len;
|
||||
void* code;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_NAMED, ASE_AWK_NDE_GLOBAL,
|
||||
* ASE_AWK_NDE_LOCAL, ASE_AWK_NDE_ARG
|
||||
* ASE_AWK_NDE_NAMEDIDX, ASE_AWK_NDE_GLOBALIDX,
|
||||
* ASE_AWK_NDE_LOCALIDX, ASE_AWK_NDE_ARGIDX */
|
||||
struct ase_awk_nde_var_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
struct
|
||||
{
|
||||
ase_char_t* name;
|
||||
ase_size_t name_len;
|
||||
ase_size_t idxa;
|
||||
} id;
|
||||
ase_awk_nde_t* idx; /* ASE_NULL for non-XXXXIDX */
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_BFN, ASE_AWK_NDE_AFN */
|
||||
struct ase_awk_nde_call_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} name;
|
||||
} afn;
|
||||
|
||||
/* minimum information of a built-in function
|
||||
* needed during run-time. */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
const ase_char_t* ptr;
|
||||
ase_size_t len;
|
||||
} name;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t min;
|
||||
ase_size_t max;
|
||||
const ase_char_t* spec;
|
||||
} arg;
|
||||
|
||||
int (*handler) (
|
||||
ase_awk_run_t*, const ase_char_t*, ase_size_t);
|
||||
} bfn;
|
||||
} what;
|
||||
ase_awk_nde_t* args;
|
||||
ase_size_t nargs;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_GETLINE */
|
||||
struct ase_awk_nde_getline_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* var;
|
||||
int in_type; /* ASE_AWK_GETLINE_XXX */
|
||||
ase_awk_nde_t* in;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_IF */
|
||||
struct ase_awk_nde_if_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* test;
|
||||
ase_awk_nde_t* then_part;
|
||||
ase_awk_nde_t* else_part; /* optional */
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_WHILE, ASE_AWK_NDE_DOWHILE */
|
||||
struct ase_awk_nde_while_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* test;
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_FOR */
|
||||
struct ase_awk_nde_for_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* init; /* optional */
|
||||
ase_awk_nde_t* test; /* optional */
|
||||
ase_awk_nde_t* incr; /* optional */
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_FOREACH */
|
||||
struct ase_awk_nde_foreach_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* test;
|
||||
ase_awk_nde_t* body;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_BREAK */
|
||||
struct ase_awk_nde_break_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_CONTINUE */
|
||||
struct ase_awk_nde_continue_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_RETURN */
|
||||
struct ase_awk_nde_return_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* val; /* optional (no return code if ASE_NULL) */
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_EXIT */
|
||||
struct ase_awk_nde_exit_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* val; /* optional (no exit code if ASE_NULL) */
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_NEXT */
|
||||
struct ase_awk_nde_next_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_NEXTFILE */
|
||||
struct ase_awk_nde_nextfile_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
int out;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_DELETE */
|
||||
struct ase_awk_nde_delete_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* var;
|
||||
};
|
||||
|
||||
/* ASE_AWK_NDE_PRINT */
|
||||
struct ase_awk_nde_print_t
|
||||
{
|
||||
ASE_AWK_NDE_HDR;
|
||||
ase_awk_nde_t* args;
|
||||
int out_type; /* ASE_AWK_OUT_XXX */
|
||||
ase_awk_nde_t* out;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ase_awk_prnpt (ase_awk_t* awk, ase_awk_nde_t* tree);
|
||||
int ase_awk_prnptnpt (ase_awk_t* awk, ase_awk_nde_t* tree);
|
||||
|
||||
void ase_awk_clrpt (ase_awk_t* awk, ase_awk_nde_t* tree);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
839
ase/awk/val.c
839
ase/awk/val.c
@ -1,839 +0,0 @@
|
||||
/*
|
||||
* $Id: val.c,v 1.1.1.1 2007/03/28 14:05:20 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
#include <ase/utl/stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
static ase_char_t* str_to_str (
|
||||
ase_awk_run_t* run, const ase_char_t* str, ase_size_t str_len,
|
||||
int opt, ase_str_t* buf, ase_size_t* len);
|
||||
static ase_char_t* val_int_to_str (
|
||||
ase_awk_run_t* run, ase_awk_val_int_t* v,
|
||||
int opt, ase_str_t* buf, ase_size_t* len);
|
||||
static ase_char_t* val_real_to_str (
|
||||
ase_awk_run_t* run, ase_awk_val_real_t* v,
|
||||
int opt, ase_str_t* buf, ase_size_t* len);
|
||||
|
||||
static ase_awk_val_nil_t awk_nil = { ASE_AWK_VAL_NIL, 0 };
|
||||
static ase_awk_val_str_t awk_zls = { ASE_AWK_VAL_STR, 0, ASE_T(""), 0 };
|
||||
|
||||
ase_awk_val_t* ase_awk_val_nil = (ase_awk_val_t*)&awk_nil;
|
||||
ase_awk_val_t* ase_awk_val_zls = (ase_awk_val_t*)&awk_zls;
|
||||
|
||||
static ase_awk_val_int_t awk_int[] =
|
||||
{
|
||||
{ ASE_AWK_VAL_INT, 0, -1, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 0, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 1, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 2, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 3, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 4, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 5, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 6, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 7, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 8, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 9, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 10, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 11, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 12, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 13, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 14, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 15, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 16, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 17, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 18, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 19, ASE_NULL },
|
||||
{ ASE_AWK_VAL_INT, 0, 20, ASE_NULL }
|
||||
};
|
||||
|
||||
ase_awk_val_t* ase_awk_val_negone = (ase_awk_val_t*)&awk_int[0];
|
||||
ase_awk_val_t* ase_awk_val_zero = (ase_awk_val_t*)&awk_int[1];
|
||||
ase_awk_val_t* ase_awk_val_one = (ase_awk_val_t*)&awk_int[2];
|
||||
|
||||
ase_awk_val_t* ase_awk_makeintval (ase_awk_run_t* run, ase_long_t v)
|
||||
{
|
||||
ase_awk_val_int_t* val;
|
||||
|
||||
if (v >= awk_int[0].val &&
|
||||
v <= awk_int[ASE_COUNTOF(awk_int)-1].val)
|
||||
{
|
||||
return (ase_awk_val_t*)&awk_int[v-awk_int[0].val];
|
||||
}
|
||||
|
||||
if (run->icache_count > 0)
|
||||
{
|
||||
val = run->icache[--run->icache_count];
|
||||
}
|
||||
else
|
||||
{
|
||||
val = (ase_awk_val_int_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_val_int_t));
|
||||
if (val == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
val->type = ASE_AWK_VAL_INT;
|
||||
val->ref = 0;
|
||||
val->val = v;
|
||||
val->nde = ASE_NULL;
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("makeintval => %p\n"), val);
|
||||
#endif
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makerealval (ase_awk_run_t* run, ase_real_t v)
|
||||
{
|
||||
ase_awk_val_real_t* val;
|
||||
|
||||
if (run->rcache_count > 0)
|
||||
{
|
||||
val = run->rcache[--run->rcache_count];
|
||||
}
|
||||
else
|
||||
{
|
||||
val = (ase_awk_val_real_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_val_real_t));
|
||||
if (val == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
val->type = ASE_AWK_VAL_REAL;
|
||||
val->ref = 0;
|
||||
val->val = v;
|
||||
val->nde = ASE_NULL;
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("makerealval => %p\n"), val);
|
||||
#endif
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makestrval0 (ase_awk_run_t* run, const ase_char_t* str)
|
||||
{
|
||||
return ase_awk_makestrval (run, str, ase_strlen(str));
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makestrval (
|
||||
ase_awk_run_t* run, const ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
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) return ASE_NULL;
|
||||
|
||||
val->type = ASE_AWK_VAL_STR;
|
||||
val->ref = 0;
|
||||
val->len = len;
|
||||
val->buf = ase_strxdup (str, len, &run->awk->prmfns.mmgr);
|
||||
if (val->buf == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("makestrval => %p\n"), val);
|
||||
#endif
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makestrval_nodup (
|
||||
ase_awk_run_t* run, ase_char_t* str, ase_size_t len)
|
||||
{
|
||||
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) return ASE_NULL;
|
||||
|
||||
val->type = ASE_AWK_VAL_STR;
|
||||
val->ref = 0;
|
||||
val->len = len;
|
||||
val->buf = str;
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makestrval2 (
|
||||
ase_awk_run_t* run,
|
||||
const ase_char_t* str1, ase_size_t len1,
|
||||
const ase_char_t* str2, ase_size_t len2)
|
||||
{
|
||||
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) return ASE_NULL;
|
||||
|
||||
val->type = ASE_AWK_VAL_STR;
|
||||
val->ref = 0;
|
||||
val->len = len1 + len2;
|
||||
val->buf = ase_strxdup2 (str1, len1, str2, len2, &run->awk->prmfns.mmgr);
|
||||
if (val->buf == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("makestrval2 => %p\n"), val);
|
||||
#endif
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makerexval (
|
||||
ase_awk_run_t* run, const ase_char_t* buf, ase_size_t len, void* code)
|
||||
{
|
||||
ase_awk_val_rex_t* val;
|
||||
|
||||
val = (ase_awk_val_rex_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_val_rex_t));
|
||||
if (val == ASE_NULL) return ASE_NULL;
|
||||
|
||||
val->type = ASE_AWK_VAL_REX;
|
||||
val->ref = 0;
|
||||
val->len = len;
|
||||
val->buf = ase_strxdup (buf, len, &run->awk->prmfns.mmgr);
|
||||
if (val->buf == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
val->code = ASE_AWK_MALLOC (run->awk, ASE_AWK_REX_LEN(code));
|
||||
if (val->code == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val->buf);
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
ase_memcpy (val->code, code, ASE_AWK_REX_LEN(code));
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
static void free_map_val (void* run, void* v)
|
||||
{
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("refdown in map free..."));
|
||||
ase_awk_dprintval (run, v);
|
||||
ase_dprintf (ASE_T("\n"));
|
||||
#endif
|
||||
|
||||
ase_awk_refdownval (run, v);
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makemapval (ase_awk_run_t* run)
|
||||
{
|
||||
ase_awk_val_map_t* val;
|
||||
|
||||
val = (ase_awk_val_map_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_val_map_t));
|
||||
if (val == ASE_NULL) return ASE_NULL;
|
||||
|
||||
val->type = ASE_AWK_VAL_MAP;
|
||||
val->ref = 0;
|
||||
val->map = ase_awk_map_open (
|
||||
ASE_NULL, run, 256, free_map_val, run->awk);
|
||||
if (val->map == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_awk_val_t* ase_awk_makerefval (ase_awk_run_t* run, int id, ase_awk_val_t** adr)
|
||||
{
|
||||
ase_awk_val_ref_t* val;
|
||||
|
||||
if (run->fcache_count > 0)
|
||||
{
|
||||
val = run->fcache[--run->fcache_count];
|
||||
}
|
||||
else
|
||||
{
|
||||
val = (ase_awk_val_ref_t*) ASE_AWK_MALLOC (
|
||||
run->awk, ASE_SIZEOF(ase_awk_val_ref_t));
|
||||
if (val == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
val->type = ASE_AWK_VAL_REF;
|
||||
val->ref = 0;
|
||||
val->id = id;
|
||||
val->adr = adr;
|
||||
|
||||
return (ase_awk_val_t*)val;
|
||||
}
|
||||
|
||||
ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val)
|
||||
{
|
||||
return val == ASE_NULL ||
|
||||
val == ase_awk_val_nil ||
|
||||
val == ase_awk_val_zls ||
|
||||
val == ase_awk_val_zero ||
|
||||
val == ase_awk_val_one ||
|
||||
(val >= (ase_awk_val_t*)&awk_int[0] &&
|
||||
val <= (ase_awk_val_t*)&awk_int[ASE_COUNTOF(awk_int)-1]);
|
||||
}
|
||||
|
||||
void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache)
|
||||
{
|
||||
if (ase_awk_isbuiltinval(val)) return;
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("freeing [cache=%d] ... "), cache);
|
||||
ase_awk_dprintval (run, val);
|
||||
ase_dprintf (ASE_T("\n"));
|
||||
#endif
|
||||
|
||||
if (val->type == ASE_AWK_VAL_NIL)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
else if (val->type == ASE_AWK_VAL_INT)
|
||||
{
|
||||
if (cache == ase_true &&
|
||||
run->icache_count < ASE_COUNTOF(run->icache))
|
||||
{
|
||||
run->icache[run->icache_count++] =
|
||||
(ase_awk_val_int_t*)val;
|
||||
}
|
||||
else ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
else if (val->type == ASE_AWK_VAL_REAL)
|
||||
{
|
||||
if (cache == ase_true &&
|
||||
run->rcache_count < ASE_COUNTOF(run->rcache))
|
||||
{
|
||||
run->rcache[run->rcache_count++] =
|
||||
(ase_awk_val_real_t*)val;
|
||||
}
|
||||
else ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
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, val);
|
||||
}
|
||||
else if (val->type == ASE_AWK_VAL_REX)
|
||||
{
|
||||
ASE_AWK_FREE (run->awk, ((ase_awk_val_rex_t*)val)->buf);
|
||||
ase_awk_freerex (run->awk, ((ase_awk_val_rex_t*)val)->code);
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
else if (val->type == ASE_AWK_VAL_MAP)
|
||||
{
|
||||
ase_awk_map_close (((ase_awk_val_map_t*)val)->map);
|
||||
ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
else if (val->type == ASE_AWK_VAL_REF)
|
||||
{
|
||||
if (cache == ase_true &&
|
||||
run->fcache_count < ASE_COUNTOF(run->fcache))
|
||||
{
|
||||
run->fcache[run->fcache_count++] =
|
||||
(ase_awk_val_ref_t*)val;
|
||||
}
|
||||
else ASE_AWK_FREE (run->awk, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASE_ASSERTX (
|
||||
!"should never happen - invalid value type",
|
||||
"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h");
|
||||
}
|
||||
}
|
||||
|
||||
void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val)
|
||||
{
|
||||
if (ase_awk_isbuiltinval(val)) return;
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("ref up [ptr=%p] [count=%d] "), val, (int)val->ref);
|
||||
ase_awk_dprintval (run, val);
|
||||
ase_dprintf (ASE_T("\n"));
|
||||
#endif
|
||||
|
||||
val->ref++;
|
||||
}
|
||||
|
||||
void ase_awk_refdownval (ase_awk_run_t* run, ase_awk_val_t* val)
|
||||
{
|
||||
if (ase_awk_isbuiltinval(val)) return;
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (ASE_T("ref down [ptr=%p] [count=%d]\n"), val, (int)val->ref);
|
||||
ase_awk_dprintval (run, val);
|
||||
ase_dprintf (ASE_T("\n"));
|
||||
#endif
|
||||
|
||||
ASE_ASSERTX (val->ref > 0,
|
||||
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
|
||||
|
||||
val->ref--;
|
||||
if (val->ref <= 0)
|
||||
{
|
||||
ase_awk_freeval(run, val, ase_true);
|
||||
}
|
||||
}
|
||||
|
||||
void ase_awk_refdownval_nofree (ase_awk_run_t* run, ase_awk_val_t* val)
|
||||
{
|
||||
if (ase_awk_isbuiltinval(val)) return;
|
||||
|
||||
ASE_ASSERTX (val->ref > 0,
|
||||
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
|
||||
val->ref--;
|
||||
}
|
||||
|
||||
ase_bool_t ase_awk_valtobool (ase_awk_run_t* run, ase_awk_val_t* val)
|
||||
{
|
||||
if (val == ASE_NULL) return ase_false;
|
||||
|
||||
switch (val->type)
|
||||
{
|
||||
case ASE_AWK_VAL_NIL:
|
||||
return ase_false;
|
||||
case ASE_AWK_VAL_INT:
|
||||
return ((ase_awk_val_int_t*)val)->val != 0;
|
||||
case ASE_AWK_VAL_REAL:
|
||||
return ((ase_awk_val_real_t*)val)->val != 0.0;
|
||||
case ASE_AWK_VAL_STR:
|
||||
return ((ase_awk_val_str_t*)val)->len > 0;
|
||||
case ASE_AWK_VAL_REX: /* TODO: is this correct? */
|
||||
return ((ase_awk_val_rex_t*)val)->len > 0;
|
||||
case ASE_AWK_VAL_MAP:
|
||||
return ase_false; /* TODO: is this correct? */
|
||||
case ASE_AWK_VAL_REF:
|
||||
return ase_false; /* TODO: is this correct? */
|
||||
}
|
||||
|
||||
ASE_ASSERTX (
|
||||
!"should never happen - invalid value type",
|
||||
"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h");
|
||||
return ase_false;
|
||||
}
|
||||
|
||||
ase_char_t* ase_awk_valtostr (
|
||||
ase_awk_run_t* run, ase_awk_val_t* v,
|
||||
int opt, ase_str_t* buf, ase_size_t* len)
|
||||
{
|
||||
if (v->type == ASE_AWK_VAL_NIL)
|
||||
{
|
||||
return str_to_str (run, ASE_T(""), 0, opt, buf, len);
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_INT)
|
||||
{
|
||||
ase_awk_val_int_t* vi = (ase_awk_val_int_t*)v;
|
||||
|
||||
/*
|
||||
if (vi->nde != ASE_NULL && vi->nde->str != ASE_NULL)
|
||||
{
|
||||
return str_to_str (
|
||||
run, vi->nde->str, vi->nde->len,
|
||||
opt, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
return val_int_to_str (run, vi, opt, buf, len);
|
||||
/*}*/
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_REAL)
|
||||
{
|
||||
ase_awk_val_real_t* vr = (ase_awk_val_real_t*)v;
|
||||
|
||||
/*
|
||||
if (vr->nde != ASE_NULL && vr->nde->str != ASE_NULL)
|
||||
{
|
||||
return str_to_str (
|
||||
run, vr->nde->str, vr->nde->len,
|
||||
opt, buf, len);
|
||||
}
|
||||
else
|
||||
{*/
|
||||
return val_real_to_str (run, vr, opt, buf, len);
|
||||
/*}*/
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_STR)
|
||||
{
|
||||
ase_awk_val_str_t* vs = (ase_awk_val_str_t*)v;
|
||||
|
||||
return str_to_str (
|
||||
run, vs->buf, vs->len, opt, buf, len);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (
|
||||
ASE_T("ERROR: WRONG VALUE TYPE [%d] in ase_awk_valtostr\n"),
|
||||
v->type);
|
||||
#endif
|
||||
|
||||
ase_awk_setrunerror (run, ASE_AWK_EVALTYPE, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
static ase_char_t* str_to_str (
|
||||
ase_awk_run_t* run, const ase_char_t* str, ase_size_t str_len,
|
||||
int opt, ase_str_t* buf, ase_size_t* len)
|
||||
{
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
ase_char_t* tmp;
|
||||
tmp = ase_strxdup (str, str_len, &run->awk->prmfns.mmgr);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (len != ASE_NULL) *len = str_len;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
ase_size_t n;
|
||||
|
||||
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_str_clear (buf);
|
||||
n = ase_str_ncat (buf, str, str_len);
|
||||
if (n == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (len != ASE_NULL) *len = ASE_STR_LEN(buf);
|
||||
return ASE_STR_BUF(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static ase_char_t* val_int_to_str (
|
||||
ase_awk_run_t* run, ase_awk_val_int_t* v,
|
||||
int opt, ase_str_t* buf, ase_size_t* len)
|
||||
{
|
||||
ase_char_t* tmp;
|
||||
ase_long_t t;
|
||||
ase_size_t l = 0;
|
||||
|
||||
t = v->val;
|
||||
if (t == 0)
|
||||
{
|
||||
/* handle zero */
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
tmp = ASE_AWK_MALLOC (
|
||||
run->awk, 2 * ASE_SIZEOF(ase_char_t));
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
tmp[0] = ASE_T('0');
|
||||
tmp[1] = ASE_T('\0');
|
||||
if (len != ASE_NULL) *len = 1;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_str_clear (buf);
|
||||
if (ase_str_cat (buf, ASE_T("0")) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (len != ASE_NULL) *len = ASE_STR_LEN(buf);
|
||||
return ASE_STR_BUF(buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* non-zero values */
|
||||
if (t < 0) { t = -t; l++; }
|
||||
while (t > 0) { l++; t /= 10; }
|
||||
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
tmp = ASE_AWK_MALLOC (
|
||||
run->awk, (l + 1) * ASE_SIZEOF(ase_char_t));
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
tmp[l] = ASE_T('\0');
|
||||
if (len != ASE_NULL) *len = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear the buffer */
|
||||
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_str_clear (buf);
|
||||
|
||||
tmp = ASE_STR_BUF(buf) + ASE_STR_LEN(buf);
|
||||
|
||||
/* extend the buffer */
|
||||
if (ase_str_nccat (
|
||||
buf, ASE_T(' '), l) == (ase_size_t)-1)
|
||||
{
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
t = v->val;
|
||||
if (t < 0) t = -t;
|
||||
|
||||
while (t > 0)
|
||||
{
|
||||
tmp[--l] = (ase_char_t)(t % 10) + ASE_T('0');
|
||||
t /= 10;
|
||||
}
|
||||
|
||||
if (v->val < 0) tmp[--l] = ASE_T('-');
|
||||
|
||||
if (buf != ASE_NULL)
|
||||
{
|
||||
tmp = ASE_STR_BUF(buf);
|
||||
if (len != ASE_NULL) *len = ASE_STR_LEN(buf);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static ase_char_t* val_real_to_str (
|
||||
ase_awk_run_t* run, ase_awk_val_real_t* v,
|
||||
int opt, ase_str_t* buf, ase_size_t* len)
|
||||
{
|
||||
ase_char_t* tmp;
|
||||
ase_size_t tmp_len;
|
||||
ase_str_t out, fbu;
|
||||
|
||||
if (opt & ASE_AWK_VALTOSTR_PRINT)
|
||||
{
|
||||
tmp = run->global.ofmt.ptr;
|
||||
tmp_len = run->global.ofmt.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = run->global.convfmt.ptr;
|
||||
tmp_len = run->global.convfmt.len;
|
||||
}
|
||||
|
||||
if (ase_str_open (&out, 256, &run->awk->prmfns.mmgr) == ASE_NULL)
|
||||
{
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (ase_str_open (&fbu, 256, &run->awk->prmfns.mmgr) == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&out);
|
||||
ase_awk_setrunerror (run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
tmp = ase_awk_format (run, &out, &fbu, tmp, tmp_len,
|
||||
(ase_size_t)-1, (ase_awk_nde_t*)v, &tmp_len);
|
||||
if (tmp == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&fbu);
|
||||
ase_str_close (&out);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
if (buf == ASE_NULL)
|
||||
{
|
||||
ase_str_close (&fbu);
|
||||
ase_str_forfeit (&out);
|
||||
if (len != ASE_NULL) *len = tmp_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_str_clear (buf);
|
||||
|
||||
if (ase_str_ncat (buf, tmp, tmp_len) == (ase_size_t)-1)
|
||||
{
|
||||
ase_str_close (&fbu);
|
||||
ase_str_close (&out);
|
||||
ase_awk_setrunerror (
|
||||
run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0);
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
tmp = ASE_STR_BUF(buf);
|
||||
if (len != ASE_NULL) *len = ASE_STR_LEN(buf);
|
||||
|
||||
ase_str_close (&fbu);
|
||||
ase_str_close (&out);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int ase_awk_valtonum (
|
||||
ase_awk_run_t* run, ase_awk_val_t* v, ase_long_t* l, ase_real_t* r)
|
||||
{
|
||||
if (v->type == ASE_AWK_VAL_NIL)
|
||||
{
|
||||
*l = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_INT)
|
||||
{
|
||||
*l = ((ase_awk_val_int_t*)v)->val;
|
||||
return 0; /* long */
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_REAL)
|
||||
{
|
||||
*r = ((ase_awk_val_real_t*)v)->val;
|
||||
return 1; /* real */
|
||||
}
|
||||
|
||||
if (v->type == ASE_AWK_VAL_STR)
|
||||
{
|
||||
return ase_awk_strtonum (run,
|
||||
((ase_awk_val_str_t*)v)->buf,
|
||||
((ase_awk_val_str_t*)v)->len, l, r);
|
||||
|
||||
#if 0
|
||||
const ase_char_t* endptr;
|
||||
|
||||
*l = ase_awk_strxtolong (run->awk,
|
||||
((ase_awk_val_str_t*)v)->buf,
|
||||
((ase_awk_val_str_t*)v)->len, 0, &endptr);
|
||||
if (*endptr == ASE_T('.') ||
|
||||
*endptr == ASE_T('E') ||
|
||||
*endptr == ASE_T('e'))
|
||||
{
|
||||
*r = ase_awk_strxtoreal (run->awk,
|
||||
((ase_awk_val_str_t*)v)->buf,
|
||||
((ase_awk_val_str_t*)v)->len, ASE_NULL);
|
||||
/* TODO: need to check if it is a valid number using endptr for strxtoreal? */
|
||||
return 1; /* real */
|
||||
}
|
||||
/* TODO: do should i handle strings ending with invalid number characters like "123xx" or "dkdkdkd"? */
|
||||
return 0; /* long */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VAL
|
||||
ase_dprintf (
|
||||
ASE_T("ERROR: WRONG VALUE TYPE [%d] in ase_awk_valtonum\n"),
|
||||
v->type);
|
||||
#endif
|
||||
|
||||
ase_awk_setrunerror (run, ASE_AWK_EVALTYPE, 0, ASE_NULL, 0);
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
int ase_awk_strtonum (
|
||||
ase_awk_run_t* run, const ase_char_t* ptr, ase_size_t len,
|
||||
ase_long_t* l, ase_real_t* r)
|
||||
{
|
||||
const ase_char_t* endptr;
|
||||
|
||||
*l = ase_awk_strxtolong (run->awk, ptr, len, 0, &endptr);
|
||||
if (*endptr == ASE_T('.') ||
|
||||
*endptr == ASE_T('E') ||
|
||||
*endptr == ASE_T('e'))
|
||||
{
|
||||
*r = ase_awk_strxtoreal (run->awk, ptr, len, ASE_NULL);
|
||||
/* TODO: need to check if it is a valid number using endptr for strxtoreal? */
|
||||
return 1; /* real */
|
||||
}
|
||||
/* TODO: do should i handle strings ending with invalid number characters like "123xx" or "dkdkdkd"? */
|
||||
return 0; /* long */
|
||||
|
||||
}
|
||||
|
||||
#define DPRINTF run->awk->prmfns.misc.dprintf
|
||||
#define DCUSTOM run->awk->prmfns.misc.custom_data
|
||||
|
||||
static int print_pair (ase_awk_pair_t* pair, void* arg)
|
||||
{
|
||||
ase_awk_run_t* run = (ase_awk_run_t*)arg;
|
||||
|
||||
DPRINTF (DCUSTOM, ASE_T(" %s=>"), pair->key);
|
||||
ase_awk_dprintval ((ase_awk_run_t*)arg, pair->val);
|
||||
DPRINTF (DCUSTOM, ASE_T(" "));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ase_awk_dprintval (ase_awk_run_t* run, ase_awk_val_t* val)
|
||||
{
|
||||
/* TODO: better value printing ... */
|
||||
|
||||
switch (val->type)
|
||||
{
|
||||
case ASE_AWK_VAL_NIL:
|
||||
DPRINTF (DCUSTOM, ASE_T("nil"));
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_INT:
|
||||
#if ASE_SIZEOF_LONG_LONG > 0
|
||||
DPRINTF (DCUSTOM, ASE_T("%lld"),
|
||||
(long long)((ase_awk_val_int_t*)val)->val);
|
||||
#elif ASE_SIZEOF___INT64 > 0
|
||||
DPRINTF (DCUSTOM, ASE_T("%I64d"),
|
||||
(__int64)((ase_awk_val_int_t*)val)->val);
|
||||
#elif ASE_SIZEOF_LONG > 0
|
||||
DPRINTF (DCUSTOM, ASE_T("%ld"),
|
||||
(long)((ase_awk_val_int_t*)val)->val);
|
||||
#elif ASE_SIZEOF_INT > 0
|
||||
DPRINTF (DCUSTOM, ASE_T("%d"),
|
||||
(int)((ase_awk_val_int_t*)val)->val);
|
||||
#else
|
||||
#error unsupported size
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_REAL:
|
||||
DPRINTF (DCUSTOM, ASE_T("%Lf"),
|
||||
(long double)((ase_awk_val_real_t*)val)->val);
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_STR:
|
||||
DPRINTF (DCUSTOM, ASE_T("%s"), ((ase_awk_val_str_t*)val)->buf);
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_REX:
|
||||
DPRINTF (DCUSTOM, ASE_T("REX[%s]"), ((ase_awk_val_rex_t*)val)->buf);
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_MAP:
|
||||
DPRINTF (DCUSTOM, ASE_T("MAP["));
|
||||
ase_awk_map_walk (((ase_awk_val_map_t*)val)->map, print_pair, run);
|
||||
DPRINTF (DCUSTOM, ASE_T("]"));
|
||||
break;
|
||||
|
||||
case ASE_AWK_VAL_REF:
|
||||
DPRINTF (DCUSTOM, ASE_T("REF[id=%d,val="), ((ase_awk_val_ref_t*)val)->id);
|
||||
ase_awk_dprintval (run, *((ase_awk_val_ref_t*)val)->adr);
|
||||
DPRINTF (DCUSTOM, ASE_T("]"));
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF (DCUSTOM, ASE_T("**** INTERNAL ERROR - INVALID VALUE TYPE ****\n"));
|
||||
}
|
||||
}
|
206
ase/awk/val.h
206
ase/awk/val.h
@ -1,206 +0,0 @@
|
||||
/*
|
||||
* $Id: val.h,v 1.1.1.1 2007/03/28 14:05:21 bacon Exp $
|
||||
*
|
||||
* {License}
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_VAL_H_
|
||||
#define _ASE_AWK_VAL_H_
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
#error Include <ase/awk/awk.h> first
|
||||
#endif
|
||||
|
||||
#include <ase/cmn/str.h>
|
||||
#include <ase/awk/map.h>
|
||||
|
||||
enum ase_awk_val_type_t
|
||||
{
|
||||
/* the values between ASE_AWK_VAL_NIL and ASE_AWK_VAL_STR inclusive
|
||||
* must be synchronized with an internal table of the __cmp_val
|
||||
* function in run.c */
|
||||
ASE_AWK_VAL_NIL = 0,
|
||||
ASE_AWK_VAL_INT = 1,
|
||||
ASE_AWK_VAL_REAL = 2,
|
||||
ASE_AWK_VAL_STR = 3,
|
||||
|
||||
ASE_AWK_VAL_REX = 4,
|
||||
ASE_AWK_VAL_MAP = 5,
|
||||
ASE_AWK_VAL_REF = 6
|
||||
};
|
||||
|
||||
enum ase_awk_val_ref_id_t
|
||||
{
|
||||
/* keep these items in the same order as corresponding items
|
||||
* in tree.h */
|
||||
ASE_AWK_VAL_REF_NAMED,
|
||||
ASE_AWK_VAL_REF_GLOBAL,
|
||||
ASE_AWK_VAL_REF_LOCAL,
|
||||
ASE_AWK_VAL_REF_ARG,
|
||||
ASE_AWK_VAL_REF_NAMEDIDX,
|
||||
ASE_AWK_VAL_REF_GLOBALIDX,
|
||||
ASE_AWK_VAL_REF_LOCALIDX,
|
||||
ASE_AWK_VAL_REF_ARGIDX,
|
||||
ASE_AWK_VAL_REF_POS
|
||||
};
|
||||
|
||||
enum ase_awk_valtostr_opt_t
|
||||
{
|
||||
ASE_AWK_VALTOSTR_CLEAR = (1 << 0),
|
||||
ASE_AWK_VALTOSTR_PRINT = (1 << 1)
|
||||
};
|
||||
|
||||
typedef struct ase_awk_val_nil_t ase_awk_val_nil_t;
|
||||
typedef struct ase_awk_val_int_t ase_awk_val_int_t;
|
||||
typedef struct ase_awk_val_real_t ase_awk_val_real_t;
|
||||
typedef struct ase_awk_val_str_t ase_awk_val_str_t;
|
||||
typedef struct ase_awk_val_rex_t ase_awk_val_rex_t;
|
||||
typedef struct ase_awk_val_map_t ase_awk_val_map_t;
|
||||
typedef struct ase_awk_val_ref_t ase_awk_val_ref_t;
|
||||
|
||||
#if ASE_SIZEOF_INT == 2
|
||||
#define ASE_AWK_VAL_HDR \
|
||||
unsigned int type: 3; \
|
||||
unsigned int ref: 13
|
||||
#else
|
||||
#define ASE_AWK_VAL_HDR \
|
||||
unsigned int type: 3; \
|
||||
unsigned int ref: 29
|
||||
#endif
|
||||
|
||||
#ifndef ASE_AWK_NDE_INT_DEFINED
|
||||
#define ASE_AWK_NDE_INT_DEFINED
|
||||
typedef struct ase_awk_nde_int_t ase_awk_nde_int_t;
|
||||
#endif
|
||||
|
||||
#ifndef ASE_AWK_NDE_REAL_DEFINED
|
||||
#define ASE_AWK_NDE_REAL_DEFINED
|
||||
typedef struct ase_awk_nde_real_t ase_awk_nde_real_t;
|
||||
#endif
|
||||
|
||||
|
||||
struct ase_awk_val_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_NIL */
|
||||
struct ase_awk_val_nil_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_INT */
|
||||
struct ase_awk_val_int_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
ase_long_t val;
|
||||
ase_awk_nde_int_t* nde;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_REAL */
|
||||
struct ase_awk_val_real_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
ase_real_t val;
|
||||
ase_awk_nde_real_t* nde;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_STR */
|
||||
struct ase_awk_val_str_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
ase_char_t* buf;
|
||||
ase_size_t len;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_REX */
|
||||
struct ase_awk_val_rex_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
ase_char_t* buf;
|
||||
ase_size_t len;
|
||||
void* code;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_MAP */
|
||||
struct ase_awk_val_map_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
|
||||
/* TODO: make val_map to array if the indices used are all
|
||||
* integers switch to map dynamically once the
|
||||
* non-integral index is seen.
|
||||
*/
|
||||
ase_awk_map_t* map;
|
||||
};
|
||||
|
||||
/* ASE_AWK_VAL_REF */
|
||||
struct ase_awk_val_ref_t
|
||||
{
|
||||
ASE_AWK_VAL_HDR;
|
||||
|
||||
int id;
|
||||
/* if id is ASE_AWK_VAL_REF_POS, adr holds an index of the
|
||||
* positional variable. Otherwise, adr points to the value
|
||||
* directly. */
|
||||
ase_awk_val_t** adr;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern ase_awk_val_t* ase_awk_val_nil;
|
||||
extern ase_awk_val_t* ase_awk_val_zls;
|
||||
extern ase_awk_val_t* ase_awk_val_negone;
|
||||
extern ase_awk_val_t* ase_awk_val_zero;
|
||||
extern ase_awk_val_t* ase_awk_val_one;
|
||||
|
||||
ase_awk_val_t* ase_awk_makeintval (ase_awk_run_t* run, ase_long_t v);
|
||||
ase_awk_val_t* ase_awk_makerealval (ase_awk_run_t* run, ase_real_t v);
|
||||
|
||||
ase_awk_val_t* ase_awk_makestrval0 (
|
||||
ase_awk_run_t* run, const ase_char_t* str);
|
||||
ase_awk_val_t* ase_awk_makestrval (
|
||||
ase_awk_run_t* run, const ase_char_t* str, ase_size_t len);
|
||||
ase_awk_val_t* ase_awk_makestrval_nodup (
|
||||
ase_awk_run_t* run, ase_char_t* str, ase_size_t len);
|
||||
ase_awk_val_t* ase_awk_makestrval2 (
|
||||
ase_awk_run_t* run,
|
||||
const ase_char_t* str1, ase_size_t len1,
|
||||
const ase_char_t* str2, ase_size_t len2);
|
||||
|
||||
ase_awk_val_t* ase_awk_makerexval (
|
||||
ase_awk_run_t* run, const ase_char_t* buf, ase_size_t len, void* code);
|
||||
ase_awk_val_t* ase_awk_makemapval (ase_awk_run_t* run);
|
||||
ase_awk_val_t* ase_awk_makerefval (
|
||||
ase_awk_run_t* run, int id, ase_awk_val_t** adr);
|
||||
|
||||
ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val);
|
||||
|
||||
void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache);
|
||||
void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
void ase_awk_refdownval (ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
void ase_awk_refdownval_nofree (ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
|
||||
ase_bool_t ase_awk_valtobool (
|
||||
ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
|
||||
ase_char_t* ase_awk_valtostr (
|
||||
ase_awk_run_t* run, ase_awk_val_t* val,
|
||||
int opt, ase_str_t* buf, ase_size_t* len);
|
||||
|
||||
int ase_awk_valtonum (
|
||||
ase_awk_run_t* run, ase_awk_val_t* v, ase_long_t* l, ase_real_t* r);
|
||||
int ase_awk_strtonum (
|
||||
ase_awk_run_t* run, const ase_char_t* ptr, ase_size_t len,
|
||||
ase_long_t* l, ase_real_t* r);
|
||||
|
||||
void ase_awk_dprintval (ase_awk_run_t* run, ase_awk_val_t* val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user