From 8b863f8852067b0638e09dc7c82355b96381dc12 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 15 Nov 2014 18:35:45 +0200 Subject: Remove MBS_SUPPORT ifdefs. --- builtin.c | 84 ++++++++++++--------------------------------------------------- 1 file changed, 15 insertions(+), 69 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 3eb09b48..75e4f580 100644 --- a/builtin.c +++ b/builtin.c @@ -247,7 +247,6 @@ do_fflush(int nargs) return make_number((AWKNUM) status); } -#if MBS_SUPPORT /* strncasecmpmbs --- like strncasecmp (multibyte string version) */ int @@ -327,14 +326,6 @@ index_multibyte_buffer(char* src, char* dest, int len) dest[idx] = mbclen; } } -#else -/* a dummy function */ -static void -index_multibyte_buffer(char* src ATTRIBUTE_UNUSED, char* dest ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) -{ - cant_happen(); -} -#endif /* do_index --- find index of a string */ @@ -345,7 +336,6 @@ do_index(int nargs) const char *p1, *p2; size_t l1, l2; long ret; -#if MBS_SUPPORT bool do_single_byte = false; mbstate_t mbs1, mbs2; @@ -353,7 +343,6 @@ do_index(int nargs) memset(& mbs1, 0, sizeof(mbstate_t)); memset(& mbs2, 0, sizeof(mbstate_t)); } -#endif POP_TWO_SCALARS(s1, s2); @@ -383,7 +372,6 @@ do_index(int nargs) goto out; } -#if MBS_SUPPORT if (gawk_mb_cur_max > 1) { s1 = force_wstring(s1); s2 = force_wstring(s2); @@ -394,14 +382,12 @@ do_index(int nargs) do_single_byte = ((s1->wstlen == 0 && s1->stlen > 0) || (s2->wstlen == 0 && s2->stlen > 0)); } -#endif /* IGNORECASE will already be false if posix */ if (IGNORECASE) { while (l1 > 0) { if (l2 > l1) break; -#if MBS_SUPPORT if (! do_single_byte && gawk_mb_cur_max > 1) { const wchar_t *pos; @@ -412,21 +398,18 @@ do_index(int nargs) ret = pos - s1->wstptr + 1; /* 1-based */ goto out; } else { -#endif - /* - * Could use tolower(*p1) == tolower(*p2) here. - * See discussion in eval.c as to why not. - */ - if (casetable[(unsigned char)*p1] == casetable[(unsigned char)*p2] - && (l2 == 1 || strncasecmp(p1, p2, l2) == 0)) { - ret = 1 + s1->stlen - l1; - break; - } - l1--; - p1++; -#if MBS_SUPPORT + /* + * Could use tolower(*p1) == tolower(*p2) here. + * See discussion in eval.c as to why not. + */ + if (casetable[(unsigned char)*p1] == casetable[(unsigned char)*p2] + && (l2 == 1 || strncasecmp(p1, p2, l2) == 0)) { + ret = 1 + s1->stlen - l1; + break; + } + l1--; + p1++; } -#endif } } else { while (l1 > 0) { @@ -437,7 +420,6 @@ do_index(int nargs) ret = 1 + s1->stlen - l1; break; } -#if MBS_SUPPORT if (! do_single_byte && gawk_mb_cur_max > 1) { const wchar_t *pos; @@ -451,10 +433,6 @@ do_index(int nargs) l1--; p1++; } -#else - l1--; - p1++; -#endif } } out: @@ -544,7 +522,6 @@ do_length(int nargs) lintwarn(_("length: received non-string argument")); tmp = force_string(tmp); -#if MBS_SUPPORT if (gawk_mb_cur_max > 1) { tmp = force_wstring(tmp); len = tmp->wstlen; @@ -555,7 +532,6 @@ do_length(int nargs) if (len == 0 && tmp->stlen > 0) len = tmp->stlen; } else -#endif len = tmp->stlen; DEREF(tmp); @@ -1058,7 +1034,6 @@ check_pos: (void) force_number(arg); if ((arg->flags & NUMBER) != 0) { uval = get_number_uj(arg); -#if MBS_SUPPORT if (gawk_mb_cur_max > 1) { char buf[100]; wchar_t wc; @@ -1099,7 +1074,7 @@ out0: ; /* else, fall through */ -#endif + cpbuf[0] = uval; prec = 1; cp = cpbuf; @@ -1113,7 +1088,6 @@ out0: */ cp = arg->stptr; prec = 1; -#if MBS_SUPPORT /* * First character can be multiple bytes if * it's a multibyte character. Grr. @@ -1131,7 +1105,6 @@ out0: fw += count - 1; } } -#endif goto pr_tail; case 's': need_format = false; @@ -1805,13 +1778,11 @@ do_substr(int nargs) if (nargs == 2) { /* third arg. missing */ /* use remainder of string */ length = t1->stlen - indx; /* default to bytes */ -#if MBS_SUPPORT if (gawk_mb_cur_max > 1) { t1 = force_wstring(t1); if (t1->wstlen > 0) /* use length of wide char string if we have one */ length = t1->wstlen - indx; } -#endif d_length = length; /* set here in case used in diagnostics, below */ } @@ -1824,12 +1795,10 @@ do_substr(int nargs) } /* get total len of input string, for following checks */ -#if MBS_SUPPORT if (gawk_mb_cur_max > 1) { t1 = force_wstring(t1); src_len = t1->wstlen; } else -#endif src_len = t1->stlen; if (indx >= src_len) { @@ -1847,7 +1816,6 @@ do_substr(int nargs) length = src_len - indx; } -#if MBS_SUPPORT /* force_wstring() already called */ if (gawk_mb_cur_max == 1 || t1->wstlen == t1->stlen) /* single byte case */ @@ -1877,9 +1845,6 @@ do_substr(int nargs) *cp = '\0'; r = make_str_node(substr, cp - substr, ALREADY_MALLOCED); } -#else - r = make_string(t1->stptr + indx, length); -#endif DEREF(t1); return r; @@ -2211,7 +2176,6 @@ do_print_rec(int nargs, int redirtype) rp->output.gawk_fflush(rp->output.fp, rp->output.opaque); } -#if MBS_SUPPORT /* is_wupper --- function version of iswupper for passing function pointers */ @@ -2276,7 +2240,6 @@ wide_tolower(wchar_t *wstr, size_t wlen) { wide_change_case(wstr, wlen, is_wupper, to_wlower); } -#endif /* do_tolower --- lower case a string */ @@ -2299,14 +2262,11 @@ do_tolower(int nargs) cp < cp2; cp++) if (isupper(*cp)) *cp = tolower(*cp); - } -#if MBS_SUPPORT - else { + } else { force_wstring(t2); wide_tolower(t2->wstptr, t2->wstlen); wstr2str(t2); } -#endif DEREF(t1); return t2; @@ -2333,14 +2293,11 @@ do_toupper(int nargs) cp < cp2; cp++) if (islower(*cp)) *cp = toupper(*cp); - } -#if MBS_SUPPORT - else { + } else { force_wstring(t2); wide_toupper(t2->wstptr, t2->wstlen); wstr2str(t2); } -#endif DEREF(t1); return t2; @@ -2490,13 +2447,12 @@ do_match(int nargs) size_t *wc_indices = NULL; rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr); /* byte length */ -#if MBS_SUPPORT if (rlength > 0 && gawk_mb_cur_max > 1) { t1 = str2wstr(t1, & wc_indices); rlength = wc_indices[rstart + rlength - 1] - wc_indices[rstart] + 1; rstart = wc_indices[rstart]; } -#endif + rstart++; /* now it's 1-based indexing */ /* Build the array only if the caller wants the optional subpatterns */ @@ -2518,12 +2474,10 @@ do_match(int nargs) start = t1->stptr + s; subpat_start = s; subpat_len = len = SUBPATEND(rp, t1->stptr, ii) - s; -#if MBS_SUPPORT if (len > 0 && gawk_mb_cur_max > 1) { subpat_start = wc_indices[s]; subpat_len = wc_indices[s + len - 1] - subpat_start + 1; } -#endif it = make_string(start, len); it->flags |= MAYBE_NUM; /* user input */ @@ -3578,7 +3532,6 @@ do_bindtextdomain(int nargs) static size_t mbc_byte_count(const char *ptr, size_t numchars) { -#if MBS_SUPPORT mbstate_t cur_state; size_t sum = 0; int mb_len; @@ -3599,9 +3552,6 @@ mbc_byte_count(const char *ptr, size_t numchars) } return sum; -#else - return numchars; -#endif } /* mbc_char_count --- return number of m.b. chars in string, up to numbytes bytes */ @@ -3609,7 +3559,6 @@ mbc_byte_count(const char *ptr, size_t numchars) static size_t mbc_char_count(const char *ptr, size_t numbytes) { -#if MBS_SUPPORT mbstate_t cur_state; size_t sum = 0; int mb_len; @@ -3632,7 +3581,4 @@ mbc_char_count(const char *ptr, size_t numbytes) } return sum; -#else - return numbytes; -#endif } -- cgit v1.2.3 From 7efd4d794abbbd1b6abc2110cd43fd7896e0cb47 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 25 Nov 2014 21:43:58 +0200 Subject: Improve warnings in gensub. --- builtin.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 75e4f580..3aeee744 100644 --- a/builtin.c +++ b/builtin.c @@ -2696,6 +2696,8 @@ do_sub(int nargs, unsigned int flags) if ((t1->flags & NUMCUR) != 0) goto set_how_many; + warning(_("gensub: third argument of `%.*s' treated as 1"), + (int) t1->stlen, t1->stptr); how_many = 1; } } else { @@ -2708,8 +2710,8 @@ set_how_many: how_many = d; else how_many = LONG_MAX; - if (d == 0) - warning(_("gensub: third argument of 0 treated as 1")); + if (d <= 0) + warning(_("gensub: third argument of %g treated as 1"), d); } DEREF(t1); -- cgit v1.2.3 From 5dd46ec03bb3dc945d2f084726aaba79a83e6340 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 26 Nov 2014 08:29:52 +0200 Subject: Fixes for new gensub warnings. --- builtin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 3aeee744..53210c4d 100644 --- a/builtin.c +++ b/builtin.c @@ -2696,7 +2696,7 @@ do_sub(int nargs, unsigned int flags) if ((t1->flags & NUMCUR) != 0) goto set_how_many; - warning(_("gensub: third argument of `%.*s' treated as 1"), + warning(_("gensub: third argument `%.*s' treated as 1"), (int) t1->stlen, t1->stptr); how_many = 1; } @@ -2711,7 +2711,7 @@ set_how_many: else how_many = LONG_MAX; if (d <= 0) - warning(_("gensub: third argument of %g treated as 1"), d); + warning(_("gensub: third argument %g treated as 1"), d); } DEREF(t1); -- cgit v1.2.3 From dcaab6dd8a28be8885ccc508c49b962a61ab09fe Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 20 Dec 2014 19:56:44 +0200 Subject: Start at non-fatal output via PROCINFO. --- builtin.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 21c6ed5c..b3f3f333 100644 --- a/builtin.c +++ b/builtin.c @@ -130,9 +130,12 @@ wrerror: gawk_exit(EXIT_FATAL); /* otherwise die verbosely */ - fatal(_("%s to \"%s\" failed (%s)"), from, - rp ? rp->value : _("standard output"), - errno ? strerror(errno) : _("reason unknown")); + if ((rp->flag & RED_NON_FATAL) != 0) { + update_ERRNO_int(errno); + } else + fatal(_("%s to \"%s\" failed (%s)"), from, + rp ? rp->value : _("standard output"), + errno ? strerror(errno) : _("reason unknown")); } /* do_exp --- exponential function */ @@ -1633,7 +1636,7 @@ do_printf(int nargs, int redirtype) FILE *fp = NULL; NODE *tmp; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; if (nargs == 0) { @@ -1660,6 +1663,10 @@ do_printf(int nargs, int redirtype) rp = redirect(redir_exp, redirtype, & errflg); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2072,7 +2079,7 @@ void do_print(int nargs, int redirtype) { struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; FILE *fp = NULL; int i; NODE *redir_exp = NULL; @@ -2087,6 +2094,10 @@ do_print(int nargs, int redirtype) rp = redirect(redir_exp, redirtype, & errflg); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2142,7 +2153,7 @@ do_print_rec(int nargs, int redirtype) FILE *fp = NULL; NODE *f0; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; assert(nargs == 0); @@ -2162,6 +2173,11 @@ do_print_rec(int nargs, int redirtype) if (! field0_valid) (void) get_field(0L, NULL); /* rebuild record */ + if (errflg) { + update_ERRNO_int(errflg); + return; + } + f0 = fields_arr[0]; if (do_lint && (f0->flags & NULL_FIELD) != 0) -- cgit v1.2.3 From 15a1d8d213380bd99b5dfe7f4cafcd6dedb8f0dc Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 27 Dec 2014 21:20:47 +0200 Subject: Make nonfatal work with stdout & stderr. Update doc more. --- builtin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index b3f3f333..e80d46d4 100644 --- a/builtin.c +++ b/builtin.c @@ -129,8 +129,10 @@ wrerror: if (fp == stdout && errno == EPIPE) gawk_exit(EXIT_FATAL); + /* otherwise die verbosely */ - if ((rp->flag & RED_NON_FATAL) != 0) { + if ( (rp != NULL && (rp->flag & RED_NON_FATAL) != 0) + || is_non_fatal_std(fp)) { update_ERRNO_int(errno); } else fatal(_("%s to \"%s\" failed (%s)"), from, -- cgit v1.2.3 From f70399532bd105c5f42ca040846aa537a8fa27bc Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 7 Jan 2015 22:12:50 +0200 Subject: Fix count$ in printf for dynamic width/precision. --- builtin.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 53210c4d..9b85de2b 100644 --- a/builtin.c +++ b/builtin.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc. + * Copyright (C) 1986, 1988, 1989, 1991-2015 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -904,7 +904,10 @@ check_pos: case '*': if (cur == NULL) break; - if (! do_traditional && isdigit((unsigned char) *s1)) { + if (! do_traditional && used_dollar && ! isdigit((unsigned char) *s1)) { + fatal(_("fatal: must use `count$' on all formats or none")); + break; /* silence warnings */ + } else if (! do_traditional && isdigit((unsigned char) *s1)) { int val = 0; for (; n0 > 0 && *s1 && isdigit((unsigned char) *s1); s1++, n0--) { -- cgit v1.2.3 From 0e829ea9a5062cac730f5a8368ab2062c1ef67fd Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 14 Jan 2015 19:51:49 +0200 Subject: Remove deferred variables. --- builtin.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 9b85de2b..1383572a 100644 --- a/builtin.c +++ b/builtin.c @@ -510,6 +510,9 @@ do_length(int nargs) * Support for deferred loading of array elements requires that * we use the array length interface even though it isn't * necessary for the built-in array types. + * + * 1/2015: The deferred arrays are gone, but this is probably + * still a good idea. */ size = assoc_length(tmp); -- cgit v1.2.3 From 2f9c84e82632cbce017a6d342acb3dede5e59e12 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 8 Feb 2015 19:45:44 +0200 Subject: Reset non-fatal-io to 31 December, add fixes from Andrew Schorr. --- builtin.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index e80d46d4..aa8caf09 100644 --- a/builtin.c +++ b/builtin.c @@ -131,10 +131,9 @@ wrerror: /* otherwise die verbosely */ - if ( (rp != NULL && (rp->flag & RED_NON_FATAL) != 0) - || is_non_fatal_std(fp)) { + if ((rp != NULL) ? is_non_fatal_redirect(rp->value) : is_non_fatal_std(fp)) update_ERRNO_int(errno); - } else + else fatal(_("%s to \"%s\" failed (%s)"), from, rp ? rp->value : _("standard output"), errno ? strerror(errno) : _("reason unknown")); @@ -1649,7 +1648,7 @@ do_printf(int nargs, int redirtype) redir_exp = TOP(); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); DEREF(redir_exp); decr_sp(); } @@ -1662,7 +1661,7 @@ do_printf(int nargs, int redirtype) redir_exp = PEEK(nargs); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; else if (errflg) { @@ -2093,7 +2092,7 @@ do_print(int nargs, int redirtype) redir_exp = PEEK(nargs); if (redir_exp->type != Node_val) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp)); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; else if (errflg) { @@ -2161,7 +2160,7 @@ do_print_rec(int nargs, int redirtype) assert(nargs == 0); if (redirtype != 0) { redir_exp = TOP(); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; DEREF(redir_exp); @@ -2169,17 +2168,17 @@ do_print_rec(int nargs, int redirtype) } else fp = output_fp; + if (errflg) { + update_ERRNO_int(errflg); + return; + } + if (fp == NULL) return; if (! field0_valid) (void) get_field(0L, NULL); /* rebuild record */ - if (errflg) { - update_ERRNO_int(errflg); - return; - } - f0 = fields_arr[0]; if (do_lint && (f0->flags & NULL_FIELD) != 0) -- cgit v1.2.3 From 59514868fde1190f719e78d4c4b91bd14a321541 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 20 Mar 2015 10:31:49 +0200 Subject: Start on testing/fixing indirect calls of builtins. --- builtin.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 1383572a..4dd08eb1 100644 --- a/builtin.c +++ b/builtin.c @@ -2994,6 +2994,29 @@ done: return make_number((AWKNUM) matches); } +/* call_sub_func --- call do_sub indirectly */ + +NODE * +call_sub_func(const char *name, int nargs) +{ + unsigned int flags = 0; + NODE *tmp; + + if (name[0] == 'g') { + if (name[1] == 'e') + flags = GENSUB; + else + flags = GSUB; + } + + tmp = PEEK(1); + if (tmp->type == Node_val) { + flags |= LITERAL; + } + + return do_sub(nargs, flags); +} + /* make_integer - Convert an integer to a number node. */ -- cgit v1.2.3 From 080694ae82635e76992158591b39a06af7363da0 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 24 Mar 2015 22:15:31 +0200 Subject: Further progress on indirect calls of builtins. --- builtin.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 4dd08eb1..7926a320 100644 --- a/builtin.c +++ b/builtin.c @@ -3000,7 +3000,7 @@ NODE * call_sub_func(const char *name, int nargs) { unsigned int flags = 0; - NODE *tmp; + NODE *regex, *replace; if (name[0] == 'g') { if (name[1] == 'e') @@ -3009,10 +3009,15 @@ call_sub_func(const char *name, int nargs) flags = GSUB; } - tmp = PEEK(1); - if (tmp->type == Node_val) { - flags |= LITERAL; - } + if ((flags == 0 || flags == GSUB) && nargs != 2) + fatal(_("%s: can be called indirectly only with two arguments"), name); + + replace = POP(); + + regex = POP(); /* the regex */ + regex = make_regnode(Node_regex, regex); + PUSH(regex); + PUSH(replace); return do_sub(nargs, flags); } -- cgit v1.2.3 From 2ee1a928483f4fe4f594aebc5c1f8da1253c28b9 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 31 Mar 2015 06:23:04 +0300 Subject: Further improvements. sub/gsub working. --- builtin.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 9 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 7926a320..c222ce78 100644 --- a/builtin.c +++ b/builtin.c @@ -3000,7 +3000,10 @@ NODE * call_sub_func(const char *name, int nargs) { unsigned int flags = 0; - NODE *regex, *replace; + NODE *regex, *replace, *glob_flag; + NODE **lhs, *rhs; + NODE *zero = make_number(0.0); + NODE *result; if (name[0] == 'g') { if (name[1] == 'e') @@ -3009,17 +3012,62 @@ call_sub_func(const char *name, int nargs) flags = GSUB; } - if ((flags == 0 || flags == GSUB) && nargs != 2) - fatal(_("%s: can be called indirectly only with two arguments"), name); + if (flags == 0 || flags == GSUB) { + /* sub or gsub */ + if (nargs != 2) + fatal(_("%s: can be called indirectly only with two arguments"), name); - replace = POP(); + replace = POP_STRING(); + regex = POP(); /* the regex */ + /* + * push regex + * push replace + * push $0 + */ + regex = make_regnode(Node_regex, regex); + PUSH(regex); + PUSH(replace); + lhs = r_get_field(zero, (Func_ptr *) 0, true); + nargs++; + PUSH_ADDRESS(lhs); + } else { + /* gensub */ + if (nargs == 4) + rhs = POP(); + else + rhs = NULL; + glob_flag = POP_STRING(); + replace = POP_STRING(); + regex = POP(); /* the regex */ + /* + * push regex + * push replace + * push glob_flag + * if (nargs = 3) { + * push $0 + * nargs++ + * } + */ + regex = make_regnode(Node_regex, regex); + PUSH(regex); + PUSH(replace); + PUSH(glob_flag); + if (rhs == NULL) { + lhs = r_get_field(zero, (Func_ptr *) 0, true); + rhs = *lhs; + UPREF(rhs); + PUSH(rhs); + nargs++; + } + PUSH(rhs); + } - regex = POP(); /* the regex */ - regex = make_regnode(Node_regex, regex); - PUSH(regex); - PUSH(replace); - return do_sub(nargs, flags); + unref(zero); + result = do_sub(nargs, flags); + if (flags != GENSUB) + reset_record(); + return result; } -- cgit v1.2.3 From a47af3141cf4a6b43e20db872e2b45ff9abb071f Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 31 Mar 2015 22:07:53 +0300 Subject: Get indirect calls working! --- builtin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index c222ce78..dde3121c 100644 --- a/builtin.c +++ b/builtin.c @@ -2994,10 +2994,10 @@ done: return make_number((AWKNUM) matches); } -/* call_sub_func --- call do_sub indirectly */ +/* call_sub --- call do_sub indirectly */ NODE * -call_sub_func(const char *name, int nargs) +call_sub(const char *name, int nargs) { unsigned int flags = 0; NODE *regex, *replace, *glob_flag; @@ -3070,6 +3070,70 @@ call_sub_func(const char *name, int nargs) return result; } +/* call_match --- call do_match indirectly */ + +NODE * +call_match(int nargs) +{ + NODE *regex, *text, *array; + NODE *result; + + regex = text = array = NULL; + if (nargs == 3) + array = POP(); + regex = POP(); + + /* Don't need to pop the string just to push it back ... */ + + regex = make_regnode(Node_regex, regex); + PUSH(regex); + + if (array) + PUSH(array); + + result = do_match(nargs); + return result; +} + +/* call_split_func --- call do_split or do_pat_split indirectly */ + +NODE * +call_split_func(const char *name, int nargs) +{ + NODE *regex, *seps; + NODE *result; + + regex = seps = NULL; + if (nargs < 2) + fatal(_("indirect call to %s requires at least two arguments"), + name); + + if (nargs == 4) + seps = POP(); + + if (nargs >= 3) { + regex = POP_STRING(); + regex = make_regnode(Node_regex, regex); + } else { + if (name[0] == 's') { + regex = make_regnode(Node_regex, FS_node->var_value); + regex->re_flags |= FS_DFLT; + } else + regex = make_regnode(Node_regex, FPAT_node->var_value); + nargs++; + } + + /* Don't need to pop the string or the data array */ + + PUSH(regex); + + if (seps) + PUSH(seps); + + result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs); + + return result; +} /* make_integer - Convert an integer to a number node. */ -- cgit v1.2.3 From ddc290584b39bab2c1edcec935a31ea12d343246 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 3 Apr 2015 09:08:54 +0300 Subject: Rename "div()" to "intdiv()". --- builtin.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 99293b9a..b70176dc 100644 --- a/builtin.c +++ b/builtin.c @@ -3752,7 +3752,7 @@ do_bindtextdomain(int nargs) return make_string(the_result, strlen(the_result)); } -/* do_div --- do integer division, return quotient and remainder in dest array */ +/* do_intdiv --- do integer division, return quotient and remainder in dest array */ /* * We define the semantics as: @@ -3763,7 +3763,7 @@ do_bindtextdomain(int nargs) */ NODE * -do_div(int nargs) +do_intdiv(int nargs) { NODE *numerator, *denominator, *result; double num, denom, quotient, remainder; @@ -3771,7 +3771,7 @@ do_div(int nargs) result = POP_PARAM(); if (result->type != Node_var_array) - fatal(_("div: third argument is not an array")); + fatal(_("intdiv: third argument is not an array")); assoc_clear(result); denominator = POP_SCALAR(); @@ -3779,9 +3779,9 @@ do_div(int nargs) if (do_lint) { if ((numerator->flags & (NUMCUR|NUMBER)) == 0) - lintwarn(_("div: received non-numeric first argument")); + lintwarn(_("intdiv: received non-numeric first argument")); if ((denominator->flags & (NUMCUR|NUMBER)) == 0) - lintwarn(_("div: received non-numeric second argument")); + lintwarn(_("intdiv: received non-numeric second argument")); } (void) force_number(numerator); @@ -3790,7 +3790,7 @@ do_div(int nargs) denom = double_to_int(get_number_d(denominator)); if (denom == 0.0) - fatal(_("div: division by zero attempted")); + fatal(_("intdiv: division by zero attempted")); quotient = double_to_int(num / denom); /* -- cgit v1.2.3