diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 09afebbe..8ba84743 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: awk.c 447 2011-05-01 13:28:51Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -369,23 +369,23 @@ struct opttab_t const qse_char_t* desc; } opttab[] = { - { QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") }, - { QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") }, - { QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,//)") }, - { QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") }, - { QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") }, - { QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") }, - { QSE_T("striprecspc"), QSE_AWK_STRIPRECSPC, QSE_T("strip spaces in splitting a record") }, - { QSE_T("stripstrspc"), QSE_AWK_STRIPSTRSPC, QSE_T("strip spaces in converting a string to a number") }, - { QSE_T("nextofile"), QSE_AWK_NEXTOFILE, QSE_T("enable 'nextofile'") }, - { QSE_T("reset"), QSE_AWK_RESET, QSE_T("enable 'reset'") }, - { QSE_T("crlf"), QSE_AWK_CRLF, QSE_T("use CRLF for a newline") }, - { QSE_T("maptovar"), QSE_AWK_MAPTOVAR, QSE_T("allow a map to be assigned or returned") }, - { QSE_T("pablock"), QSE_AWK_PABLOCK, QSE_T("enable pattern-action loop") }, - { QSE_T("rexbound"), QSE_AWK_REXBOUND, QSE_T("enable {n,m} in a regular expression") }, - { QSE_T("ncmponstr"), QSE_AWK_NCMPONSTR, QSE_T("perform numeric comparsion on numeric strings") }, - { QSE_T("strictnaming"), QSE_AWK_STRICTNAMING, QSE_T("enable the strict naming rule") }, - { QSE_T("include"), QSE_AWK_INCLUDE, QSE_T("enable 'include'") }, + { QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") }, + { QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") }, + { QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,//)") }, + { QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") }, + { QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") }, + { QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") }, + { QSE_T("striprecspc"), QSE_AWK_STRIPRECSPC, QSE_T("strip spaces in splitting a record") }, + { QSE_T("stripstrspc"), QSE_AWK_STRIPSTRSPC, QSE_T("strip spaces in converting a string to a number") }, + { QSE_T("nextofile"), QSE_AWK_NEXTOFILE, QSE_T("enable 'nextofile'") }, + { QSE_T("reset"), QSE_AWK_RESET, QSE_T("enable 'reset'") }, + { QSE_T("crlf"), QSE_AWK_CRLF, QSE_T("use CRLF for a newline") }, + { QSE_T("maptovar"), QSE_AWK_MAPTOVAR, QSE_T("allow a map to be assigned or returned") }, + { QSE_T("pablock"), QSE_AWK_PABLOCK, QSE_T("enable pattern-action loop") }, + { QSE_T("rexbound"), QSE_AWK_REXBOUND, QSE_T("enable {n,m} in a regular expression") }, + { QSE_T("ncmponstr"), QSE_AWK_NCMPONSTR, QSE_T("perform numeric comparsion on numeric strings") }, + { QSE_T("strictnaming"), QSE_AWK_STRICTNAMING, QSE_T("enable the strict naming rule") }, + { QSE_T("include"), QSE_AWK_INCLUDE, QSE_T("enable 'include'") }, { QSE_NULL, 0 } }; diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index 9374e994..8644eae4 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: awk.c 447 2011-05-01 13:28:51Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -223,7 +223,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) qse_lda_setcopier (awk->parse.params, QSE_LDA_COPIER_INLINE); awk->option = QSE_AWK_CLASSIC; -#if defined(_WIN32) || defined(__OS2__) +#if defined(__OS2__) || defined(_WIN32) || defined(__DOS__) awk->option |= QSE_AWK_CRLF; #endif diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index 81177336..51c3e943 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -1,5 +1,5 @@ /* - * $Id: rio.c 446 2011-04-30 15:24:38Z hyunghwan.chung $ + * $Id: rio.c 447 2011-05-01 13:28:51Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -22,10 +22,10 @@ enum io_mask_t { - MASK_READ = 0x0100, - MASK_WRITE = 0x0200, - MASK_RDWR = 0x0400, - MASK_CLEAR = 0x00FF + IO_MASK_READ = 0x0100, + IO_MASK_WRITE = 0x0200, + IO_MASK_RDWR = 0x0400, + IO_MASK_CLEAR = 0x00FF }; static int in_type_map[] = @@ -50,10 +50,10 @@ static int in_mode_map[] = static int in_mask_map[] = { - MASK_READ, - MASK_RDWR, - MASK_READ, - MASK_READ + IO_MASK_READ, + IO_MASK_RDWR, + IO_MASK_READ, + IO_MASK_READ }; static int out_type_map[] = @@ -80,11 +80,11 @@ static int out_mode_map[] = static int out_mask_map[] = { - MASK_WRITE, - MASK_RDWR, - MASK_WRITE, - MASK_WRITE, - MASK_WRITE + IO_MASK_WRITE, + IO_MASK_RDWR, + IO_MASK_WRITE, + IO_MASK_WRITE, + IO_MASK_WRITE }; static int find_rio_in ( @@ -249,7 +249,8 @@ static QSE_INLINE int match_long_rs ( * A match in this case must end at the end of * the current record buffer */ QSE_ASSERT ( - QSE_STR_PTR(buf) + QSE_STR_LEN(buf) == match.ptr + match.len + QSE_STR_PTR(buf) + QSE_STR_LEN(buf) == + match.ptr + match.len ); /* drop the RS part. no extra character after RS to drop @@ -462,28 +463,36 @@ int qse_awk_rtx_readio ( if (pc == QSE_T('\r') && QSE_STR_LEN(buf) > 0) { + /* shrink the line length and the record + * by dropping of CR before NL */ + QSE_ASSERT (line_len > 0); + line_len--; QSE_STR_LEN(buf) -= 1; } - } - if (line_len == 0 && c == QSE_T('\n')) - { - if (QSE_STR_LEN(buf) <= 0) + if (line_len == 0) { - /* if the record is empty when a blank - * line is encountered, the line - * terminator should not be added to - * the record */ - continue; + /* we got a blank line */ + if (QSE_STR_LEN(buf) <= 0) + { + /* if the record is empty when a blank + * line is encountered, the line + * terminator should not be added to + * the record */ + continue; + } + + /* when a blank line is encountered, + * it needs to snip off the line + * terminator of the previous line */ + QSE_STR_LEN(buf) -= 1; + done = 1; + break; } - /* when a blank line is encountered, - * it needs to snip off the line - * terminator of the previous line */ - QSE_STR_LEN(buf) -= 1; - done = 1; - break; + line_len = 0; } + else line_len++; if (qse_str_ccat (buf, c) == (qse_size_t)-1) { @@ -492,9 +501,6 @@ int qse_awk_rtx_readio ( done = 1; break; } -/* TODO: handle different line terminator */ - if (c == QSE_T('\n')) line_len = 0; - else line_len = line_len + 1; } while (p->in.pos < p->in.len); @@ -561,7 +567,6 @@ int qse_awk_rtx_readio ( n = match_long_rs (run, buf, p); if (n != 0) { - //p->in.pos--; /* unread the character in c */ if (n <= -1) ret = -1; break; } @@ -983,7 +988,7 @@ int qse_awk_rtx_closio_read ( { qse_awk_rio_fun_t handler; - handler = run->rio.handler[p->type & MASK_CLEAR]; + handler = run->rio.handler[p->type & IO_MASK_CLEAR]; if (handler != QSE_NULL) { if (handler (run, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1) @@ -1042,7 +1047,7 @@ int qse_awk_rtx_closio_write ( { qse_awk_rio_fun_t handler; - handler = run->rio.handler[p->type & MASK_CLEAR]; + handler = run->rio.handler[p->type & IO_MASK_CLEAR]; if (handler != QSE_NULL) { qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); @@ -1088,7 +1093,7 @@ int qse_awk_rtx_closeio ( { if (opt[0] == QSE_T('r')) { - if (p->type & MASK_RDWR) + if (p->type & IO_MASK_RDWR) { if (p->rwcstate != QSE_AWK_RIO_CLOSE_WRITE) { @@ -1098,12 +1103,12 @@ int qse_awk_rtx_closeio ( rwcmode = QSE_AWK_RIO_CLOSE_READ; } } - else if (!(p->type & MASK_READ)) goto skip; + else if (!(p->type & IO_MASK_READ)) goto skip; } else { QSE_ASSERT (opt[0] == QSE_T('w')); - if (p->type & MASK_RDWR) + if (p->type & IO_MASK_RDWR) { if (p->rwcstate != QSE_AWK_RIO_CLOSE_READ) { @@ -1113,11 +1118,11 @@ int qse_awk_rtx_closeio ( rwcmode = QSE_AWK_RIO_CLOSE_WRITE; } } - else if (!(p->type & MASK_WRITE)) goto skip; + else if (!(p->type & IO_MASK_WRITE)) goto skip; } } - handler = rtx->rio.handler[p->type & MASK_CLEAR]; + handler = rtx->rio.handler[p->type & IO_MASK_CLEAR]; if (handler != QSE_NULL) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR, QSE_NULL); @@ -1131,7 +1136,7 @@ int qse_awk_rtx_closeio ( } } - if (p->type & MASK_RDWR) + if (p->type & IO_MASK_RDWR) { p->rwcmode = rwcmode; if (p->rwcstate == 0 && rwcmode != 0) @@ -1172,7 +1177,7 @@ void qse_awk_rtx_cleario (qse_awk_rtx_t* run) while (run->rio.chain != QSE_NULL) { handler = run->rio.handler[ - run->rio.chain->type & MASK_CLEAR]; + run->rio.chain->type & IO_MASK_CLEAR]; next = run->rio.chain->next; if (handler != QSE_NULL) diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index a763646f..63555e09 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1,5 +1,5 @@ /* - * $Id: std.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: std.c 447 2011-05-01 13:28:51Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -37,7 +37,7 @@ #endif #ifndef QSE_HAVE_CONFIG_H -# if defined(__OS2__) || defined(_WIN32) +# if defined(__OS2__) || defined(_WIN32) || defined(__DOS__) # define HAVE_POW # define HAVE_SIN # define HAVE_COS diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index c489a6ec..7988ecc6 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: tree.c 447 2011-05-01 13:28:51Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -103,29 +103,34 @@ static const qse_char_t* print_outop_str[] = QSE_T("") }; -#define PUT_SRCSTR(awk,str) \ - do { if (qse_awk_putsrcstr (awk, str) == -1) return -1; } while (0) +#define PUT_SRCSTR(awk,str) QSE_BLOCK (\ + if (qse_awk_putsrcstr (awk, str) == -1) return -1; \ +) -#define PUT_NL(awk) \ - do { \ - if (awk->option & QSE_AWK_CRLF) PUT_SRCSTR (awk, QSE_T("\r")); \ - PUT_SRCSTR (awk, QSE_T("\n")); \ - } while (0) +#define PUT_NL(awk) QSE_BLOCK (\ + if (awk->option & QSE_AWK_CRLF) PUT_SRCSTR (awk, QSE_T("\r")); \ + PUT_SRCSTR (awk, QSE_T("\n")); \ +) -#define PUT_SRCSTRX(awk,str,len) \ - do { if (qse_awk_putsrcstrx (awk, str, len) == -1) return -1; } while (0) +#define PUT_SRCSTRX(awk,str,len) QSE_BLOCK (\ + if (qse_awk_putsrcstrx (awk, str, len) == -1) return -1; \ +) -#define PRINT_TABS(awk,depth) \ - do { if (print_tabs(awk,depth) == -1) return -1; } while (0) +#define PRINT_TABS(awk,depth) QSE_BLOCK (\ + if (print_tabs(awk,depth) == -1) return -1; \ +) -#define PRINT_EXPR(awk,nde) \ - do { if (print_expr(awk,nde) == -1) return -1; } while (0) +#define PRINT_EXPR(awk,nde) QSE_BLOCK (\ + if (print_expr(awk,nde) == -1) return -1; \ +) -#define PRINT_EXPR_LIST(awk,nde) \ - do { if (print_expr_list(awk,nde) == -1) return -1; } while (0) +#define PRINT_EXPR_LIST(awk,nde) QSE_BLOCK(\ + if (print_expr_list(awk,nde) == -1) return -1; \ +) -#define PRINT_STMTS(awk,nde,depth) \ - do { if (print_stmts(awk,nde,depth) == -1) return -1; } while (0) +#define PRINT_STMTS(awk,nde,depth) QSE_BLOCK(\ + if (print_stmts(awk,nde,depth) == -1) return -1; \ +) static int print_tabs (qse_awk_t* awk, int depth); static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde); diff --git a/qse/regress/awk/lang-044.awk b/qse/regress/awk/lang-044.awk new file mode 100644 index 00000000..aff69b9e --- /dev/null +++ b/qse/regress/awk/lang-044.awk @@ -0,0 +1,2 @@ +BEGIN { RS=""; } +{ print "[" $0 "]"; } diff --git a/qse/regress/awk/lang-044.dat b/qse/regress/awk/lang-044.dat new file mode 100644 index 00000000..f421afdd --- /dev/null +++ b/qse/regress/awk/lang-044.dat @@ -0,0 +1,11 @@ +abc +this is the second line + +def +vwxyz +this is the second second line + + + + ttttt +killer diff --git a/qse/regress/awk/regress.sh b/qse/regress/awk/regress.sh index b0eea117..f6c98ad2 100755 --- a/qse/regress/awk/regress.sh +++ b/qse/regress/awk/regress.sh @@ -166,6 +166,7 @@ PROGS=" lang-041.awk!!!--newline=on -o- lang-042.awk!!!--newline=on -o- lang-043.awk!lang-043.dat!!--newline=on -o- + lang-044.awk!lang-044.dat!!--newline=on -o- columnate.awk!./passwd.dat!!--newline=on -F: levenshtein-utests.awk!!!--newline=on --include=on