*** empty log message ***

This commit is contained in:
hyung-hwan 2006-04-22 13:54:53 +00:00
parent 220dd573de
commit d53cc259a6
8 changed files with 278 additions and 89 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.44 2006-04-21 17:24:31 bacon Exp $
* $Id: awk.c,v 1.45 2006-04-22 13:54:52 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -24,7 +24,8 @@ xp_awk_t* xp_awk_open (void)
return XP_NULL;
}
if (xp_awk_map_open (&awk->tree.funcs, awk, 256, __free_func) == XP_NULL)
/* TODO: initial map size?? */
if (xp_awk_map_open(&awk->tree.funcs,awk,256,__free_func) == XP_NULL)
{
xp_str_close (&awk->token.name);
xp_free (awk);
@ -61,12 +62,8 @@ xp_awk_t* xp_awk_open (void)
awk->opt.parse = 0;
awk->opt.run = 0;
awk->errnum = XP_AWK_ENOERR;
awk->src_func = XP_NULL;
awk->in_func = XP_NULL;
awk->out_func = XP_NULL;
awk->src_arg = XP_NULL;
awk->in_arg = XP_NULL;
awk->out_arg = XP_NULL;
awk->srcio = XP_NULL;
awk->srcio_arg = XP_NULL;
awk->parse.nlocals_max = 0;
@ -109,6 +106,7 @@ void xp_awk_clear (xp_awk_t* awk)
xp_awk_tab_clear (&awk->parse.globals);
xp_awk_tab_clear (&awk->parse.locals);
xp_awk_tab_clear (&awk->parse.params);
awk->parse.nlocals_max = 0;
/* clear parse trees */
@ -135,8 +133,6 @@ void xp_awk_clear (xp_awk_t* awk)
awk->tree.chain = next;
}
awk->tree.chain_tail = XP_NULL;
/* TODO: destroy function list */
}
void xp_awk_setparseopt (xp_awk_t* awk, int opt)
@ -153,14 +149,14 @@ int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t src, void* arg)
{
if (xp_awk_detsrc(awk) == -1) return -1;
xp_assert (awk->src_func == XP_NULL);
if (src(XP_AWK_IO_OPEN, arg, XP_NULL, 0) == -1) {
awk->errnum = XP_AWK_ESRCOP;
xp_assert (awk->srcio == XP_NULL);
if (src(XP_AWK_INPUT_OPEN, arg, XP_NULL, 0) == -1) {
awk->errnum = XP_AWK_ESRCINOPEN;
return -1;
}
awk->src_func = src;
awk->src_arg = arg;
awk->srcio = src;
awk->srcio_arg = arg;
awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0;
return 0;
@ -168,13 +164,18 @@ int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t src, void* arg)
int xp_awk_detsrc (xp_awk_t* awk)
{
if (awk->src_func != XP_NULL) {
if (awk->src_func(XP_AWK_IO_CLOSE, awk->src_arg, XP_NULL, 0) == -1) {
awk->errnum = XP_AWK_ESRCCL;
if (awk->srcio != XP_NULL) {
xp_ssize_t n;
n = awk->srcio (XP_AWK_INPUT_CLOSE, awk->srcio_arg, XP_NULL, 0);
if (n == -1)
{
awk->errnum = XP_AWK_ESRCINCLOSE;
return -1;
}
awk->src_func = XP_NULL;
awk->src_arg = XP_NULL;
awk->srcio = XP_NULL;
awk->srcio_arg = XP_NULL;
awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.53 2006-04-18 16:04:54 bacon Exp $
* $Id: awk.h,v 1.54 2006-04-22 13:54:52 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -16,9 +16,15 @@ typedef xp_ssize_t (*xp_awk_io_t) (
/* io function commands */
enum
{
XP_AWK_IO_OPEN,
XP_AWK_IO_CLOSE,
XP_AWK_IO_DATA
XP_AWK_INPUT_OPEN = 0,
XP_AWK_INPUT_CLOSE = 1,
XP_AWK_INPUT_NEXT = 2,
XP_AWK_INPUT_DATA = 3,
XP_AWK_OUTPUT_OPEN = 4,
XP_AWK_OUTPUT_CLOSE = 5,
XP_AWK_OUTPUT_NEXT = 6,
XP_AWK_OUTPUT_DATA = 7
};
/* parse options */
@ -44,9 +50,13 @@ enum
XP_AWK_ENOERR, /* no error */
XP_AWK_ENOMEM, /* out of memory */
XP_AWK_ESRCOP,
XP_AWK_ESRCCL,
XP_AWK_ESRCDT, /* error in reading source */
XP_AWK_ESRCINOPEN,
XP_AWK_ESRCINCLOSE,
XP_AWK_ESRCINDATA, /* error in reading source */
XP_AWK_ETXTINOPEN,
XP_AWK_ETXTINCLOSE,
XP_AWK_ETXTINDATA, /* error in reading text */
XP_AWK_ELXCHR, /* lexer came accross an wrong character */
XP_AWK_ELXUNG, /* lexer failed to unget a character */
@ -101,13 +111,10 @@ void xp_awk_setrunopt (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);
int xp_awk_attin (xp_awk_t* awk, xp_awk_io_t in, void* arg);
int xp_awk_detin (xp_awk_t* awk);
int xp_awk_attout (xp_awk_t* awk, xp_awk_io_t out, void* arg);
int xp_awk_detout (xp_awk_t* awk);
/* TODO: xp_awk_parse (xp_awk_t* awk, xp_awk_io_t src, void* arg)??? */
int xp_awk_parse (xp_awk_t* awk);
int xp_awk_run (xp_awk_t* awk);
int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg);
/* utility functions exported by awk.h */
xp_long_t xp_awk_strtolong (

View File

@ -1,5 +1,5 @@
/*
* $Id: awk_i.h,v 1.7 2006-04-21 17:24:31 bacon Exp $
* $Id: awk_i.h,v 1.8 2006-04-22 13:54:52 bacon Exp $
*/
#ifndef _XP_AWK_AWKI_H_
@ -75,13 +75,8 @@ struct xp_awk_t
} opt;
/* io functions */
xp_awk_io_t src_func;
xp_awk_io_t in_func;
xp_awk_io_t out_func;
void* src_arg;
void* in_arg;
void* out_arg;
xp_awk_io_t srcio;
void* srcio_arg;
/* parse tree */
xp_awk_tree_t tree;
@ -136,12 +131,23 @@ struct xp_awk_run_t
xp_size_t icache_count;
xp_size_t rcache_count;
/* input_stream */
/* output_stream */
xp_awk_t* awk;
xp_awk_io_t txtio;
void* txtio_arg;
struct
{
xp_char_t buf[1024];
xp_size_t buf_pos;
xp_size_t buf_len;
xp_bool_t eof;
xp_str_t line;
} input;
int opt;
int errnum;
xp_awk_tree_t* tree;
xp_size_t nglobals;
};
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: err.c,v 1.12 2006-04-18 16:04:54 bacon Exp $
* $Id: err.c,v 1.13 2006-04-22 13:54:52 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -15,9 +15,15 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
{
XP_TEXT("no error"),
XP_TEXT("out of memory"),
XP_TEXT("cannot open source"),
XP_TEXT("cannot close source"),
XP_TEXT("cannot read source"),
XP_TEXT("cannot open source input"),
XP_TEXT("cannot close source input"),
XP_TEXT("cannot read source input"),
XP_TEXT("cannot open text input"),
XP_TEXT("cannot close text input"),
XP_TEXT("cannot read text input"),
XP_TEXT("invalid character"),
XP_TEXT("cannot unget character"),

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c,v 1.85 2006-04-19 03:42:08 bacon Exp $
* $Id: parse.c,v 1.86 2006-04-22 13:54:52 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -2802,10 +2802,10 @@ static int __get_char (xp_awk_t* awk)
return 0;
}
n = awk->src_func(XP_AWK_IO_DATA, awk->src_arg, &c, 1);
n = awk->srcio (XP_AWK_INPUT_DATA, awk->srcio_arg, &c, 1);
if (n == -1)
{
awk->errnum = XP_AWK_ESRCDT;
awk->errnum = XP_AWK_ESRCINDATA;
return -1;
}
awk->lex.curc = (n == 0)? XP_CHAR_EOF: c;

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.67 2006-04-21 17:24:31 bacon Exp $
* $Id: run.c,v 1.68 2006-04-22 13:54:52 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -31,14 +31,16 @@
#define EXIT_ABORT 5
#define PANIC(run,code) \
do { (run)->awk->errnum = (code); return XP_NULL; } while (0)
do { (run)->errnum = (code); return XP_NULL; } while (0)
#define PANIC_I(run,code) \
do { (run)->awk->errnum = (code); return -1; } while (0)
do { (run)->errnum = (code); return -1; } while (0)
static int __open_run (xp_awk_run_t* run, xp_awk_t* awk);
static int __open_run (
xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg);
static void __close_run (xp_awk_run_t* run);
static int __run_main (xp_awk_run_t* run);
static int __run_pattern_blocks (xp_awk_run_t* run);
static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde);
static int __run_statement (xp_awk_run_t* run, xp_awk_nde_t* nde);
static int __run_if_statement (xp_awk_run_t* run, xp_awk_nde_if_t* nde);
@ -126,9 +128,11 @@ static int __raw_push (xp_awk_run_t* run, void* val);
static void __raw_pop (xp_awk_run_t* run);
static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times);
static int __read_text_input (xp_awk_run_t* run);
static int __val_to_num (xp_awk_val_t* v, xp_long_t* l, xp_real_t* r);
static xp_char_t* __val_to_str (xp_awk_val_t* v, int* errnum);
typedef xp_awk_val_t* (*binop_func_t) (
xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right);
typedef xp_awk_val_t* (*eval_expr_t) (xp_awk_run_t* run, xp_awk_nde_t* nde);
@ -142,16 +146,33 @@ static int __printval (xp_awk_pair_t* pair)
return 0;
}
int xp_awk_run (xp_awk_t* awk)
int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg)
{
xp_awk_run_t run;
xp_awk_run_t* run;
int n;
if (__open_run (&run, awk) == -1) return -1;
if (__run_main (&run) == -1) return -1;
xp_printf (XP_TEXT("run.icache_count = %d\n"), run.icache_count);
__close_run (&run);
run = (xp_awk_run_t*) xp_malloc (xp_sizeof(xp_awk_run_t));
if (run == XP_NULL)
{
awk->errnum = XP_AWK_ENOMEM;
return -1;
}
return 0;
if (__open_run (run, awk, txtio, txtio_arg) == -1)
{
/* TODO: find a way to set the errnum into awk object in a thread-safe way */
awk->errnum = run->errnum;
xp_free (run);
return -1;
}
n = __run_main (run);
if (n == -1) awk->errnum = run->errnum;
__close_run (run);
xp_free (run);
return n;
}
static void __free_namedval (xp_awk_run_t* run, void* val)
@ -159,25 +180,40 @@ static void __free_namedval (xp_awk_run_t* run, void* val)
xp_awk_refdownval (run, val);
}
static int __open_run (xp_awk_run_t* run, xp_awk_t* awk)
static int __open_run (
xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg)
{
run->stack = XP_NULL;
run->stack_top = 0;
run->stack_base = 0;
run->stack_limit = 0;
run->exit_level = 0;
run->icache_count = 0;
run->rcache_count = 0;
run->awk = awk;
run->txtio = txtio;
run->txtio_arg = txtio_arg;
run->opt = awk->opt.run;
run->errnum = XP_AWK_ENOERR;
run->tree = &awk->tree;
run->nglobals = awk->tree.nglobals;
run->input.buf_pos = 0;
run->input.buf_len = 0;
if (xp_str_open (&run->input.line, 256) == XP_NULL)
{
run->errnum = XP_AWK_ENOMEM;
return -1;
}
if (xp_awk_map_open (&run->named,
run, 256, __free_namedval) == XP_NULL)
{
awk->errnum = XP_AWK_ENOMEM;
xp_str_close (&run->input.line);
run->errnum = XP_AWK_ENOMEM;
return -1;
}
@ -201,6 +237,9 @@ static void __close_run (xp_awk_run_t* run)
/* destroy named variables */
xp_awk_map_close (&run->named);
/* destroy input data */
xp_str_close (&run->input.line);
/* destroy values in free list */
while (run->icache_count > 0)
{
@ -244,6 +283,7 @@ static int __run_main (xp_awk_run_t* run)
if (run->opt & XP_AWK_RUNMAIN)
{
// TODO: should the main function be user-specifiable?
static xp_char_t m_a_i_n[] =
{
XP_CHAR('m'),
@ -282,6 +322,7 @@ static int __run_main (xp_awk_run_t* run)
__raw_pop_times (run, run->nglobals);
PANIC_I (run, XP_AWK_ENOMEM);
}
if (__raw_push(run,(void*)saved_stack_top) == -1)
{
run->stack_top = saved_stack_top;
@ -322,16 +363,9 @@ static int __run_main (xp_awk_run_t* run)
(xp_awk_nde_blk_t*)run->tree->begin) == -1) n = -1;
}
while (run->exit_level != EXIT_GLOBAL &&
run->exit_level != EXIT_ABORT)
if (n == 0 && run->txtio != XP_NULL)
{
run->exit_level = EXIT_NONE;
/*
* TODO: execute pattern blocks.
*/
break;
if (__run_pattern_blocks (run) == -1) n = -1;
}
if (n == 0 && run->tree->end != XP_NULL)
@ -386,6 +420,52 @@ xp_printf (XP_TEXT("-[END VARIABLES]--------------------------\n"));
return n;
}
static int __run_pattern_blocks (xp_awk_run_t* run)
{
xp_ssize_t n;
xp_assert (run->txtio != XP_NULL);
n = run->txtio (XP_AWK_INPUT_OPEN, run->txtio_arg, XP_NULL, 0);
if (n == -1) PANIC_I (run, XP_AWK_ETXTINOPEN);
run->input.buf_pos = 0;
run->input.buf_len = 0;
run->input.eof = xp_false;
while (run->exit_level != EXIT_GLOBAL &&
run->exit_level != EXIT_ABORT)
{
int x;
run->exit_level = EXIT_NONE;
x = __read_text_input(run);
if (x == -1)
{
/* don't care about the result of input close */
run->txtio (XP_AWK_INPUT_CLOSE,
run->txtio_arg, XP_NULL, 0);
return -1;
}
if (x == 0) break; /* end of input */
/*
* TODO: execute pattern blocks.
*/
/* for each block { run it }
* handle according if next and nextfile has been called
*/
xp_printf (XP_TEXT("**** line [%s]\n"), XP_STR_BUF(&run->input.line));
}
n = run->txtio (XP_AWK_INPUT_CLOSE, run->txtio_arg, XP_NULL, 0);
if (n == -1) PANIC_I (run, XP_AWK_ETXTINCLOSE);
return 0;
}
static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde)
{
@ -2413,6 +2493,48 @@ static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times)
}
}
static int __read_text_input (xp_awk_run_t* run)
{
xp_ssize_t n;
xp_char_t c;
xp_str_clear (&run->input.line);
if (run->input.eof) return 0;
while (1)
{
if (run->input.buf_pos >= run->input.buf_len)
{
n = run->txtio (XP_AWK_INPUT_DATA, run->txtio_arg,
run->input.buf, xp_countof(run->input.buf));
if (n == -1) PANIC_I (run, XP_AWK_ETXTINDATA);
if (n == 0)
{
if (XP_STR_LEN(&run->input.line) == 0) return 0;
run->input.eof = xp_true;
break;
}
run->input.buf_pos = 0;
run->input.buf_len = n;
}
c = run->input.buf[run->input.buf_pos++];
if (xp_str_ccat (&run->input.line, c) == (xp_size_t)-1)
{
PANIC_I (run, XP_AWK_ENOMEM);
}
/* TODO: use LF instead of this hard coded value */
/* any better way to tell line terminating with newlines?
* line with new line characters removed or retained? */
if (c == XP_CHAR('\n')) break;
}
return 1;
}
static int __val_to_num (xp_awk_val_t* v, xp_long_t* l, xp_real_t* r)
{
if (v->type == XP_AWK_VAL_NIL)

View File

@ -1,5 +1,5 @@
/*
* $Id: run.h,v 1.9 2006-04-14 16:26:00 bacon Exp $
* $Id: run.h,v 1.10 2006-04-22 13:54:52 bacon Exp $
*/
#ifndef _XP_AWK_RUN_H_
@ -9,16 +9,6 @@
#error Never include this file directly. Include <xp/awk/awk.h> instead
#endif
typedef struct xp_awk_frm_t xp_awk_frm_t;
struct xp_awk_frm_t
{
xp_size_t nparams;
xp_size_t nlocals;
xp_awk_val_t* stack;
xp_awk_frm_t* prev;
};
enum
{
/* if you change this, you have to change __assop_str in tree.c */

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.25 2006-04-19 02:52:53 bacon Exp $
* $Id: awk.c,v 1.26 2006-04-22 13:54:53 bacon Exp $
*/
#include <xp/awk/awk.h>
@ -35,11 +35,12 @@ static xp_ssize_t process_source (
xp_char_t c;
switch (cmd) {
case XP_AWK_IO_OPEN:
case XP_AWK_IO_CLOSE:
case XP_AWK_INPUT_OPEN:
case XP_AWK_INPUT_CLOSE:
case XP_AWK_INPUT_NEXT:
return 0;
case XP_AWK_IO_DATA:
case XP_AWK_INPUT_DATA:
if (size <= 0) return -1;
#ifdef XP_CHAR_IS_MCHAR
c = fgetc (stdin);
@ -49,11 +50,66 @@ static xp_ssize_t process_source (
if (c == XP_CHAR_EOF) return 0;
*data = c;
return 1;
case XP_AWK_OUTPUT_OPEN:
case XP_AWK_OUTPUT_CLOSE:
case XP_AWK_OUTPUT_NEXT:
case XP_AWK_OUTPUT_DATA:
return 0;
}
return -1;
}
struct data_io
{
const char* input_file;
FILE* input_handle;
};
static xp_ssize_t process_data (
int cmd, void* arg, xp_char_t* data, xp_size_t size)
{
struct data_io* io = (struct data_io*)arg;
xp_char_t c;
switch (cmd) {
case XP_AWK_INPUT_OPEN:
io->input_handle = fopen (io->input_file, "r");
if (io->input_handle == NULL) return -1;
return 0;
case XP_AWK_INPUT_CLOSE:
fclose (io->input_handle);
io->input_handle = NULL;
return 0;
case XP_AWK_INPUT_NEXT:
/* input switching not supported for the time being... */
return -1;
case XP_AWK_INPUT_DATA:
if (size <= 0) return -1;
#ifdef XP_CHAR_IS_MCHAR
c = fgetc (io->input_handle);
#else
c = fgetwc (io->input_handle);
#endif
if (c == XP_CHAR_EOF) return 0;
*data = c;
return 1;
case XP_AWK_OUTPUT_OPEN:
case XP_AWK_OUTPUT_CLOSE:
case XP_AWK_OUTPUT_NEXT:
case XP_AWK_OUTPUT_DATA:
return -1;
}
return -1;
}
#ifdef __linux
#include <mcheck.h>
#endif
@ -65,6 +121,7 @@ int xp_main (int argc, xp_char_t* argv[])
#endif
{
xp_awk_t* awk;
struct data_io data_io = { "awk.in", NULL };
#ifdef __linux
mtrace ();
@ -114,7 +171,7 @@ int xp_main (int argc, xp_char_t* argv[])
return -1;
}
if (xp_awk_run(awk) == -1)
if (xp_awk_run (awk, process_data, (void*)&data_io) == -1)
{
#if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR)
xp_printf (