Recovered from cvs revision 2007-04-30 05:47:00

This commit is contained in:
2007-04-30 18:34:00 +00:00
parent a5832c2672
commit 76daf75d92
442 changed files with 0 additions and 62624 deletions

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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 ();
}
};

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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) $<

View File

@ -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) $<

View File

@ -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) $<

View File

@ -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) $<

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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"));
}
}

View File

@ -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