*** 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>
@ -63,8 +63,6 @@ xp_awk_t* xp_awk_open (void)
awk->option = 0;
awk->errnum = XP_AWK_ENOERR;
awk->srcio = XP_NULL;
awk->srcio_arg = XP_NULL;
awk->parse.nlocals_max = 0;
@ -80,12 +78,13 @@ xp_awk_t* xp_awk_open (void)
awk->token.line = 0;
awk->token.column = 0;
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;
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;
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);
if (xp_awk_detsrc(awk) == -1) return -1;
xp_awk_map_close (&awk->tree.afns);
xp_awk_tab_close (&awk->parse.globals);
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)
{
/* 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.locals);
@ -126,6 +130,7 @@ void xp_awk_clear (xp_awk_t* awk)
awk->parse.depth.loop = 0;
/* clear parse trees */
awk->tree.nbglobals = 0;
awk->tree.nglobals = 0;
xp_awk_map_clear (&awk->tree.afns);
@ -162,54 +167,6 @@ void xp_awk_setopt (xp_awk_t* awk, int 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)
{
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_
@ -134,7 +134,6 @@ enum
XP_AWK_ENOMEM, /* out of memory */
XP_AWK_EINVAL, /* invalid parameter */
XP_AWK_ENOSRCIO, /* no source io handler set */
XP_AWK_ESRCINOPEN,
XP_AWK_ESRCINCLOSE,
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_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);
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);

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_
@ -51,10 +51,6 @@ struct xp_awk_t
/* options */
int option;
/* io functions */
xp_awk_io_t srcio;
void* srcio_arg;
/* parse tree */
xp_awk_tree_t tree;
int state;
@ -79,20 +75,28 @@ struct xp_awk_t
xp_size_t nlocals_max;
} parse;
/* source buffer management */
struct
/* source code management */
struct
{
xp_cint_t curc;
xp_cint_t ungotc[5];
xp_size_t ungotc_count;
xp_awk_srcios_t* ios;
xp_char_t buf[512];
xp_size_t buf_pos;
xp_size_t buf_len;
struct
{
xp_cint_t curc;
xp_cint_t ungotc[5];
xp_size_t ungotc_count;
xp_size_t line;
xp_size_t column;
} lex;
xp_size_t line;
xp_size_t column;
} 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];

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>
@ -28,7 +28,6 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("out of memory"),
XP_T("invalid parameter"),
XP_T("no source io handler set"),
XP_T("cannot open source input"),
XP_T("cannot close 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 "awk.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"
EXPORTS
Java_xpkit_xpj_awk_AWK_open
Java_xpkit_xpj_awk_AWK_close
Java_xpkit_xpj_awk_Awk_open
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_
@ -11,8 +11,10 @@
extern "C" {
#endif
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_open (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
}

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>
@ -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_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
{
const xp_char_t* name;
@ -291,7 +299,7 @@ static struct __bvent __bvtab[] =
#define GET_CHAR_TO(awk,c) \
do { \
if (__get_char(awk) == -1) return -1; \
c = (awk)->lex.curc; \
c = (awk)->src.lex.curc; \
} while(0)
#define SET_TOKEN_TYPE(awk,code) \
@ -314,14 +322,8 @@ static struct __bvent __bvtab[] =
} \
} 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 CONSUME(awk) \
do { if (__get_token(awk) == -1) return XP_NULL; } while (0)
#define PANIC(awk,code) \
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_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);
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)
{
/* TODO: switch to srcios */
if (awk->srcio == XP_NULL)
int n = 0;
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_ENOSRCIO;
awk->errnum = XP_AWK_ESRCINOPEN;
return -1;
}
/* TODO: consider opening source here rather in attsrc. same for closing.
* if it does, this part should initialize some of the data like token.line */
xp_awk_clear (awk);
if (__add_builtin_globals (awk) == XP_NULL)
{
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_TOKEN (awk);
/* get the first token */
if (__get_token(awk) == -1)
{
n = -1;
xp_awk_clear (awk);
goto exit_parse;
}
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)
{
n = -1;
xp_awk_clear (awk);
return -1;
goto exit_parse;
}
}
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)
@ -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_len = 0;
afn->nargs = nargs;
afn->body = body;
@ -821,6 +860,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
xp_assert (n != 0);
afn->name = pair->key; /* do some trick to save a string. */
afn->name_len = pair->key_len;
xp_free (name_dup);
return body;
@ -3233,8 +3273,8 @@ static int __get_token (xp_awk_t* awk)
while (n == 1);
xp_str_clear (&awk->token.name);
awk->token.line = awk->lex.line;
awk->token.column = awk->lex.column;
awk->token.line = awk->src.lex.line;
awk->token.column = awk->src.lex.column;
if (line != 0 && (awk->option & XP_AWK_BLOCKLESS) &&
(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)
{
@ -3290,7 +3330,7 @@ static int __get_token (xp_awk_t* awk)
}
while (n == 1);
c = awk->lex.curc;
c = awk->src.lex.curc;
if (c != XP_T('\"')) break;
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);
SET_TOKEN_TYPE (awk, TOKEN_INT);
c = awk->lex.curc;
c = awk->src.lex.curc;
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)
{
if (awk->lex.curc != XP_T('\"'))
if (awk->src.lex.curc != XP_T('\"'))
{
/* the starting quote has been comsumed before this function
* 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);
}
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
* 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);
}
@ -3886,9 +3926,9 @@ static int __get_char (xp_awk_t* awk)
xp_ssize_t n;
/*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;
}
@ -3899,13 +3939,13 @@ static int __get_char (xp_awk_t* awk)
awk->errnum = XP_AWK_ESRCINDATA;
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 (
XP_AWK_IO_READ, awk->srcio_arg,
awk->lex.buf, xp_countof(awk->lex.buf));
n = awk->src.ios->in (
XP_AWK_IO_READ, awk->src.ios->custom_data,
awk->src.shared.buf, xp_countof(awk->src.shared.buf));
if (n == -1)
{
awk->errnum = XP_AWK_ESRCINDATA;
@ -3914,41 +3954,41 @@ static int __get_char (xp_awk_t* awk)
if (n == 0)
{
awk->lex.curc = XP_CHAR_EOF;
awk->src.lex.curc = XP_CHAR_EOF;
return 0;
}
awk->lex.buf_pos = 0;
awk->lex.buf_len = n;
awk->src.shared.buf_pos = 0;
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->lex.column = 1;
awk->src.lex.line++;
awk->src.lex.column = 1;
}
else awk->lex.column++;
else awk->src.lex.column++;
return 0;
}
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;
return -1;
}
awk->lex.ungotc[awk->lex.ungotc_count++] = c;
awk->src.lex.ungotc[awk->src.lex.ungotc_count++] = c;
return 0;
}
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);
return 0;
@ -3956,7 +3996,7 @@ static int __skip_spaces (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('#'))
{
@ -4005,7 +4045,7 @@ static int __skip_comment (xp_awk_t* awk)
}
if (__unget_char(awk,c) == -1) return -1; /* error */
awk->lex.curc = XP_T('/');
awk->src.lex.curc = XP_T('/');
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_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_
@ -89,7 +89,7 @@ enum
/* afn (awk function defined with the keyword function) */
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_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
{
xp_char_t* name;
xp_size_t name_len;
xp_size_t nargs;
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>
@ -600,16 +600,9 @@ static int __main (int argc, xp_char_t* argv[])
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.out = XP_NULL;
srcios.custom_data = XP_NULL;
srcios.custom_data = &src_io;
if (xp_awk_parse (awk, &srcios) == -1)
{