*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-06 08:16:03 +00:00
parent ef1059528f
commit cd71858cc8
10 changed files with 462 additions and 155 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.66 2006-08-04 17:36:40 bacon Exp $ * $Id: awk.c,v 1.67 2006-08-06 08:15:29 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -63,8 +63,6 @@ xp_awk_t* xp_awk_open (void)
awk->option = 0; awk->option = 0;
awk->errnum = XP_AWK_ENOERR; awk->errnum = XP_AWK_ENOERR;
awk->srcio = XP_NULL;
awk->srcio_arg = XP_NULL;
awk->parse.nlocals_max = 0; awk->parse.nlocals_max = 0;
@ -80,12 +78,13 @@ xp_awk_t* xp_awk_open (void)
awk->token.line = 0; awk->token.line = 0;
awk->token.column = 0; awk->token.column = 0;
awk->lex.curc = XP_CHAR_EOF; awk->src.ios = XP_NULL;
awk->lex.ungotc_count = 0; awk->src.lex.curc = XP_CHAR_EOF;
awk->lex.buf_pos = 0; awk->src.lex.ungotc_count = 0;
awk->lex.buf_len = 0; awk->src.lex.line = 1;
awk->lex.line = 1; awk->src.lex.column = 1;
awk->lex.column = 1; awk->src.shared.buf_pos = 0;
awk->src.shared.buf_len = 0;
for (i = 0; i < xp_countof(awk->extio); i++) awk->extio[i] = XP_NULL; for (i = 0; i < xp_countof(awk->extio); i++) awk->extio[i] = XP_NULL;
@ -99,8 +98,6 @@ int xp_awk_close (xp_awk_t* awk)
{ {
xp_awk_clear (awk); xp_awk_clear (awk);
if (xp_awk_detsrc(awk) == -1) return -1;
xp_awk_map_close (&awk->tree.afns); xp_awk_map_close (&awk->tree.afns);
xp_awk_tab_close (&awk->parse.globals); xp_awk_tab_close (&awk->parse.globals);
xp_awk_tab_close (&awk->parse.locals); xp_awk_tab_close (&awk->parse.locals);
@ -117,6 +114,13 @@ int xp_awk_close (xp_awk_t* awk)
void xp_awk_clear (xp_awk_t* awk) void xp_awk_clear (xp_awk_t* awk)
{ {
/* TODO: kill all associated run instances... */ /* TODO: kill all associated run instances... */
awk->src.ios = XP_NULL;
awk->src.lex.curc = XP_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;
xp_awk_tab_clear (&awk->parse.globals); xp_awk_tab_clear (&awk->parse.globals);
xp_awk_tab_clear (&awk->parse.locals); xp_awk_tab_clear (&awk->parse.locals);
@ -126,6 +130,7 @@ void xp_awk_clear (xp_awk_t* awk)
awk->parse.depth.loop = 0; awk->parse.depth.loop = 0;
/* clear parse trees */ /* clear parse trees */
awk->tree.nbglobals = 0;
awk->tree.nglobals = 0; awk->tree.nglobals = 0;
xp_awk_map_clear (&awk->tree.afns); xp_awk_map_clear (&awk->tree.afns);
@ -162,54 +167,6 @@ void xp_awk_setopt (xp_awk_t* awk, int opt)
awk->option = opt; awk->option = opt;
} }
int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t handler, void* arg)
{
if (xp_awk_detsrc(awk) == -1) return -1;
xp_assert (awk->srcio == XP_NULL);
if (handler (XP_AWK_IO_OPEN, arg, XP_NULL, 0) == -1)
{
awk->errnum = XP_AWK_ESRCINOPEN;
return -1;
}
awk->srcio = handler;
awk->srcio_arg = arg;
awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0;
awk->lex.buf_pos = 0;
awk->lex.buf_len = 0;
awk->lex.line = 1;
awk->lex.column = 1;
return 0;
}
int xp_awk_detsrc (xp_awk_t* awk)
{
if (awk->srcio != XP_NULL)
{
xp_ssize_t n;
n = awk->srcio (XP_AWK_IO_CLOSE, awk->srcio_arg, XP_NULL, 0);
if (n == -1)
{
awk->errnum = XP_AWK_ESRCINCLOSE;
return -1;
}
awk->srcio = XP_NULL;
awk->srcio_arg = XP_NULL;
awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0;
awk->lex.buf_pos = 0;
awk->lex.buf_len = 0;
awk->lex.line = 1;
awk->lex.column = 1;
}
return 0;
}
static void __free_afn (void* owner, void* afn) static void __free_afn (void* owner, void* afn)
{ {
xp_awk_afn_t* f = (xp_awk_afn_t*)afn; xp_awk_afn_t* f = (xp_awk_afn_t*)afn;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.90 2006-08-04 17:54:52 bacon Exp $ * $Id: awk.h,v 1.91 2006-08-06 08:15:29 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -134,7 +134,6 @@ enum
XP_AWK_ENOMEM, /* out of memory */ XP_AWK_ENOMEM, /* out of memory */
XP_AWK_EINVAL, /* invalid parameter */ XP_AWK_EINVAL, /* invalid parameter */
XP_AWK_ENOSRCIO, /* no source io handler set */
XP_AWK_ESRCINOPEN, XP_AWK_ESRCINOPEN,
XP_AWK_ESRCINCLOSE, XP_AWK_ESRCINCLOSE,
XP_AWK_ESRCINNEXT, XP_AWK_ESRCINNEXT,
@ -235,10 +234,7 @@ const xp_char_t* xp_awk_getsuberrstr (xp_awk_t* awk);
void xp_awk_clear (xp_awk_t* awk); void xp_awk_clear (xp_awk_t* awk);
void xp_awk_setopt (xp_awk_t* awk, int opt); void xp_awk_setopt (xp_awk_t* awk, int opt);
int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t src, void* arg);
int xp_awk_detsrc (xp_awk_t* awk);
xp_size_t xp_awk_getsrcline (xp_awk_t* awk); xp_size_t xp_awk_getsrcline (xp_awk_t* awk);
int xp_awk_setextio (xp_awk_t* awk, int id, xp_awk_io_t handler, void* arg); int xp_awk_setextio (xp_awk_t* awk, int id, xp_awk_io_t handler, void* arg);
int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios); int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk_i.h,v 1.40 2006-08-04 17:36:40 bacon Exp $ * $Id: awk_i.h,v 1.41 2006-08-06 08:15:29 bacon Exp $
*/ */
#ifndef _XP_AWK_AWKI_H_ #ifndef _XP_AWK_AWKI_H_
@ -51,10 +51,6 @@ struct xp_awk_t
/* options */ /* options */
int option; int option;
/* io functions */
xp_awk_io_t srcio;
void* srcio_arg;
/* parse tree */ /* parse tree */
xp_awk_tree_t tree; xp_awk_tree_t tree;
int state; int state;
@ -79,20 +75,28 @@ struct xp_awk_t
xp_size_t nlocals_max; xp_size_t nlocals_max;
} parse; } parse;
/* source buffer management */ /* source code management */
struct struct
{ {
xp_cint_t curc; xp_awk_srcios_t* ios;
xp_cint_t ungotc[5];
xp_size_t ungotc_count;
xp_char_t buf[512]; struct
xp_size_t buf_pos; {
xp_size_t buf_len; xp_cint_t curc;
xp_cint_t ungotc[5];
xp_size_t ungotc_count;
xp_size_t line; xp_size_t line;
xp_size_t column; xp_size_t column;
} lex; } lex;
struct
{
xp_char_t buf[512];
xp_size_t buf_pos;
xp_size_t buf_len;
} shared;
} src;
xp_awk_io_t extio[XP_AWK_EXTIO_NUM]; xp_awk_io_t extio[XP_AWK_EXTIO_NUM];

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c,v 1.31 2006-08-03 15:49:37 bacon Exp $ * $Id: err.c,v 1.32 2006-08-06 08:15:29 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -28,7 +28,6 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("out of memory"), XP_T("out of memory"),
XP_T("invalid parameter"), XP_T("invalid parameter"),
XP_T("no source io handler set"),
XP_T("cannot open source input"), XP_T("cannot open source input"),
XP_T("cannot close source input"), XP_T("cannot close source input"),
XP_T("cannot switch to next source input"), XP_T("cannot switch to next source input"),

View File

@ -1,17 +1,165 @@
/* /*
* $Id: jni.c,v 1.2 2006-08-02 15:19:59 bacon Exp $ * $Id: jni.c,v 1.3 2006-08-06 08:15:29 bacon Exp $
*/ */
#include "jni.h" #include "jni.h"
#include "awk.h" #include "awk.h"
#include "sa.h" #include "sa.h"
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_AWK_open (JNIEnv* env, jobject obj) #define EXCEPTION_AWK "xpkit/xpj/awk/AwkException"
#define FIELD_AWK "__awk"
static xp_ssize_t __read_source (
int cmd, void* arg, xp_char_t* data, xp_size_t count);
static xp_ssize_t __call_java_read_source (
JNIEnv* env, jobject obj, xp_char_t* buf, xp_size_t size);
typedef struct srcio_data_t srcio_data_t;
struct srcio_data_t
{ {
xp_printf (XP_T("Java_AWK_open\n")); JNIEnv* env;
jobject obj;
};
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_open (JNIEnv* env, jobject obj)
{
jclass class;
jfieldID fid;
jthrowable except;
xp_awk_t* awk;
int opt;
class = (*env)->GetObjectClass(env, obj);
awk = xp_awk_open ();
if (awk == NULL)
{
except = (*env)->FindClass (env, EXCEPTION_AWK);
if (except == 0) return;
(*env)->ThrowNew (env, except, "cannot create awk");
return;
}
fid = (*env)->GetFieldID (env, class, FIELD_AWK, "J");
if (fid == 0) return;
(*env)->SetLongField (env, obj, fid, (jlong)awk);
opt = XP_AWK_EXPLICIT | XP_AWK_UNIQUE | XP_AWK_DBLSLASHES |
XP_AWK_SHADING | XP_AWK_IMPLICIT | XP_AWK_SHIFT |
XP_AWK_EXTIO | XP_AWK_BLOCKLESS;
xp_awk_setopt (awk, opt);
xp_printf (XP_T("__awk(native) done => %u, 0x%X\n"), awk, awk);
} }
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_AWK_close (JNIEnv* env, jobject obj) JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_close (JNIEnv* env, jobject obj)
{ {
xp_printf (XP_T("Java_AWK_close\n")); jclass class;
jfieldID fid;
class = (*env)->GetObjectClass(env, obj);
fid = (*env)->GetFieldID (env, class, FIELD_AWK, "J");
if (fid == 0) return;
xp_awk_close ((xp_awk_t*) (*env)->GetLongField (env, obj, fid));
(*env)->SetLongField (env, obj, fid, (jlong)0);
xp_printf (XP_T("close (native) done\n"));
}
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_parse (JNIEnv* env, jobject obj)
{
jclass class;
jfieldID fid;
jthrowable except;
xp_awk_t* awk;
xp_awk_srcios_t srcios;
srcio_data_t srcio_data;
class = (*env)->GetObjectClass (env, obj);
fid = (*env)->GetFieldID (env, class, FIELD_AWK, "J");
if (fid == 0) return;
awk = (xp_awk_t*) (*env)->GetLongField (env, obj, fid);
srcio_data.env = env;
srcio_data.obj = obj;
srcios.in = __read_source;
srcios.out = XP_NULL;
srcios.custom_data = &srcio_data;
if (xp_awk_parse (awk, &srcios) == -1)
{
except = (*env)->FindClass (env, EXCEPTION_AWK);
if (except == 0) return;
(*env)->ThrowNew (env, except, "ERROR ....");
xp_printf (XP_T("parse error -> line [%d] %s\n"), xp_awk_getsrcline(awk), xp_awk_geterrstr(awk));
return;
}
}
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_run (JNIEnv* env, jobject obj)
{
}
static xp_ssize_t __read_source (
int cmd, void* arg, xp_char_t* data, xp_size_t count)
{
srcio_data_t* srcio_data;
srcio_data = (srcio_data_t*)arg;
if (cmd == XP_AWK_IO_OPEN || cmd == XP_AWK_IO_CLOSE) return 0;
if (cmd == XP_AWK_IO_NEXT) return -1;
if (cmd == XP_AWK_IO_READ)
{
return __call_java_read_source (
srcio_data->env, srcio_data->obj, data, count);
}
else if (cmd == XP_AWK_IO_WRITE)
{
return 0;
}
else
{
return -1;
}
}
static xp_ssize_t __call_java_read_source (
JNIEnv* env, jobject obj, xp_char_t* buf, xp_size_t size)
{
jclass class;
jmethodID mid;
jcharArray array;
xp_ssize_t i, n;
jchar* tmp;
class = (*env)->GetObjectClass(env, obj);
mid = (*env)->GetMethodID (env, class, "read_source", "([CI)I");
if (mid == 0) return -1;
array = (*env)->NewCharArray (env, 1024);
if (array == NULL) return -1;
n = (*env)->CallIntMethod (env, obj, mid, array, 1024);
// TODO: how to handle error..
// TODO: what is xp_char_t is xp_mchar_t? use UTF8 ???
tmp = (*env)->GetCharArrayElements (env, array, 0);
for (i = 0; i < n && i < size; i++) buf[i] = (xp_char_t)tmp[i];
(*env)->ReleaseCharArrayElements (env, array, tmp, 0);
return i;
} }

View File

@ -1,6 +1,8 @@
LIBRARY "xpawk.dll" LIBRARY "xpawk.dll"
EXPORTS EXPORTS
Java_xpkit_xpj_awk_AWK_open Java_xpkit_xpj_awk_Awk_open
Java_xpkit_xpj_awk_AWK_close Java_xpkit_xpj_awk_Awk_close
Java_xpkit_xpj_awk_Awk_parse
Java_xpkit_xpj_awk_Awk_run

View File

@ -1,5 +1,5 @@
/* /*
* $Id: jni.h,v 1.2 2006-08-02 15:19:59 bacon Exp $ * $Id: jni.h,v 1.3 2006-08-06 08:15:29 bacon Exp $
*/ */
#ifndef _XP_AWK_JNI_H_ #ifndef _XP_AWK_JNI_H_
@ -11,8 +11,10 @@
extern "C" { extern "C" {
#endif #endif
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_AWK_open (JNIEnv*, jobject); JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_open (JNIEnv*, jobject);
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_AWK_close (JNIEnv*, jobject); JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_close (JNIEnv*, jobject);
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_parse (JNIEnv*, jobject);
JNIEXPORT void JNICALL Java_xpkit_xpj_awk_Awk_run (JNIEnv*, jobject);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.159 2006-08-04 17:54:52 bacon Exp $ * $Id: parse.c,v 1.160 2006-08-06 08:15:29 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -207,6 +207,14 @@ static int __assign_to_opcode (xp_awk_t* awk);
static int __is_plain_var (xp_awk_nde_t* nde); static int __is_plain_var (xp_awk_nde_t* nde);
static int __is_var (xp_awk_nde_t* nde); static int __is_var (xp_awk_nde_t* nde);
static void __deparse (xp_awk_t* awk);
static int __deparse_func (xp_awk_pair_t* pair, void* arg);
static int __put_char (xp_awk_t* awk, xp_char_t c);
static int __put_charstr (xp_awk_t* awk, const xp_char_t* str);
static int __put_charstrx (xp_awk_t* awk, const xp_char_t* str, xp_size_t len);
static int __flush (xp_awk_t* awk);
struct __kwent struct __kwent
{ {
const xp_char_t* name; const xp_char_t* name;
@ -291,7 +299,7 @@ static struct __bvent __bvtab[] =
#define GET_CHAR_TO(awk,c) \ #define GET_CHAR_TO(awk,c) \
do { \ do { \
if (__get_char(awk) == -1) return -1; \ if (__get_char(awk) == -1) return -1; \
c = (awk)->lex.curc; \ c = (awk)->src.lex.curc; \
} while(0) } while(0)
#define SET_TOKEN_TYPE(awk,code) \ #define SET_TOKEN_TYPE(awk,code) \
@ -314,14 +322,8 @@ static struct __bvent __bvtab[] =
} \ } \
} while (0) } while (0)
#define GET_TOKEN(awk) \
do { if (__get_token(awk) == -1) return -1; } while (0)
#define MATCH(awk,token_type) ((awk)->token.type == (token_type)) #define MATCH(awk,token_type) ((awk)->token.type == (token_type))
#define CONSUME(awk) \
do { if (__get_token(awk) == -1) return XP_NULL; } while (0)
#define PANIC(awk,code) \ #define PANIC(awk,code) \
do { (awk)->errnum = (code); return XP_NULL; } while (0) do { (awk)->errnum = (code); return XP_NULL; } while (0)
@ -337,7 +339,7 @@ static int __dump_func (xp_awk_pair_t* pair, void* arg)
xp_awk_afn_t* afn = (xp_awk_afn_t*)pair->val; xp_awk_afn_t* afn = (xp_awk_afn_t*)pair->val;
xp_size_t i; xp_size_t i;
xp_assert (xp_strcmp(pair->key, afn->name) == 0); xp_assert (xp_strcmp (pair->key, afn->name) == 0);
xp_printf (XP_T("function %s ("), afn->name); xp_printf (XP_T("function %s ("), afn->name);
for (i = 0; i < afn->nargs; ) for (i = 0; i < afn->nargs; )
{ {
@ -410,22 +412,42 @@ static void __dump (xp_awk_t* awk)
int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios) int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios)
{ {
/* TODO: switch to srcios */ int n = 0;
if (awk->srcio == XP_NULL)
xp_assert (srcios != XP_NULL && srcios->in != XP_NULL);
xp_awk_clear (awk);
awk->src.ios = srcios;
if (awk->src.ios->in (
XP_AWK_IO_OPEN, awk->src.ios->custom_data, XP_NULL, 0) == -1)
{ {
/* the source code io handler is not set */ awk->errnum = XP_AWK_ESRCINOPEN;
awk->errnum = XP_AWK_ENOSRCIO;
return -1; return -1;
} }
/* TODO: consider opening source here rather in attsrc. same for closing. if (__add_builtin_globals (awk) == XP_NULL)
* if it does, this part should initialize some of the data like token.line */ {
xp_awk_clear (awk); n = -1;
xp_awk_clear (awk);
goto exit_parse;
}
if (__add_builtin_globals (awk) == XP_NULL) return -1; /* get the first character */
if (__get_char(awk) == -1)
{
n = -1;
xp_awk_clear (awk);
goto exit_parse;
}
GET_CHAR (awk); /* get the first token */
GET_TOKEN (awk); if (__get_token(awk) == -1)
{
n = -1;
xp_awk_clear (awk);
goto exit_parse;
}
while (1) while (1)
{ {
@ -434,16 +456,32 @@ int xp_awk_parse (xp_awk_t* awk, xp_awk_srcios_t* srcios)
if (__parse_progunit (awk) == XP_NULL) if (__parse_progunit (awk) == XP_NULL)
{ {
n = -1;
xp_awk_clear (awk); xp_awk_clear (awk);
return -1; goto exit_parse;
} }
} }
awk->tree.nglobals = xp_awk_tab_getsize(&awk->parse.globals); awk->tree.nglobals = xp_awk_tab_getsize(&awk->parse.globals);
xp_printf (XP_T("-----------------------------\n"));
__dump (awk);
return 0; if (awk->src.ios->out != XP_NULL) __deparse (awk);
exit_parse:
if (awk->src.ios->in (
XP_AWK_IO_CLOSE, awk->src.ios->custom_data, XP_NULL, 0) == -1)
{
xp_awk_clear (awk);
if (n == 0)
{
/* this is to keep the earlier error above
* that might be more critical than this */
awk->errnum = XP_AWK_ESRCINCLOSE;
n = -1;
}
}
return n;
} }
static xp_awk_t* __parse_progunit (xp_awk_t* awk) static xp_awk_t* __parse_progunit (xp_awk_t* awk)
@ -805,6 +843,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
} }
afn->name = XP_NULL; /* function name set below */ afn->name = XP_NULL; /* function name set below */
afn->name_len = 0;
afn->nargs = nargs; afn->nargs = nargs;
afn->body = body; afn->body = body;
@ -821,6 +860,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
xp_assert (n != 0); xp_assert (n != 0);
afn->name = pair->key; /* do some trick to save a string. */ afn->name = pair->key; /* do some trick to save a string. */
afn->name_len = pair->key_len;
xp_free (name_dup); xp_free (name_dup);
return body; return body;
@ -3233,8 +3273,8 @@ static int __get_token (xp_awk_t* awk)
while (n == 1); while (n == 1);
xp_str_clear (&awk->token.name); xp_str_clear (&awk->token.name);
awk->token.line = awk->lex.line; awk->token.line = awk->src.lex.line;
awk->token.column = awk->lex.column; awk->token.column = awk->src.lex.column;
if (line != 0 && (awk->option & XP_AWK_BLOCKLESS) && if (line != 0 && (awk->option & XP_AWK_BLOCKLESS) &&
(awk->parse.id.block == PARSE_PATTERN || (awk->parse.id.block == PARSE_PATTERN ||
@ -3248,7 +3288,7 @@ static int __get_token (xp_awk_t* awk)
} }
} }
c = awk->lex.curc; c = awk->src.lex.curc;
if (c == XP_CHAR_EOF) if (c == XP_CHAR_EOF)
{ {
@ -3290,7 +3330,7 @@ static int __get_token (xp_awk_t* awk)
} }
while (n == 1); while (n == 1);
c = awk->lex.curc; c = awk->src.lex.curc;
if (c != XP_T('\"')) break; if (c != XP_T('\"')) break;
if (__get_charstr(awk) == -1) return -1; if (__get_charstr(awk) == -1) return -1;
@ -3618,7 +3658,7 @@ static int __get_number (xp_awk_t* awk)
xp_assert (XP_STR_LEN(&awk->token.name) == 0); xp_assert (XP_STR_LEN(&awk->token.name) == 0);
SET_TOKEN_TYPE (awk, TOKEN_INT); SET_TOKEN_TYPE (awk, TOKEN_INT);
c = awk->lex.curc; c = awk->src.lex.curc;
if (c == XP_T('0')) if (c == XP_T('0'))
{ {
@ -3708,22 +3748,22 @@ static int __get_number (xp_awk_t* awk)
static int __get_charstr (xp_awk_t* awk) static int __get_charstr (xp_awk_t* awk)
{ {
if (awk->lex.curc != XP_T('\"')) if (awk->src.lex.curc != XP_T('\"'))
{ {
/* the starting quote has been comsumed before this function /* the starting quote has been comsumed before this function
* has been called */ * has been called */
ADD_TOKEN_CHAR (awk, awk->lex.curc); ADD_TOKEN_CHAR (awk, awk->src.lex.curc);
} }
return __get_string (awk, XP_T('\"'), XP_T('\\'), xp_false); return __get_string (awk, XP_T('\"'), XP_T('\\'), xp_false);
} }
static int __get_rexstr (xp_awk_t* awk) static int __get_rexstr (xp_awk_t* awk)
{ {
if (awk->lex.curc != XP_T('/')) if (awk->src.lex.curc != XP_T('/'))
{ {
/* the starting slash has been comsumed before this function /* the starting slash has been comsumed before this function
* has been called */ * has been called */
ADD_TOKEN_CHAR (awk, awk->lex.curc); ADD_TOKEN_CHAR (awk, awk->src.lex.curc);
} }
return __get_string (awk, XP_T('/'), XP_T('\\'), xp_true); return __get_string (awk, XP_T('/'), XP_T('\\'), xp_true);
} }
@ -3886,9 +3926,9 @@ static int __get_char (xp_awk_t* awk)
xp_ssize_t n; xp_ssize_t n;
/*xp_char_t c;*/ /*xp_char_t c;*/
if (awk->lex.ungotc_count > 0) if (awk->src.lex.ungotc_count > 0)
{ {
awk->lex.curc = awk->lex.ungotc[--awk->lex.ungotc_count]; awk->src.lex.curc = awk->src.lex.ungotc[--awk->src.lex.ungotc_count];
return 0; return 0;
} }
@ -3899,13 +3939,13 @@ static int __get_char (xp_awk_t* awk)
awk->errnum = XP_AWK_ESRCINDATA; awk->errnum = XP_AWK_ESRCINDATA;
return -1; return -1;
} }
awk->lex.curc = (n == 0)? XP_CHAR_EOF: c; awk->src.lex.curc = (n == 0)? XP_CHAR_EOF: c;
*/ */
if (awk->lex.buf_pos >= awk->lex.buf_len) if (awk->src.shared.buf_pos >= awk->src.shared.buf_len)
{ {
n = awk->srcio ( n = awk->src.ios->in (
XP_AWK_IO_READ, awk->srcio_arg, XP_AWK_IO_READ, awk->src.ios->custom_data,
awk->lex.buf, xp_countof(awk->lex.buf)); awk->src.shared.buf, xp_countof(awk->src.shared.buf));
if (n == -1) if (n == -1)
{ {
awk->errnum = XP_AWK_ESRCINDATA; awk->errnum = XP_AWK_ESRCINDATA;
@ -3914,41 +3954,41 @@ static int __get_char (xp_awk_t* awk)
if (n == 0) if (n == 0)
{ {
awk->lex.curc = XP_CHAR_EOF; awk->src.lex.curc = XP_CHAR_EOF;
return 0; return 0;
} }
awk->lex.buf_pos = 0; awk->src.shared.buf_pos = 0;
awk->lex.buf_len = n; awk->src.shared.buf_len = n;
} }
awk->lex.curc = awk->lex.buf[awk->lex.buf_pos++]; awk->src.lex.curc = awk->src.shared.buf[awk->src.shared.buf_pos++];
if (awk->lex.curc == XP_T('\n')) if (awk->src.lex.curc == XP_T('\n'))
{ {
awk->lex.line++; awk->src.lex.line++;
awk->lex.column = 1; awk->src.lex.column = 1;
} }
else awk->lex.column++; else awk->src.lex.column++;
return 0; return 0;
} }
static int __unget_char (xp_awk_t* awk, xp_cint_t c) static int __unget_char (xp_awk_t* awk, xp_cint_t c)
{ {
if (awk->lex.ungotc_count >= xp_countof(awk->lex.ungotc)) if (awk->src.lex.ungotc_count >= xp_countof(awk->src.lex.ungotc))
{ {
awk->errnum = XP_AWK_ELXUNG; awk->errnum = XP_AWK_ELXUNG;
return -1; return -1;
} }
awk->lex.ungotc[awk->lex.ungotc_count++] = c; awk->src.lex.ungotc[awk->src.lex.ungotc_count++] = c;
return 0; return 0;
} }
static int __skip_spaces (xp_awk_t* awk) static int __skip_spaces (xp_awk_t* awk)
{ {
xp_cint_t c = awk->lex.curc; xp_cint_t c = awk->src.lex.curc;
while (xp_isspace(c)) GET_CHAR_TO (awk, c); while (xp_isspace(c)) GET_CHAR_TO (awk, c);
return 0; return 0;
@ -3956,7 +3996,7 @@ static int __skip_spaces (xp_awk_t* awk)
static int __skip_comment (xp_awk_t* awk) static int __skip_comment (xp_awk_t* awk)
{ {
xp_cint_t c = awk->lex.curc; xp_cint_t c = awk->src.lex.curc;
if ((awk->option & XP_AWK_HASHSIGN) && c == XP_T('#')) if ((awk->option & XP_AWK_HASHSIGN) && c == XP_T('#'))
{ {
@ -4005,7 +4045,7 @@ static int __skip_comment (xp_awk_t* awk)
} }
if (__unget_char(awk,c) == -1) return -1; /* error */ if (__unget_char(awk,c) == -1) return -1; /* error */
awk->lex.curc = XP_T('/'); awk->src.lex.curc = XP_T('/');
return 0; return 0;
} }
@ -4070,3 +4110,168 @@ static int __is_var (xp_awk_nde_t* nde)
nde->type == XP_AWK_NDE_ARGIDX || nde->type == XP_AWK_NDE_ARGIDX ||
nde->type == XP_AWK_NDE_NAMEDIDX; nde->type == XP_AWK_NDE_NAMEDIDX;
} }
struct __deparse_func_t
{
xp_awk_t* awk;
xp_char_t* tmp;
xp_size_t tmp_len;
};
static void __deparse (xp_awk_t* awk)
{
xp_awk_chain_t* chain;
xp_char_t tmp[128];
struct __deparse_func_t df;
xp_assert (awk->src.ios->out != XP_NULL);
awk->src.shared.buf_len = 0;
awk->src.shared.buf_pos = 0;
if (awk->tree.nglobals > awk->tree.nbglobals)
{
xp_size_t i;
xp_assert (awk->tree.nglobals > 0);
__put_charstr (awk, XP_T("global "));
for (i = awk->tree.nbglobals; i < awk->tree.nglobals - 1; i++)
{
xp_sprintf (tmp, xp_countof(tmp),
XP_T("__global%lu, "), (unsigned long)i);
__put_charstr (awk, tmp);
}
xp_sprintf (tmp, xp_countof(tmp),
XP_T("__global%lu;\n\n"), (unsigned long)i);
__put_charstr (awk, tmp);
}
df.awk = awk;
df.tmp = tmp;
df.tmp_len = xp_countof(tmp);
xp_awk_map_walk (&awk->tree.afns, __deparse_func, &df);
if (awk->tree.begin != XP_NULL)
{
__put_charstr (awk, XP_T("BEGIN "));
xp_awk_prnpt (awk->tree.begin);
__put_char (awk, XP_T('\n'));
}
chain = awk->tree.chain;
while (chain != XP_NULL)
{
if (chain->pattern != XP_NULL)
{
/*xp_awk_prnpt (chain->pattern);*/
xp_awk_prnptnpt (chain->pattern);
}
if (chain->action == XP_NULL)
{
/* blockless pattern */
__put_char (awk, XP_T('\n'));
}
else
{
xp_awk_prnpt (chain->action);
}
__put_char (awk, XP_T('\n'));
chain = chain->next;
}
if (awk->tree.end != XP_NULL)
{
__put_charstr (awk, XP_T("END "));
xp_awk_prnpt (awk->tree.end);
}
__flush (awk);
}
static int __deparse_func (xp_awk_pair_t* pair, void* arg)
{
struct __deparse_func_t* df = (struct __deparse_func_t*)arg;
xp_awk_afn_t* afn = (xp_awk_afn_t*)pair->val;
xp_size_t i;
xp_assert (xp_strxncmp (
pair->key, pair->key_len, afn->name, afn->name_len) == 0);
__put_charstr (df->awk, XP_T("function \n"));
__put_charstr (df->awk, afn->name);
__put_charstr (df->awk, XP_T(" ("));
for (i = 0; i < afn->nargs; )
{
xp_printf (XP_T("__arg%lu"), (unsigned long)i++);
if (i >= afn->nargs) break;
__put_charstr (df->awk, XP_T(", "));
}
__put_charstr (df->awk, XP_T(")\n"));
xp_awk_prnpt (afn->body);
__put_char (df->awk, XP_T('\n'));
return 0;
}
static int __put_char (xp_awk_t* awk, xp_char_t c)
{
awk->src.shared.buf[awk->src.shared.buf_len++] = c;
if (awk->src.shared.buf_len >= xp_countof(awk->src.shared.buf))
{
if (__flush (awk) == -1) return -1;
}
return 0;
}
static int __put_charstr (xp_awk_t* awk, const xp_char_t* str)
{
while (*str != XP_T('\0'))
{
if (__put_char (awk, *str) == -1) return -1;
str++;
}
return 0;
}
static int __put_charstrx (xp_awk_t* awk, const xp_char_t* str, xp_size_t len)
{
const xp_char_t* end = str + len;
while (str < end)
{
if (__put_char (awk, *str) == -1) return -1;
str++;
}
return 0;
}
static int __flush (xp_awk_t* awk)
{
xp_ssize_t n;
xp_assert (awk->src.ios->out != XP_NULL);
while (awk->src.shared.buf_pos < awk->src.shared.buf_len)
{
n = awk->src.ios->out (
XP_AWK_IO_WRITE, awk->src.ios->custom_data,
&awk->src.shared.buf[awk->src.shared.buf_pos],
awk->src.shared.buf_len - awk->src.shared.buf_pos);
if (n <= 0) return -1;
awk->src.shared.buf_pos += n;
}
awk->src.shared.buf_pos = 0;
awk->src.shared.buf_len = 0;
return 0;
}

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.h,v 1.65 2006-08-03 05:05:48 bacon Exp $ * $Id: tree.h,v 1.66 2006-08-06 08:15:29 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
@ -89,7 +89,7 @@ enum
/* afn (awk function defined with the keyword function) */ /* afn (awk function defined with the keyword function) */
typedef struct xp_awk_afn_t xp_awk_afn_t; typedef struct xp_awk_afn_t xp_awk_afn_t;
typedef struct xp_awk_nde_t xp_awk_nde_t; typedef struct xp_awk_nde_t xp_awk_nde_t;
typedef struct xp_awk_nde_blk_t xp_awk_nde_blk_t; typedef struct xp_awk_nde_blk_t xp_awk_nde_blk_t;
typedef struct xp_awk_nde_grp_t xp_awk_nde_grp_t; typedef struct xp_awk_nde_grp_t xp_awk_nde_grp_t;
@ -121,6 +121,7 @@ typedef struct xp_awk_nde_print_t xp_awk_nde_print_t;
struct xp_awk_afn_t struct xp_awk_afn_t
{ {
xp_char_t* name; xp_char_t* name;
xp_size_t name_len;
xp_size_t nargs; xp_size_t nargs;
xp_awk_nde_t* body; xp_awk_nde_t* body;
}; };

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.67 2006-08-04 17:54:52 bacon Exp $ * $Id: awk.c,v 1.68 2006-08-06 08:16:03 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -600,16 +600,9 @@ static int __main (int argc, xp_char_t* argv[])
xp_awk_setopt (awk, opt); xp_awk_setopt (awk, opt);
if (xp_awk_attsrc (awk, process_source, (void*)&src_io) == -1)
{
xp_awk_close (awk);
xp_printf (XP_T("Error: cannot attach source\n"));
return -1;
}
srcios.in = process_source; srcios.in = process_source;
srcios.out = XP_NULL; srcios.out = XP_NULL;
srcios.custom_data = XP_NULL; srcios.custom_data = &src_io;
if (xp_awk_parse (awk, &srcios) == -1) if (xp_awk_parse (awk, &srcios) == -1)
{ {