qse/ase/awk/StdAwk.java
2008-03-04 05:13:15 +00:00

452 lines
9.3 KiB
Java

/*
* $Id: StdAwk.java 115 2008-03-03 11:13:15Z baconevi $
*
* {License}
*/
package ase.awk;
import java.io.*;
/**
* Extends the core interpreter engine to implement the language closer to
* the standard.
*/
public abstract class StdAwk extends Awk
{
private long seed;
private java.util.Random random;
public StdAwk () throws Exception
{
super ();
seed = System.currentTimeMillis();
random = new java.util.Random (seed);
addFunction ("sin", 1, 1);
addFunction ("cos", 1, 1);
addFunction ("tan", 1, 1);
addFunction ("atan", 1, 1);
addFunction ("atan2", 2, 2);
addFunction ("log", 1, 1);
addFunction ("exp", 1, 1);
addFunction ("sqrt", 1, 1);
addFunction ("int", 1, 1, "bfnint");
addFunction ("srand", 0, 1);
addFunction ("rand", 0, 0);
addFunction ("systime", 0, 0);
addFunction ("strftime", 0, 2);
addFunction ("strfgmtime", 0, 2);
addFunction ("system", 1, 1);
}
/* == file interface == */
protected int openFile (File file)
{
int mode = file.getMode();
if (mode == File.MODE_READ)
{
FileInputStream fis;
try { fis = new FileInputStream (file.getName()); }
catch (IOException e) { return -1; }
Reader rd = new BufferedReader (
new InputStreamReader (fis));
file.setHandle (rd);
return 1;
}
else if (mode == File.MODE_WRITE)
{
FileOutputStream fos;
try { fos = new FileOutputStream (file.getName()); }
catch (IOException e) { return -1; }
Writer wr = new BufferedWriter (
new OutputStreamWriter (fos));
file.setHandle (wr);
return 1;
}
else if (mode == File.MODE_APPEND)
{
FileOutputStream fos;
try { fos = new FileOutputStream (file.getName(), true); }
catch (IOException e) { return -1; }
Writer wr = new BufferedWriter (
new OutputStreamWriter (fos));
file.setHandle (wr);
return 1;
}
return -1;
}
protected int closeFile (File file)
{
int mode = file.getMode();
if (mode == File.MODE_READ)
{
Reader isr = (Reader)file.getHandle();
try { isr.close (); }
catch (IOException e) { return -1; }
return 0;
}
else if (mode == File.MODE_WRITE)
{
Writer osw = (Writer)file.getHandle();
try { osw.close (); }
catch (IOException e) { return -1; }
return 0;
}
else if (mode == File.MODE_APPEND)
{
Writer osw = (Writer)file.getHandle();
try { osw.close (); }
catch (IOException e) { return -1; }
return 0;
}
return -1;
}
protected int readFile (File file, char[] buf, int len)
{
int mode = file.getMode();
if (mode == File.MODE_READ)
{
Reader rd = (Reader)file.getHandle();
try
{
len = rd.read (buf, 0, len);
if (len == -1) return 0;
}
catch (IOException e) { return -1; }
return len;
}
return -1;
}
protected int writeFile (File file, char[] buf, int len)
{
int mode = file.getMode();
if (mode == File.MODE_WRITE ||
mode == File.MODE_APPEND)
{
Writer wr = (Writer)file.getHandle();
try { wr.write (buf, 0, len); }
catch (IOException e) { return -1; }
return len;
}
return -1;
}
protected int flushFile (File file)
{
int mode = file.getMode ();
if (mode == File.MODE_WRITE ||
mode == File.MODE_APPEND)
{
Writer wr = (Writer)file.getHandle ();
try { wr.flush (); }
catch (IOException e) { return -1; }
return 0;
}
return -1;
}
private class RWE
{
public Writer wr;
public Reader rd;
public Reader er;
public RWE (Writer wr, Reader rd, Reader er)
{
this.wr = wr;
this.rd = rd;
this.er = er;
}
};
/* == pipe interface == */
protected int openPipe (Pipe pipe)
{
int mode = pipe.getMode();
if (mode == Pipe.MODE_READ)
{
Process proc;
try { proc = popen (pipe.getName()); }
catch (IOException e) { return -1; }
Reader rd = new BufferedReader (
new InputStreamReader (proc.getInputStream()));
pipe.setHandle (rd);
return 1;
}
else if (mode == Pipe.MODE_WRITE)
{
Process proc;
try { proc = popen (pipe.getName()); }
catch (IOException e) { return -1; }
Writer wr = new BufferedWriter (
new OutputStreamWriter (proc.getOutputStream()));
Reader rd = new BufferedReader (
new InputStreamReader (proc.getInputStream()));
Reader er = new BufferedReader (
new InputStreamReader (proc.getErrorStream()));
pipe.setHandle (new RWE (wr, rd, er));
return 1;
}
return -1;
}
protected int closePipe (Pipe pipe)
{
int mode = pipe.getMode();
if (mode == Pipe.MODE_READ)
{
Reader rd = (Reader)pipe.getHandle();
try { rd.close (); }
catch (IOException e) { return -1; }
return 0;
}
else if (mode == Pipe.MODE_WRITE)
{
//Writer wr = (Writer)pipe.getHandle();
RWE rwe = (RWE)pipe.getHandle();
try { rwe.wr.close (); }
catch (IOException e) { return -1; }
char[] buf = new char[256];
try
{
while (true)
{
int len = rwe.rd.read (buf, 0, buf.length);
if (len == -1) break;
System.out.print (new String (buf, 0, len));
}
System.out.flush ();
}
catch (IOException e) {}
try
{
while (true)
{
int len = rwe.er.read (buf, 0, buf.length);
if (len == -1) break;
System.err.print (new String (buf, 0, len));
}
System.err.flush ();
}
catch (IOException e) {}
try { rwe.rd.close (); } catch (IOException e) {}
try { rwe.er.close (); } catch (IOException e) {}
pipe.setHandle (null);
return 0;
}
return -1;
}
protected int readPipe (Pipe pipe, char[] buf, int len)
{
int mode = pipe.getMode();
if (mode == Pipe.MODE_READ)
{
Reader rd = (Reader)pipe.getHandle();
try
{
len = rd.read (buf, 0, len);
if (len == -1) len = 0;
}
catch (IOException e) { len = -1; }
return len;
}
return -1;
}
protected int writePipe (Pipe pipe, char[] buf, int len)
{
int mode = pipe.getMode();
if (mode == Pipe.MODE_WRITE)
{
//Writer wr = (Writer)pipe.getHandle ();
RWE rw = (RWE)pipe.getHandle();
try
{
rw.wr.write (buf, 0, len);
rw.wr.flush ();
}
catch (IOException e) { return -1; }
return len;
}
return -1;
}
protected int flushPipe (Pipe pipe)
{
int mode = pipe.getMode ();
if (mode == Pipe.MODE_WRITE)
{
Writer wr = (Writer)pipe.getHandle ();
try { wr.flush (); }
catch (IOException e) { return -1; }
return 0;
}
return -1;
}
/* == arithmetic built-in functions */
public void sin (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.sin(args[0].getRealValue()));
}
public void cos (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.cos(args[0].getRealValue()));
}
public void tan (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.tan(args[0].getRealValue()));
}
public void atan (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.atan(args[0].getRealValue()));
}
public void atan2 (Context ctx, String name, Return ret, Argument[] args)
{
double y = args[0].getRealValue();
double x = args[1].getRealValue();
ret.setRealValue (Math.atan2(y,x));
}
public void log (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.log(args[0].getRealValue()));
}
public void exp (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.exp(args[0].getRealValue()));
}
public void sqrt (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (Math.sqrt(args[0].getRealValue()));
}
public void bfnint (Context ctx, String name, Return ret, Argument[] args)
{
ret.setIntValue (args[0].getIntValue());
}
public void rand (Context ctx, String name, Return ret, Argument[] args)
{
ret.setRealValue (random.nextDouble ());
}
public void srand (Context ctx, String name, Return ret, Argument[] args)
{
long prev_seed = seed;
seed = (args == null || args.length == 0)?
System.currentTimeMillis ():
args[0].getIntValue();
random.setSeed (seed);
ret.setIntValue (prev_seed);
}
public void systime (Context ctx, String name, Return ret, Argument[] args)
{
long msec = System.currentTimeMillis ();
ret.setIntValue (msec / 1000);
}
public void strftime (Context ctx, String name, Return ret, Argument[] args) throws Exception
{
String fmt = (args.length<1)? "%c": args[0].getStringValue();
long t = (args.length<2)? (System.currentTimeMillis()/1000): args[1].getIntValue();
ret.setStringValue (strftime (fmt, t));
}
public void strfgmtime (Context ctx, String name, Return ret, Argument[] args) throws Exception
{
String fmt = (args.length<1)? "%c": args[0].getStringValue();
long t = (args.length<2)? (System.currentTimeMillis()/1000): args[1].getIntValue();
ret.setStringValue (strfgmtime (fmt, t));
}
/* miscellaneous built-in functions */
public void system (Context ctx, String name, Return ret, Argument[] args) throws Exception
{
ret.setIntValue (system (args[0].getStringValue()));
}
/* == 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);
}
}