diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 0e1fa07c..04864f13 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.81 2006-07-26 16:43:35 bacon Exp $ + * $Id: awk.h,v 1.82 2006-07-27 16:50:28 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -180,9 +180,8 @@ int xp_awk_detsrc (xp_awk_t* awk); int xp_awk_setextio (xp_awk_t* awk, int id, xp_awk_io_t handler, void* arg); xp_size_t xp_awk_getsrcline (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, xp_awk_io_t txtio, void* txtio_arg); +int xp_awk_run (xp_awk_t* awk); /* functions to access internal stack structure */ xp_size_t xp_awk_getnargs (void* run); diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 338ee7ee..37c3ea1d 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.34 2006-07-26 16:43:35 bacon Exp $ + * $Id: awk_i.h,v 1.35 2006-07-27 16:50:28 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ @@ -164,9 +164,6 @@ struct xp_awk_run_t xp_size_t icache_count; xp_size_t rcache_count; - xp_awk_io_t txtio; - void* txtio_arg; - struct { xp_char_t buf[1024]; diff --git a/ase/awk/extio.c b/ase/awk/extio.c index ee8bf7c1..482d7177 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.19 2006-07-14 04:19:21 bacon Exp $ + * $Id: extio.c,v 1.20 2006-07-27 16:50:28 bacon Exp $ */ #include @@ -45,7 +45,7 @@ int xp_awk_readextio ( XP_AWK_IO_PIPE_READ, 0, XP_AWK_IO_FILE_READ, - XP_AWK_IO_FILE_READ + XP_AWK_IO_CONSOLE_READ }; static int __in_mask_map[] = diff --git a/ase/awk/run.c b/ase/awk/run.c index 7a52edf3..d4276319 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.140 2006-07-26 16:43:35 bacon Exp $ + * $Id: run.c,v 1.141 2006-07-27 16:50:28 bacon Exp $ */ #include @@ -47,8 +47,7 @@ enum #define PANIC2_I(awk,code,subcode) \ do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return -1; } while (0) -static int __open_run ( - xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg); +static int __open_run (xp_awk_run_t* run, xp_awk_t* awk); static void __close_run (xp_awk_run_t* run); static int __run_main (xp_awk_run_t* run); @@ -165,6 +164,8 @@ 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_record (xp_awk_run_t* run); +static int __set_record ( + xp_awk_run_t* run, const xp_char_t* str, xp_size_t len); static int __split_record (xp_awk_run_t* run); static void __clear_record (xp_awk_run_t* run, xp_bool_t noline); static int __recomp_record_fields (xp_awk_run_t* run, @@ -218,7 +219,7 @@ void xp_awk_seterrnum (void* run, int errnum) r->errnum = errnum; } -int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg) +int xp_awk_run (xp_awk_t* awk) { xp_awk_run_t* run; int n; @@ -230,7 +231,7 @@ int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg) return -1; } - if (__open_run (run, awk, txtio, txtio_arg) == -1) + if (__open_run (run, awk) == -1) { /* TODO: find a way to set the errnum into awk object in a thread-safe way */ awk->errnum = run->errnum; @@ -252,8 +253,7 @@ static void __free_namedval (void* run, void* val) xp_awk_refdownval ((xp_awk_run_t*)run, val); } -static int __open_run ( - xp_awk_run_t* run, xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg) +static int __open_run (xp_awk_run_t* run, xp_awk_t* awk) { xp_memset (run, 0, xp_sizeof(*run)); @@ -267,9 +267,6 @@ static int __open_run ( run->icache_count = 0; run->rcache_count = 0; - run->txtio = txtio; - run->txtio_arg = txtio_arg; - run->opt = awk->opt.run; run->errnum = XP_AWK_ENOERR; /*run->tree = &awk->tree; */ @@ -463,7 +460,7 @@ static int __run_main (xp_awk_run_t* run) if (__run_block (run, blk) == -1) n = -1; } - if (n == 0 && run->txtio != XP_NULL) + if (n == 0) { if (__run_pattern_blocks (run) == -1) n = -1; } @@ -524,11 +521,7 @@ xp_printf (XP_T("-[END VARIABLES]--------------------------\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_IO_OPEN, 0, run->txtio_arg, XP_NULL, 0); - if (n == -1) PANIC_I (run, XP_AWK_ETXTINOPEN); + int errnum; run->inrec.buf_pos = 0; run->inrec.buf_len = 0; @@ -545,8 +538,7 @@ static int __run_pattern_blocks (xp_awk_run_t* run) if (x == -1) { /* don't care about the result of input close */ - run->txtio (XP_AWK_IO_CLOSE, 0, - run->txtio_arg, XP_NULL, 0); + xp_awk_closeextio (run, XP_T(""), &errnum); return -1; } @@ -554,15 +546,26 @@ static int __run_pattern_blocks (xp_awk_run_t* run) if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1) { - /* don't care about the result of input close */ - run->txtio (XP_AWK_IO_CLOSE, 0, - run->txtio_arg, XP_NULL, 0); + xp_awk_closeextio (run, XP_T(""), &errnum); return -1; } } - n = run->txtio (XP_AWK_IO_CLOSE, 0, run->txtio_arg, XP_NULL, 0); - if (n == -1) PANIC_I (run, XP_AWK_ETXTINCLOSE); + /* In case of getline, the code would getline return -1, set ERRNO, + * and make this function return 0 after having checke if closextio + * has returned -1 and errnum has been set to XP_AWK_ENOERR. + * But this part of the code ends the input for the implicit + * pattern-block loop, which is totally different from getline. + * So it just returns -1 as long as closeextio returns -1 regardless + * of the value of errnum */ + n = xp_awk_closeextio (run, XP_T(""), &errnum); + if (n == -1) + { + if (errnum == XP_AWK_ENOERR) + PANIC_I (run, XP_AWK_ETXTINCLOSE); + else + PANIC_I (run, errnum); + } return 0; } @@ -1158,13 +1161,17 @@ static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde) static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde) { - xp_ssize_t n; +// xp_ssize_t n; /* TODO: implement this properly */ /* TODO: how to pass opt properly for IO_NEXT??? -> READ? WRITE? */ +/* n = run->txtio (XP_AWK_IO_NEXT, 0, run->txtio_arg, XP_NULL, 0); if (n == -1) PANIC_I (run, XP_AWK_ETXTINNEXT); return (n == -1)? -1: 0; +*/ +xp_printf (XP_T("nextfile not implemented....\n")); + return -1; } static int __run_delete (xp_awk_run_t* run, xp_awk_nde_delete_t* nde) @@ -3578,8 +3585,16 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) { if (p->var == XP_NULL) { - /* TODO: set $0 if var is null */ - xp_printf (XP_T("set %s to $0\n"), XP_STR_BUF(&buf)); + /* set $0 with the input value */ + __clear_record (run, xp_false); + + if (__set_record (run, + XP_STR_BUF(&buf), XP_STR_LEN(&buf)) == -1) + { + xp_str_close (&buf); + return XP_NULL; + } + xp_str_close (&buf); } else @@ -3602,6 +3617,10 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) xp_awk_refdownval (run, v); } } + else + { + xp_str_close (&buf); + } res = xp_awk_makeintval (run, n); if (res == XP_NULL) PANIC (run, XP_AWK_ENOMEM); @@ -3646,51 +3665,39 @@ static void __raw_pop_times (xp_awk_run_t* run, xp_size_t times) static int __read_record (xp_awk_run_t* run) { xp_ssize_t n; - xp_char_t c; - xp_awk_val_t* v; + int errnum; __clear_record (run, xp_false); - while (1) + /*TODO: use RS */ + n = xp_awk_readextio ( + run, XP_AWK_EXTIO_CONSOLE, + XP_T(""), &run->inrec.line, &errnum); + if (n < 0) { - if (run->inrec.buf_pos >= run->inrec.buf_len) - { - if (run->inrec.eof) - { - if (XP_STR_LEN(&run->inrec.line) == 0) return 0; - break; - } - - n = run->txtio (XP_AWK_IO_READ, 0, run->txtio_arg, - run->inrec.buf, xp_countof(run->inrec.buf)); - if (n == -1) PANIC_I (run, XP_AWK_ETXTINDATA); - if (n == 0) - { - run->inrec.eof = xp_true; - if (XP_STR_LEN(&run->inrec.line) == 0) return 0; - break; - } - - run->inrec.buf_len = n; - run->inrec.buf_pos = 0; - } - - c = run->inrec.buf[run->inrec.buf_pos++]; - - /* TODO: use RS 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_T('\n')) break; - - if (xp_str_ccat (&run->inrec.line, c) == (xp_size_t)-1) - { - PANIC_I (run, XP_AWK_ENOMEM); - } + if (errnum == XP_AWK_ENOERR) + PANIC_I (run, XP_AWK_ETXTINDATA); + else + PANIC_I (run, errnum); + } + if (n == 0) + { + xp_assert (XP_STR_LEN(&run->inrec.line) == 0); + return 0; } - v = xp_awk_makestrval ( + if (__set_record (run, XP_STR_BUF(&run->inrec.line), - XP_STR_LEN(&run->inrec.line)); + XP_STR_LEN(&run->inrec.line)) == -1) return -1; + + return 1; +} + +static int __set_record (xp_awk_run_t* run, const xp_char_t* str, xp_size_t len) +{ + xp_awk_val_t* v; + + v = xp_awk_makestrval (str, len); if (v == XP_NULL) { __clear_record (run, xp_false); @@ -3698,8 +3705,8 @@ static int __read_record (xp_awk_run_t* run) } xp_assert (run->inrec.d0 == xp_awk_val_nil); - /* the record has been cleared in the beginning of the function. - * so xp_awk_refdownval is not needed over run->inrec.d0 */ + /* the record should be clear cleared before this function is called + * as it doesn't call xp_awk_refdownval on run->inrec.d0 */ run->inrec.d0 = v; xp_awk_refupval (v); @@ -3709,7 +3716,7 @@ static int __read_record (xp_awk_run_t* run) return -1; } - return 1; /* has read a record */ + return 0; /* success */ } static int __split_record (xp_awk_run_t* run) diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index c958eb97..579291ec 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.53 2006-07-26 16:43:35 bacon Exp $ + * $Id: awk.c,v 1.54 2006-07-27 16:50:29 bacon Exp $ */ #include @@ -14,6 +14,7 @@ #include #include #include + #include #else #include #ifndef PATH_MAX @@ -36,6 +37,9 @@ extern int xp_awk_strcmp (const xp_char_t* s1, const xp_char_t* s2); #define xp_strlen xp_awk_strlen extern int xp_awk_strlen (const xp_char_t* s); + + #include + #define xp_assert assert #endif #if defined(_WIN32) && defined(__STAND_ALONE) && defined(_DEBUG) @@ -177,59 +181,6 @@ static xp_ssize_t process_source ( return -1; } - - -static xp_ssize_t process_data ( - int cmd, int opt, 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_IO_OPEN: - { - io->input_handle = fopen (io->input_file, "r"); - if (io->input_handle == NULL) return -1; - return 0; - } - - case XP_AWK_IO_CLOSE: - { - fclose (io->input_handle); - io->input_handle = NULL; - return 0; - } - - case XP_AWK_IO_READ: - { - 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_IO_WRITE: - { - return -1; - } - - case XP_AWK_IO_NEXT: - { - /* input switching not supported for the time being... */ - return -1; - } - - } - - return -1; -} - static xp_ssize_t process_extio_pipe ( int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) { @@ -347,11 +298,21 @@ xp_printf (XP_TEXT("closing %s of type %d (file)\n"), epa->name, epa->type); return -1; } + static xp_ssize_t process_extio_console ( int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) { xp_awk_extio_t* epa = (xp_awk_extio_t*)arg; + static const xp_char_t* infiles[] = + { + XP_T(""), + //XP_T("awk.in"), + XP_NULL + }; + + static xp_size_t infile_no = 0; + switch (cmd) { case XP_AWK_IO_OPEN: @@ -360,11 +321,42 @@ static xp_ssize_t process_extio_console ( /* opt: XP_AWK_IO_CONSOLE_READ, * XP_AWK_IO_CONSOLE_WRITE */ -xp_printf (XP_TEXT("opening [%s] of type %d (console)\n"), epa->name, epa->type); + /* epa->name is always empty for console */ + xp_assert (epa->name[0] == XP_T('\0')); + +xp_printf (XP_TEXT("opening console of type %x\n"), epa->type); + if (opt == XP_AWK_IO_CONSOLE_READ) - epa->handle = stdin; + { + if (infiles[infile_no] == XP_NULL) + { + /* no input file */ +xp_printf (XP_TEXT("failed to open console of type %x - no more input file\n"), epa->type); + return -1; + } + else if (infiles[infile_no][0] == XP_T('\0')) + { +xp_printf (XP_T(" console(r) - \n")); + epa->handle = stdin; + } + else + { +xp_printf (XP_T(" console(r) - %s\n"), infiles[infile_no]); + epa->handle = fopen_t (infiles[infile_no], XP_T("r")); + if (epa->handle == XP_NULL) + { +xp_printf (XP_TEXT("failed to open console of type %x - fopen failure\n"), epa->type); + return -1; + } + } + + infile_no++; + } else if (opt == XP_AWK_IO_CONSOLE_WRITE) + { +xp_printf (XP_T(" console(w) - \n")); epa->handle = stdout; + } else return -1; return 0; @@ -372,18 +364,41 @@ xp_printf (XP_TEXT("opening [%s] of type %d (console)\n"), epa->name, epa->type case XP_AWK_IO_CLOSE: { -xp_printf (XP_TEXT("closing [%s] of type %d (console)\n"), epa->name, epa->type); +xp_printf (XP_TEXT("closing [%s] of type %x (console)\n"), epa->name, epa->type); /* TODO: CloseConsole in GUI APPLICATION */ return 0; } case XP_AWK_IO_READ: { - if (fgets_t (data, size, (FILE*)epa->handle) == XP_NULL) - /*if (fgets_t (data, size, stdin) == XP_NULL)*/ + while (fgets_t (data, size, (FILE*)epa->handle) == XP_NULL) { - return 0; + /* it has reached the end of the current file. + * open the next file if available */ + if (infiles[infile_no] == XP_NULL) + { + /* no more input console */ + return 0; + } + + if (epa->handle != stdin) fclose (epa->handle); + if (infiles[infile_no][0] == XP_T('\0')) + { + epa->handle = stdin; + } + else + { + epa->handle = fopen_t (infiles[infile_no], XP_T("r")); + if (epa->handle == XP_NULL) + { +xp_printf (XP_TEXT("failed to open the next console of type %x - fopen failure\n"), epa->type); + return -1; + } + } + + infile_no++; } + return xp_strlen(data); } @@ -526,7 +541,7 @@ static int __main (int argc, xp_char_t* argv[]) return -1; } - if (xp_awk_run (awk, process_data, (void*)&data_io) == -1) + if (xp_awk_run (awk) == -1) { #if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR) xp_printf ( diff --git a/ase/test/awk/t17.awk b/ase/test/awk/t17.awk index 4acfb3de..8cb09878 100644 --- a/ase/test/awk/t17.awk +++ b/ase/test/awk/t17.awk @@ -1 +1,9 @@ -/hello[[:space:]]/ { print $0; } +/hello[[:space:]]/ +{ + print $0; + //getline a; + //print a; + + if (getline > 0) print $0; + print "----------------"; +}