diff --git a/CHANGES b/CHANGES index 382c2e6..4554642 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,15 @@ --- $MawkId: CHANGES,v 1.171 2012/12/10 00:35:00 tom Exp $ +-- $MawkId: CHANGES,v 1.173 2013/02/19 10:57:16 tom Exp $ Changes by Thomas E Dickey +20130219 + + modify missing-operand check in rexp.c to allow the case of empty + "()", matching behavior of gawk and BWK (report by Arkadiusz + Miskiewicz). + + revert in-progress change to gsub retain ifdef'd for additional + development since it did not handle array as the second parameter + (report by Arkadiusz Miskiewicz). + 20121209 + build-fix for cygwin in matherr.c, which declares a different type for _LIB_VERSION diff --git a/MANIFEST b/MANIFEST index 37daa59..40d2a98 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,4 @@ -MANIFEST for mawk, version t20121209 +MANIFEST for mawk, version t20130219 -------------------------------------------------------------------------------- MANIFEST this file ACKNOWLEDGMENT acknowledgements diff --git a/bi_funct.c b/bi_funct.c index e2ac02d..9919870 100644 --- a/bi_funct.c +++ b/bi_funct.c @@ -1,6 +1,6 @@ /******************************************** bi_funct.c -copyright 2008-2010,2012, Thomas E. Dickey +copyright 2008-2012,2013, Thomas E. Dickey copyright 1991-1995,1996, Michael D. Brennan This is a source file for mawk, an implementation of @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: bi_funct.c,v 1.64 2012/12/07 10:14:17 tom Exp $ + * $MawkId: bi_funct.c,v 1.67 2013/02/19 10:57:28 tom Exp $ * @Log: bi_funct.c,v @ * Revision 1.9 1996/01/14 17:16:11 mike * flush_all_output() before system() @@ -78,6 +78,8 @@ the GNU General Public License, version 2, 1991. #include #include +/* #define EXP_UNROLLED_GSUB */ + #if OPT_TRACE > 0 #define return_CELL(func, cell) TRACE(("..." func " ->")); \ TRACE_CELL(cell); \ @@ -1190,6 +1192,7 @@ typedef struct { #define NextTarget NextGSUB.target #define NextTargetLen NextGSUB.target_len +#ifdef EXP_UNROLLED_GSUB /* #define DEBUG_GSUB 1 */ static size_t gsub_max; @@ -1536,3 +1539,142 @@ bi_gsub(CELL * sp) return_CELL("bi_gsub", sp); } + +#else /* GSUB uses stack... */ +static unsigned repl_cnt; /* number of global replacements */ + +/* recursive global subsitution + dealing with empty matches makes this mildly painful + + repl is always of type REPL or REPLV, destroyed by caller + flag is set if, match of empty string at front is OK +*/ + +static STRING * +gsub(PTR re, CELL * repl, char *target, size_t target_len, int flag) +{ + char *front = 0, *middle; + STRING *back; + size_t front_len, middle_len; + STRING *ret_val; + CELL xrepl; /* a copy of repl so we can change repl */ + + if (!(middle = REmatch(target, target_len, cast_to_re(re), &middle_len))) + return new_STRING(target); /* no match */ + + cellcpy(&xrepl, repl); + + if (!flag && middle_len == 0 && middle == target) { + /* match at front that's not allowed */ + + if (*target == 0) { /* target is empty string */ + repl_destroy(&xrepl); + null_str.ref_cnt++; + return &null_str; + } else if (1 && isAnchored(re)) { + repl_destroy(&xrepl); + return new_STRING1(target, target_len); + } else { + char xbuff[2]; + + front_len = 0; + /* make new repl with target[0] */ + repl_destroy(repl); + --target_len; + xbuff[0] = *target++; + xbuff[1] = 0; + repl->type = C_REPL; + repl->ptr = (PTR) new_STRING(xbuff); + back = gsub(re, &xrepl, target, target_len, 1); + } + } else { /* a match that counts */ + repl_cnt++; + + front = target; + front_len = (unsigned) (middle - target); + + if (front_len == target_len) { /* matched back of target */ + back = &null_str; + null_str.ref_cnt++; + } else { + back = gsub(re, + &xrepl, + middle + middle_len, + target_len - (front_len + middle_len), + 0); + } + + /* patch the &'s if needed */ + if (repl->type == C_REPLV) { + STRING *sval = new_STRING0(middle_len); + + memcpy(sval->str, middle, middle_len); + replv_to_repl(repl, sval); + free_STRING(sval); + } + } + + /* put the three pieces together */ + ret_val = new_STRING0(front_len + string(repl)->len + back->len); + { + char *p = ret_val->str; + + if (front_len) { + memcpy(p, front, front_len); + p += front_len; + } + + if (string(repl)->len) { + memcpy(p, string(repl)->str, string(repl)->len); + p += string(repl)->len; + } + if (back->len) + memcpy(p, back->str, back->len); + } + + /* cleanup, repl is freed by the caller */ + repl_destroy(&xrepl); + free_STRING(back); + + return ret_val; +} + +/* set up for call to gsub() */ +CELL * +bi_gsub(CELL * sp) +{ + CELL *cp; /* pts at the replacement target */ + CELL sc; /* copy of replacement target */ + CELL tc; /* build the result here */ + + TRACE_FUNC("bi_gsub", sp); + + sp -= 2; + if (sp->type != C_RE) + cast_to_RE(sp); + if ((sp + 1)->type != C_REPL && (sp + 1)->type != C_REPLV) + cast_to_REPL(sp + 1); + + cellcpy(&sc, cp = (CELL *) (sp + 2)->ptr); + if (sc.type < C_STRING) + cast1_to_s(&sc); + + repl_cnt = 0; + tc.ptr = (PTR) gsub(sp->ptr, sp + 1, string(&sc)->str, string(&sc)->len, 1); + + if (repl_cnt) { + tc.type = C_STRING; + slow_cell_assign(cp, &tc); + } + + /* cleanup */ + free_STRING(string(&sc)); + free_STRING(string(&tc)); + repl_destroy(sp + 1); + + sp->type = C_DOUBLE; + sp->dval = (double) repl_cnt; + + return_CELL("bi_gsub", sp); +} +#endif /* EXP_UNROLLED_GSUB */ diff --git a/package/debian/changelog b/package/debian/changelog index 926bebd..c2cf308 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,3 +1,9 @@ +mawk-cur (1.3.4-20130219) unstable; urgency=low + + * miscelleneous bug-fixes + + -- Thomas E. Dickey Tue, 19 Feb 2013 06:45:33 -0500 + mawk-cur (1.3.4-20121209) unstable; urgency=low * fix regression with LC_NUMERIC feature diff --git a/package/mawk.spec b/package/mawk.spec index c2796a1..7d8edd3 100644 --- a/package/mawk.spec +++ b/package/mawk.spec @@ -1,8 +1,8 @@ Summary: mawk - pattern scanning and text processing language %define AppProgram mawk %define AppVersion 1.3.4 -%define AppRelease 20121209 -# $MawkId: mawk.spec,v 1.22 2012/12/09 14:23:10 tom Exp $ +%define AppRelease 20130219 +# $MawkId: mawk.spec,v 1.23 2013/02/19 11:45:36 tom Exp $ Name: %{AppProgram} Version: %{AppVersion} Release: %{AppRelease} diff --git a/patchlev.h b/patchlev.h index 440e1a5..e06c50a 100644 --- a/patchlev.h +++ b/patchlev.h @@ -11,9 +11,9 @@ the GNU General Public License, version 2, 1991. */ /* - * $MawkId: patchlev.h,v 1.46 2012/12/09 14:23:10 tom Exp $ + * $MawkId: patchlev.h,v 1.47 2013/02/19 11:45:36 tom Exp $ */ #define PATCH_BASE 1 #define PATCH_LEVEL 3 #define PATCH_STRING ".4" -#define DATE_STRING "20121209" +#define DATE_STRING "20130219" diff --git a/rexp.c b/rexp.c index a6cf573..c7e8147 100644 --- a/rexp.c +++ b/rexp.c @@ -1,6 +1,6 @@ /******************************************** rexp.c -copyright 2008-2010,2012, Thomas E. Dickey +copyright 2008-2012,2013, Thomas E. Dickey copyright 1991-1993,1996, Michael D. Brennan This is a source file for mawk, an implementation of @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: rexp.c,v 1.17 2012/11/02 00:39:09 tom Exp $ + * $MawkId: rexp.c,v 1.18 2013/02/19 10:51:21 tom Exp $ * @Log: rexp.c,v @ * Revision 1.3 1996/09/02 18:47:36 mike * Make ^* and ^+ syntax errors. @@ -80,6 +80,38 @@ static short table[8][8] = { static jmp_buf err_buf; /* used to trap on error */ +#if OPT_TRACE > 0 +static const char * +token_name(int token) +{ + const char *result; +#define CASE(name) case name: result = #name; break + switch (token) { + CASE(T_NONE); + CASE(T_OR); + CASE(T_CAT); + CASE(T_STAR); + CASE(T_PLUS); + CASE(T_Q); + CASE(T_LP); + CASE(T_RP); + CASE(T_START); + CASE(T_END); + CASE(T_ANY); + CASE(T_CLASS); + CASE(T_SLASH); + CASE(T_CHAR); + CASE(T_STR); + CASE(T_U); + default: + result = "?"; + break; + } +#undef CASE + return result; +} +#endif + void RE_error_trap(int x) { @@ -123,6 +155,7 @@ REcompile(char *re, size_t len) t = RE_lex(m_stack); while (1) { + TRACE(("RE_lex token %s\n", token_name(t))); switch (t) { case T_STR: case T_ANY: @@ -152,8 +185,15 @@ REcompile(char *re, size_t len) if ((op_ptr->prec = table[op_ptr->token][t]) == G) { do { /* op_pop */ - if (op_ptr->token <= T_CAT) /*binary op */ + if (op_ptr->token <= T_CAT) { /*binary op */ + if (m_ptr == m_stack + && op_ptr->token == T_CAT) { + TRACE(("...ignoring empty T_CAT\n")); + op_ptr--; + continue; + } m_ptr--; + } /* if not enough values on machine stack then we have a missing operand */ if (m_ptr < m_stack) diff --git a/version.c b/version.c index 680eecb..f6bf60f 100644 --- a/version.c +++ b/version.c @@ -1,6 +1,6 @@ /******************************************** version.c -copyright 2008-2009,2010. Thomas E. Dickey +copyright 2008-2012,2013. Thomas E. Dickey copyright 1991-1995,1996. Michael D. Brennan This is a source file for mawk, an implementation of @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: version.c,v 1.12 2012/09/01 13:50:17 tom Exp $ + * $MawkId: version.c,v 1.13 2013/02/19 11:46:10 tom Exp $ * * @Log: version.c,v @ * Revision 1.10 1996/07/28 21:47:07 mike @@ -34,7 +34,7 @@ the GNU General Public License, version 2, 1991. #define VERSION_STRING \ "mawk %d.%d%s%s %s\n\ -Copyright 2012, Thomas E. Dickey\n\ +Copyright 2013, Thomas E. Dickey\n\ Copyright 1996, Michael D. Brennan\n\n" /* If use different command line syntax for MSDOS diff --git a/zmalloc.c b/zmalloc.c index 8f0b758..1c19ce6 100644 --- a/zmalloc.c +++ b/zmalloc.c @@ -1,6 +1,6 @@ /******************************************** zmalloc.c -copyright 2008-2010,2012, Thomas E. Dickey +copyright 2008-2012,2013, Thomas E. Dickey copyright 1991-1993,1995, Michael D. Brennan This is a source file for mawk, an implementation of @@ -11,7 +11,7 @@ the GNU General Public License, version 2, 1991. ********************************************/ /* - * $MawkId: zmalloc.c,v 1.27 2012/12/09 14:03:31 tom Exp $ + * $MawkId: zmalloc.c,v 1.29 2013/02/19 11:54:10 tom Exp $ * @Log: zmalloc.c,v @ * Revision 1.6 1995/06/06 00:18:35 mike * change mawk_exit(1) to mawk_exit(2) @@ -231,10 +231,10 @@ out_of_mem(void) static char out[] = "out of memory"; if (mawk_state == EXECUTION) { - rt_error(out); + rt_error("%s", out); } else { /* I don't think this will ever happen */ - compile_error(out); + compile_error("%s", out); mawk_exit(2); } }