diff --git a/ase/awk/StdAwk.cpp b/ase/awk/StdAwk.cpp index 281ee32f..4d163b6a 100644 --- a/ase/awk/StdAwk.cpp +++ b/ase/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp,v 1.14 2007/05/16 14:44:13 bacon Exp $ + * $Id: StdAwk.cpp,v 1.15 2007/05/18 15:36:02 bacon Exp $ */ #include @@ -26,44 +26,49 @@ namespace ASE ::srand (seed); } + #define ADD_FUNC(name,min,max,impl) \ + do { \ + if (addFunction (name, min, max, \ + (FunctionHandler)impl) == -1) return -1; \ + } while (0) + int StdAwk::open () { int n = Awk::open (); - if (n == 0) - { - int opt = - ASE_AWK_IMPLICIT | - ASE_AWK_EXPLICIT | - ASE_AWK_UNIQUEFN | - ASE_AWK_IDIV | - ASE_AWK_SHADING | - ASE_AWK_SHIFT | - ASE_AWK_EXTIO | - ASE_AWK_BLOCKLESS | - ASE_AWK_STRBASEONE | - ASE_AWK_STRIPSPACES | - ASE_AWK_NEXTOFILE | - ASE_AWK_ARGSTOMAIN; - ase_awk_setoption (awk, opt); + if (n == -1) return n; + + int opt = + ASE_AWK_IMPLICIT | + ASE_AWK_EXPLICIT | + ASE_AWK_UNIQUEFN | + ASE_AWK_IDIV | + ASE_AWK_SHADING | + ASE_AWK_SHIFT | + ASE_AWK_EXTIO | + ASE_AWK_BLOCKLESS | + ASE_AWK_STRBASEONE | + ASE_AWK_STRIPSPACES | + ASE_AWK_NEXTOFILE | + ASE_AWK_ARGSTOMAIN; + ase_awk_setoption (awk, opt); - addFunction (ASE_T("sin"), 1, 1, (FunctionHandler)&StdAwk::sin); - addFunction (ASE_T("cos"), 1, 1, (FunctionHandler)&StdAwk::cos); - addFunction (ASE_T("tan"), 1, 1, (FunctionHandler)&StdAwk::tan); - addFunction (ASE_T("atan2"), 2, 2, (FunctionHandler)&StdAwk::atan2); - addFunction (ASE_T("log"), 1, 1, (FunctionHandler)&StdAwk::log); - addFunction (ASE_T("exp"), 1, 1, (FunctionHandler)&StdAwk::exp); - addFunction (ASE_T("sqrt"), 1, 1, (FunctionHandler)&StdAwk::sqrt); - addFunction (ASE_T("int"), 1, 1, (FunctionHandler)&StdAwk::fnint); - addFunction (ASE_T("rand"), 0, 0, (FunctionHandler)&StdAwk::rand); - addFunction (ASE_T("srand"), 1, 1, (FunctionHandler)&StdAwk::srand); - addFunction (ASE_T("systime"), 0, 0, (FunctionHandler)&StdAwk::systime); - addFunction (ASE_T("strftime"), 0, 2, (FunctionHandler)&StdAwk::strftime); - addFunction (ASE_T("strfgmtime"), 0, 2, (FunctionHandler)&StdAwk::strfgmtime); - addFunction (ASE_T("system"), 1, 1, (FunctionHandler)&StdAwk::system); - } + ADD_FUNC (ASE_T("sin"), 1, 1, &StdAwk::sin); + ADD_FUNC (ASE_T("cos"), 1, 1, &StdAwk::cos); + ADD_FUNC (ASE_T("tan"), 1, 1, &StdAwk::tan); + ADD_FUNC (ASE_T("atan2"), 2, 2, &StdAwk::atan2); + ADD_FUNC (ASE_T("log"), 1, 1, &StdAwk::log); + ADD_FUNC (ASE_T("exp"), 1, 1, &StdAwk::exp); + ADD_FUNC (ASE_T("sqrt"), 1, 1, &StdAwk::sqrt); + ADD_FUNC (ASE_T("int"), 1, 1, &StdAwk::fnint); + ADD_FUNC (ASE_T("rand"), 0, 0, &StdAwk::rand); + ADD_FUNC (ASE_T("srand"), 1, 1, &StdAwk::srand); + ADD_FUNC (ASE_T("systime"), 0, 0, &StdAwk::systime); + ADD_FUNC (ASE_T("strftime"), 0, 2, &StdAwk::strftime); + ADD_FUNC (ASE_T("strfgmtime"), 0, 2, &StdAwk::strfgmtime); + ADD_FUNC (ASE_T("system"), 1, 1, &StdAwk::system); - return n; + return 0; } int StdAwk::sin (Return* ret, const Argument* args, size_t nargs) @@ -228,8 +233,20 @@ namespace ASE StdAwk::ssize_t StdAwk::readPipe (Pipe& io, char_t* buf, size_t len) { - // TODO: change this implementation... FILE* fp = (FILE*)io.getHandle(); + ssize_t n = 0; + + while (n < len) + { + ase_cint_t c = ase_fgetc (fp); + if (c == ASE_CHAR_EOF) break; + + buf[n++] = c; + if (c == ASE_T('\n')) break; + } + + return n; + /* if (ase_fgets (buf, len, fp) == ASE_NULL) { if (ferror(fp)) return -1; @@ -237,6 +254,7 @@ namespace ASE } return ase_strlen(buf); + */ } @@ -326,8 +344,21 @@ namespace ASE StdAwk::ssize_t StdAwk::readFile (File& io, char_t* buf, size_t len) { - // TODO: replace ase_fgets by something else FILE* fp = (FILE*)io.getHandle(); + ssize_t n = 0; + + while (n < len) + { + ase_cint_t c = ase_fgetc (fp); + if (c == ASE_CHAR_EOF) break; + + buf[n++] = c; + if (c == ASE_T('\n')) break; + } + + return n; + + /* if (ase_fgets (buf, len, fp) == ASE_NULL) { if (ferror(fp)) return -1; @@ -335,6 +366,7 @@ namespace ASE } return ase_strlen(buf); + */ } StdAwk::ssize_t StdAwk::writeFile (File& io, char_t* buf, size_t len) diff --git a/ase/awk/extio.c b/ase/awk/extio.c index e942124e..4d829013 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.3 2007/04/30 05:47:33 bacon Exp $ + * $Id: extio.c,v 1.4 2007/05/18 16:19:20 bacon Exp $ * * {License} */ @@ -247,7 +247,44 @@ int ase_awk_readextio ( if (n == 0) { p->in.eof = ase_true; + if (ASE_STR_LEN(buf) == 0) ret = 0; + else if (rs_len >= 2) + { + /* when RS is multiple characters, it needs to check + * for the match at the end of the input stream as + * the buffer has been appened with the last character + * after the previous matchrex has failed */ + + const ase_char_t* match_ptr; + ase_size_t match_len; + + ASE_ASSERT (run->global.rs != ASE_NULL); + + n = ase_awk_matchrex ( + run->awk, run->global.rs, + ((run->global.ignorecase)? ASE_AWK_REX_IGNORECASE: 0), + ASE_STR_BUF(buf), ASE_STR_LEN(buf), + &match_ptr, &match_len, &run->errnum); + if (n == -1) + { + ret = -1; + break; + } + + if (n == 1) + { + /* the match should be found at the end of + * the current buffer */ + ASE_ASSERT ( + ASE_STR_BUF(buf) + ASE_STR_LEN(buf) == + match_ptr + match_len); + + ASE_STR_LEN(buf) -= match_len; + break; + } + } + break; } @@ -320,6 +357,7 @@ int ase_awk_readextio ( if (n == -1) { ret = -1; + p->in.pos--; /* unread the character in c */ break; } @@ -332,6 +370,7 @@ int ase_awk_readextio ( match_ptr + match_len); ASE_STR_LEN(buf) -= match_len; + p->in.pos--; /* unread the character in c */ break; } } diff --git a/ase/change.log b/ase/change.log index 282733c2..d20a0e89 100644 --- a/ase/change.log +++ b/ase/change.log @@ -4,6 +4,10 @@ * fixed bug (nextofile not allowed in the BEGIN and END block) * fixed bug (ASE_MALLOC/ASE_FREE defined wrongly causing test programs to crash in the debug mode when compiled with MSVC/C++. +* fixed bug (the first character of the next record lost when RS are + multiple characters) +* fixed bug (the last field of the last record lost when RS are + multiple characters) * added awk c++ classes (awk/Awk.hpp awk/Awk.cpp awk/StdAwk.hpp awk/StdAwk.cpp) * added c++ test program (test/awk/Awk.cpp) diff --git a/ase/test/awk/adr-001.awk b/ase/test/awk/adr-001.awk new file mode 100644 index 00000000..e2a1bf52 --- /dev/null +++ b/ase/test/awk/adr-001.awk @@ -0,0 +1,9 @@ +#!/bin/awk + +BEGIN { + RS = "\n\n"; + FS = "\n"; +} +{ + print $1, $NF; +} diff --git a/ase/test/awk/adr-001.out b/ase/test/awk/adr-001.out new file mode 100644 index 00000000..90718fb0 --- /dev/null +++ b/ase/test/awk/adr-001.out @@ -0,0 +1,12 @@ +BEGIN { + RS = "\n\n"; + FS = "\n"; +} + +{ + print $1,$NF; +} + +James Brown 012-345-678 +Richie Ren 02-3473-9192 +Toh WeeKung 9102-1203 diff --git a/ase/test/awk/adr-en.data b/ase/test/awk/adr-en.data new file mode 100644 index 00000000..e170e0f3 --- /dev/null +++ b/ase/test/awk/adr-en.data @@ -0,0 +1,15 @@ +James Brown +IBM +Somewhere over the rainbow +012-345-678 + +Richie Ren +Ezsystem +Taipei Taiwan +02-3473-9192 + +Toh WeeKung +Topaz +Singapore +9102-1203 + diff --git a/ase/test/awk/regress.sh b/ase/test/awk/regress.sh index 589a4cfa..d79340e6 100755 --- a/ase/test/awk/regress.sh +++ b/ase/test/awk/regress.sh @@ -21,6 +21,11 @@ run_init() run_script_for_init "$script" "cou-en.data" done + for script in adr-???.awk + do + run_script_for_init "$script" "adr-en.data" + done + for script in err-???.awk do run_script_for_init "$script" "err-en.data" @@ -88,6 +93,24 @@ run_test() fi done + for script in adr-???.awk + do + run_script_for_test "$script" "adr-en.data" + if [ $? -ne 0 ] + then + echo "###################################" + echo "PROBLEM(S) DETECTED IN $script.". + echo "###################################" + + echo "Do you want to abort? [y/n]" + read ans + if [ "$ans" = "y" -o "$ans" = "Y" ] + then + return 1 + fi + fi + done + for script in err-???.awk do run_script_for_test "$script" "err-en.data"