"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "builtin.c" between
gawk-5.0.1.tar.xz and gawk-5.1.0.tar.xz

About: GNU awk - pattern scanning and processing language.

builtin.c  (gawk-5.0.1.tar.xz):builtin.c  (gawk-5.1.0.tar.xz)
/* /*
* builtin.c - Builtin functions and various utility procedures. * builtin.c - Builtin functions and various utility procedures.
*/ */
/* /*
* Copyright (C) 1986, 1988, 1989, 1991-2019 the Free Software Foundation, Inc. * Copyright (C) 1986, 1988, 1989, 1991-2020,
* the Free Software Foundation, Inc.
* *
* This file is part of GAWK, the GNU implementation of the * This file is part of GAWK, the GNU implementation of the
* AWK Programming Language. * AWK Programming Language.
* *
* GAWK is free software; you can redistribute it and/or modify * GAWK is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* GAWK is distributed in the hope that it will be useful, * GAWK is distributed in the hope that it will be useful,
skipping to change at line 140 skipping to change at line 141
w32_maybe_set_errno(); w32_maybe_set_errno();
#endif #endif
/* for stdout, die with a real SIGPIPE, like other awks */ /* for stdout, die with a real SIGPIPE, like other awks */
if (fp == stdout && errno == EPIPE) if (fp == stdout && errno == EPIPE)
die_via_sigpipe(); die_via_sigpipe();
/* otherwise die verbosely */ /* otherwise die verbosely */
if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) : is_non_fatal_std(fp)) if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) : is_non_fatal_std(fp))
update_ERRNO_int(errno); update_ERRNO_int(errno);
else else
fatal(_("%s to \"%s\" failed (%s)"), from, fatal(_("%s to \"%s\" failed: %s"), from,
rp != NULL rp != NULL
? rp->value ? rp->value
: fp == stdout : fp == stdout
? _("standard output") ? _("standard output")
: _("standard error"), : _("standard error"),
errno ? strerror(errno) : _("reason unknown")); errno ? strerror(errno) : _("reason unknown"));
} }
/* do_exp --- exponential function */ /* do_exp --- exponential function */
NODE * NODE *
do_exp(int nargs) do_exp(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d, res; double d, res;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("exp: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "exp");
d = force_number(tmp)->numbr; d = force_number(tmp)->numbr;
DEREF(tmp); DEREF(tmp);
errno = 0; errno = 0;
res = exp(d); res = exp(d);
if (errno == ERANGE) if (errno == ERANGE)
warning(_("exp: argument %g is out of range"), d); warning(_("exp: argument %g is out of range"), d);
return make_number((AWKNUM) res); return make_number((AWKNUM) res);
} }
/* stdfile --- return fp for a standard file */ /* stdfile --- return fp for a standard file */
skipping to change at line 374 skipping to change at line 375
if (gawk_mb_cur_max > 1) { if (gawk_mb_cur_max > 1) {
memset(& mbs1, 0, sizeof(mbstate_t)); memset(& mbs1, 0, sizeof(mbstate_t));
memset(& mbs2, 0, sizeof(mbstate_t)); memset(& mbs2, 0, sizeof(mbstate_t));
} }
POP_TWO_SCALARS(s1, s2); POP_TWO_SCALARS(s1, s2);
if (do_lint) { if (do_lint) {
if ((fixtype(s1)->flags & STRING) == 0) if ((fixtype(s1)->flags & STRING) == 0)
lintwarn(_("index: received non-string first argument")); lintwarn(_("%s: received non-string first argument"), "in dex");
if ((fixtype(s2)->flags & STRING) == 0) if ((fixtype(s2)->flags & STRING) == 0)
lintwarn(_("index: received non-string second argument")) ; lintwarn(_("%s: received non-string second argument"), "i ndex");
} }
s1 = force_string(s1); s1 = force_string(s1);
s2 = force_string(s2); s2 = force_string(s2);
p1 = s1->stptr; p1 = s1->stptr;
p2 = s2->stptr; p2 = s2->stptr;
l1 = s1->stlen; l1 = s1->stlen;
l2 = s2->stlen; l2 = s2->stlen;
ret = 0; ret = 0;
skipping to change at line 489 skipping to change at line 490
/* do_int --- convert double to int for awk */ /* do_int --- convert double to int for awk */
NODE * NODE *
do_int(int nargs) do_int(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d; double d;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("int: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "int");
d = force_number(tmp)->numbr; d = force_number(tmp)->numbr;
d = double_to_int(d); d = double_to_int(d);
DEREF(tmp); DEREF(tmp);
return make_number((AWKNUM) d); return make_number((AWKNUM) d);
} }
/* do_isarray --- check if argument is array */ /* do_isarray --- check if argument is array */
NODE * NODE *
do_isarray(int nargs) do_isarray(int nargs)
skipping to change at line 550 skipping to change at line 551
* still a good idea. * still a good idea.
*/ */
size = assoc_length(tmp); size = assoc_length(tmp);
return make_number(size); return make_number(size);
} }
assert(tmp->type == Node_val); assert(tmp->type == Node_val);
if (do_lint && (fixtype(tmp)->flags & STRING) == 0) if (do_lint && (fixtype(tmp)->flags & STRING) == 0)
lintwarn(_("length: received non-string argument")); lintwarn(_("%s: received non-string argument"), "length");
tmp = force_string(tmp); tmp = force_string(tmp);
if (gawk_mb_cur_max > 1) { if (gawk_mb_cur_max > 1) {
tmp = force_wstring(tmp); tmp = force_wstring(tmp);
len = tmp->wstlen; len = tmp->wstlen;
/* /*
* If the bytes don't make a valid wide character * If the bytes don't make a valid wide character
* string, fall back to the bytes themselves. * string, fall back to the bytes themselves.
*/ */
if (len == 0 && tmp->stlen > 0) if (len == 0 && tmp->stlen > 0)
skipping to change at line 579 skipping to change at line 580
/* do_log --- the log function */ /* do_log --- the log function */
NODE * NODE *
do_log(int nargs) do_log(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d, arg; double d, arg;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("log: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "log");
arg = force_number(tmp)->numbr; arg = force_number(tmp)->numbr;
if (arg < 0.0) if (arg < 0.0)
warning(_("log: received negative argument %g"), arg); warning(_("%s: received negative argument %g"), "log", arg);
d = log(arg); d = log(arg);
DEREF(tmp); DEREF(tmp);
return make_number((AWKNUM) d); return make_number((AWKNUM) d);
} }
#ifdef HAVE_MPFR #ifdef HAVE_MPFR
/* /*
* mpz2mpfr --- convert an arbitrary-precision integer to a float * mpz2mpfr --- convert an arbitrary-precision integer to a float
* without any loss of precision. The returned value is only * without any loss of precision. The returned value is only
skipping to change at line 733 skipping to change at line 734
mpz_ptr zi; mpz_ptr zi;
mpfr_ptr mf; mpfr_ptr mf;
#endif #endif
enum { MP_NONE = 0, MP_INT_WITH_PREC = 1, MP_INT_WITHOUT_PREC, MP_FLOAT } fmt_type; enum { MP_NONE = 0, MP_INT_WITH_PREC = 1, MP_INT_WITHOUT_PREC, MP_FLOAT } fmt_type;
static const char sp[] = " "; static const char sp[] = " ";
static const char zero_string[] = "0"; static const char zero_string[] = "0";
static const char lchbuf[] = "0123456789abcdef"; static const char lchbuf[] = "0123456789abcdef";
static const char Uchbuf[] = "0123456789ABCDEF"; static const char Uchbuf[] = "0123456789ABCDEF";
#define INITIAL_OUT_SIZE 512 #define INITIAL_OUT_SIZE 64
emalloc(obuf, char *, INITIAL_OUT_SIZE, "format_tree"); emalloc(obuf, char *, INITIAL_OUT_SIZE, "format_tree");
obufout = obuf; obufout = obuf;
osiz = INITIAL_OUT_SIZE; osiz = INITIAL_OUT_SIZE;
ofre = osiz - 1; ofre = osiz - 1;
cur_arg = 1; cur_arg = 1;
{ {
size_t k; size_t k;
for (k = 0; k < sizeof(cpbufs)/sizeof(cpbufs[0]); k++) { for (k = 0; k < sizeof(cpbufs)/sizeof(cpbufs[0]); k++) {
skipping to change at line 921 skipping to change at line 922
if (do_traditional) { if (do_traditional) {
msg(_("fatal: `$' is not permitted in awk formats ")); msg(_("fatal: `$' is not permitted in awk formats "));
goto out; goto out;
} }
if (cur == &fw) { if (cur == &fw) {
argnum = fw; argnum = fw;
fw = 0; fw = 0;
used_dollar = true; used_dollar = true;
if (argnum <= 0) { if (argnum <= 0) {
msg(_("fatal: arg count with `$' must be > 0")); msg(_("fatal: argument index with `$' mus t be > 0"));
goto out; goto out;
} }
if (argnum >= num_args) { if (argnum >= num_args) {
msg(_("fatal: arg count %ld greater than total number of supplied arguments"), argnum); msg(_("fatal: argument index %ld greater than total number of supplied arguments"), argnum);
goto out; goto out;
} }
} else { } else {
msg(_("fatal: `$' not permitted after period in f ormat")); msg(_("fatal: `$' not permitted after period in f ormat"));
goto out; goto out;
} }
goto retry; goto retry;
case '*': case '*':
if (cur == NULL) if (cur == NULL)
skipping to change at line 1645 skipping to change at line 1646
if (do_lint) { if (do_lint) {
if (need_format) if (need_format)
lintwarn( lintwarn(
_("[s]printf: format specifier does not have control lett er")); _("[s]printf: format specifier does not have control lett er"));
if (cur_arg < num_args) if (cur_arg < num_args)
lintwarn( lintwarn(
_("too many arguments supplied for format string")); _("too many arguments supplied for format string"));
} }
bchunk(s0, s1 - s0); bchunk(s0, s1 - s0);
olen_final = obufout - obuf; olen_final = obufout - obuf;
if (ofre > 0) #define GIVE_BACK_SIZE (INITIAL_OUT_SIZE * 2)
if (ofre > GIVE_BACK_SIZE)
erealloc(obuf, char *, olen_final + 1, "format_tree"); erealloc(obuf, char *, olen_final + 1, "format_tree");
r = make_str_node(obuf, olen_final, ALREADY_MALLOCED); r = make_str_node(obuf, olen_final, ALREADY_MALLOCED);
obuf = NULL; obuf = NULL;
out: out:
{ {
size_t k; size_t k;
size_t count = sizeof(cpbufs)/sizeof(cpbufs[0]); size_t count = sizeof(cpbufs)/sizeof(cpbufs[0]);
for (k = 0; k < count; k++) { for (k = 0; k < count; k++) {
if (cpbufs[k].buf != cpbufs[k].stackbuf) if (cpbufs[k].buf != cpbufs[k].stackbuf)
efree(cpbufs[k].buf); efree(cpbufs[k].buf);
skipping to change at line 1788 skipping to change at line 1790
/* do_sqrt --- do the sqrt function */ /* do_sqrt --- do the sqrt function */
NODE * NODE *
do_sqrt(int nargs) do_sqrt(int nargs)
{ {
NODE *tmp; NODE *tmp;
double arg; double arg;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("sqrt: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "sqrt");
arg = (double) force_number(tmp)->numbr; arg = (double) force_number(tmp)->numbr;
DEREF(tmp); DEREF(tmp);
if (arg < 0.0) if (arg < 0.0)
warning(_("sqrt: called with negative argument %g"), arg); warning(_("%s: received negative argument %g"), "sqrt", arg);
return make_number((AWKNUM) sqrt(arg)); return make_number((AWKNUM) sqrt(arg));
} }
/* do_substr --- do the substr function */ /* do_substr --- do the substr function */
NODE * NODE *
do_substr(int nargs) do_substr(int nargs)
{ {
NODE *t1; NODE *t1;
NODE *r; NODE *r;
skipping to change at line 1999 skipping to change at line 2001
if (nargs == 3) { if (nargs == 3) {
t3 = POP_SCALAR(); t3 = POP_SCALAR();
do_gmt = boolval(t3); do_gmt = boolval(t3);
DEREF(t3); DEREF(t3);
} }
if (nargs >= 2) { if (nargs >= 2) {
t2 = POP_SCALAR(); t2 = POP_SCALAR();
if (do_lint && (fixtype(t2)->flags & NUMBER) == 0) if (do_lint && (fixtype(t2)->flags & NUMBER) == 0)
lintwarn(_("strftime: received non-numeric second argument")); lintwarn(_("%s: received non-numeric second argum ent"), "strftime");
(void) force_number(t2); (void) force_number(t2);
clock_val = get_number_d(t2); clock_val = get_number_d(t2);
fclock = (time_t) clock_val; fclock = (time_t) clock_val;
/* /*
* Protect against negative value being assigned * Protect against negative value being assigned
* to unsigned time_t. * to unsigned time_t.
*/ */
if (clock_val < 0 && fclock > 0) { if (clock_val < 0 && fclock > 0) {
if (do_lint) if (do_lint)
lintwarn(_("strftime: second argument les s than 0 or too big for time_t")); lintwarn(_("strftime: second argument les s than 0 or too big for time_t"));
skipping to change at line 2025 skipping to change at line 2027
if (do_lint) if (do_lint)
lintwarn(_("strftime: second argument out of range for time_t")); lintwarn(_("strftime: second argument out of range for time_t"));
return make_string("", 0); return make_string("", 0);
} }
DEREF(t2); DEREF(t2);
} }
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & STRING) == 0) if (do_lint && (fixtype(tmp)->flags & STRING) == 0)
lintwarn(_("strftime: received non-string first argument" )); lintwarn(_("%s: received non-string first argument"), "st rftime");
t1 = force_string(tmp); t1 = force_string(tmp);
format = t1->stptr; format = t1->stptr;
formatlen = t1->stlen; formatlen = t1->stlen;
if (formatlen == 0) { if (formatlen == 0) {
if (do_lint) if (do_lint)
lintwarn(_("strftime: received empty format strin g")); lintwarn(_("strftime: received empty format strin g"));
DEREF(t1); DEREF(t1);
return make_string("", 0); return make_string("", 0);
} }
skipping to change at line 2115 skipping to change at line 2117
if (nargs == 2) { if (nargs == 2) {
t2 = POP_SCALAR(); t2 = POP_SCALAR();
do_gmt = boolval(t2); do_gmt = boolval(t2);
DEREF(t2); DEREF(t2);
} }
else else
do_gmt = false; do_gmt = false;
t1 = POP_SCALAR(); t1 = POP_SCALAR();
if (do_lint && (fixtype(t1)->flags & STRING) == 0) if (do_lint && (fixtype(t1)->flags & STRING) == 0)
lintwarn(_("mktime: received non-string argument")); lintwarn(_("%s: received non-string argument"), "mktime");
t1 = force_string(t1); t1 = force_string(t1);
save = t1->stptr[t1->stlen]; save = t1->stptr[t1->stlen];
t1->stptr[t1->stlen] = '\0'; t1->stptr[t1->stlen] = '\0';
count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d", count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d",
& year, & month, & day, & year, & month, & day,
& hour, & minute, & second, & hour, & minute, & second,
& dst); & dst);
skipping to change at line 2173 skipping to change at line 2175
char *cmd; char *cmd;
char save; char save;
int status; int status;
if (do_sandbox) if (do_sandbox)
fatal(_("'system' function not allowed in sandbox mode")); fatal(_("'system' function not allowed in sandbox mode"));
(void) flush_io(); /* so output is synchronous with gawk's */ (void) flush_io(); /* so output is synchronous with gawk's */
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & STRING) == 0) if (do_lint && (fixtype(tmp)->flags & STRING) == 0)
lintwarn(_("system: received non-string argument")); lintwarn(_("%s: received non-string argument"), "system");
cmd = force_string(tmp)->stptr; cmd = force_string(tmp)->stptr;
if (cmd && *cmd) { if (cmd && *cmd) {
/* insure arg to system is zero-terminated */ /* insure arg to system is zero-terminated */
save = cmd[tmp->stlen]; save = cmd[tmp->stlen];
cmd[tmp->stlen] = '\0'; cmd[tmp->stlen] = '\0';
os_restore_mode(fileno(stdin)); os_restore_mode(fileno(stdin));
set_sigpipe_to_default(); set_sigpipe_to_default();
skipping to change at line 2265 skipping to change at line 2267
for (i = 1; i <= nargs; i++) { for (i = 1; i <= nargs; i++) {
tmp = args_array[i] = POP(); tmp = args_array[i] = POP();
if (tmp->type == Node_var_array) { if (tmp->type == Node_var_array) {
while (--i > 0) while (--i > 0)
DEREF(args_array[i]); DEREF(args_array[i]);
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(tmp)); fatal(_("attempt to use array `%s' in a scalar context"), array_vname(tmp));
} }
// Let force_string_ofmt handle checking if things // Let force_string_ofmt handle checking if things
// are already valid. // are already valid.
args_array[i] = force_string_ofmt(tmp); args_array[i] = force_string_ofmt(tmp);
if (args_array[i] != tmp)
DEREF(tmp);
} }
if (redir_exp != NULL) { if (redir_exp != NULL) {
DEREF(redir_exp); DEREF(redir_exp);
decr_sp(); decr_sp();
} }
if (fp == NULL) { if (fp == NULL) {
for (i = nargs; i > 0; i--) for (i = nargs; i > 0; i--)
DEREF(args_array[i]); DEREF(args_array[i]);
skipping to change at line 2422 skipping to change at line 2426
/* do_tolower --- lower case a string */ /* do_tolower --- lower case a string */
NODE * NODE *
do_tolower(int nargs) do_tolower(int nargs)
{ {
NODE *t1, *t2; NODE *t1, *t2;
t1 = POP_SCALAR(); t1 = POP_SCALAR();
if (do_lint && (fixtype(t1)->flags & STRING) == 0) if (do_lint && (fixtype(t1)->flags & STRING) == 0)
lintwarn(_("tolower: received non-string argument")); lintwarn(_("%s: received non-string argument"), "tolower");
t1 = force_string(t1); t1 = force_string(t1);
t2 = make_string(t1->stptr, t1->stlen); t2 = make_string(t1->stptr, t1->stlen);
if (gawk_mb_cur_max == 1) { if (gawk_mb_cur_max == 1) {
unsigned char *cp, *cp2; unsigned char *cp, *cp2;
for (cp = (unsigned char *)t2->stptr, for (cp = (unsigned char *)t2->stptr,
cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp2 = (unsigned char *)(t2->stptr + t2->stlen);
cp < cp2; cp++) cp < cp2; cp++)
if (isupper(*cp)) if (isupper(*cp))
skipping to change at line 2453 skipping to change at line 2457
/* do_toupper --- upper case a string */ /* do_toupper --- upper case a string */
NODE * NODE *
do_toupper(int nargs) do_toupper(int nargs)
{ {
NODE *t1, *t2; NODE *t1, *t2;
t1 = POP_SCALAR(); t1 = POP_SCALAR();
if (do_lint && (fixtype(t1)->flags & STRING) == 0) if (do_lint && (fixtype(t1)->flags & STRING) == 0)
lintwarn(_("toupper: received non-string argument")); lintwarn(_("%s: received non-string argument"), "toupper");
t1 = force_string(t1); t1 = force_string(t1);
t2 = make_string(t1->stptr, t1->stlen); t2 = make_string(t1->stptr, t1->stlen);
if (gawk_mb_cur_max == 1) { if (gawk_mb_cur_max == 1) {
unsigned char *cp, *cp2; unsigned char *cp, *cp2;
for (cp = (unsigned char *)t2->stptr, for (cp = (unsigned char *)t2->stptr,
cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp2 = (unsigned char *)(t2->stptr + t2->stlen);
cp < cp2; cp++) cp < cp2; cp++)
if (islower(*cp)) if (islower(*cp))
skipping to change at line 2486 skipping to change at line 2490
NODE * NODE *
do_atan2(int nargs) do_atan2(int nargs)
{ {
NODE *t1, *t2; NODE *t1, *t2;
double d1, d2; double d1, d2;
POP_TWO_SCALARS(t1, t2); POP_TWO_SCALARS(t1, t2);
if (do_lint) { if (do_lint) {
if ((fixtype(t1)->flags & NUMBER) == 0) if ((fixtype(t1)->flags & NUMBER) == 0)
lintwarn(_("atan2: received non-numeric first argument")) ; lintwarn(_("%s: received non-numeric first argument"), "a tan2");
if ((fixtype(t2)->flags & NUMBER) == 0) if ((fixtype(t2)->flags & NUMBER) == 0)
lintwarn(_("atan2: received non-numeric second argument") ); lintwarn(_("%s: received non-numeric second argument"), " atan2");
} }
d1 = force_number(t1)->numbr; d1 = force_number(t1)->numbr;
d2 = force_number(t2)->numbr; d2 = force_number(t2)->numbr;
DEREF(t1); DEREF(t1);
DEREF(t2); DEREF(t2);
return make_number((AWKNUM) atan2(d1, d2)); return make_number((AWKNUM) atan2(d1, d2));
} }
/* do_sin --- do the sin function */ /* do_sin --- do the sin function */
NODE * NODE *
do_sin(int nargs) do_sin(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d; double d;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("sin: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "sin");
d = sin((double) force_number(tmp)->numbr); d = sin((double) force_number(tmp)->numbr);
DEREF(tmp); DEREF(tmp);
return make_number((AWKNUM) d); return make_number((AWKNUM) d);
} }
/* do_cos --- do the cos function */ /* do_cos --- do the cos function */
NODE * NODE *
do_cos(int nargs) do_cos(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d; double d;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("cos: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "cos");
d = cos((double) force_number(tmp)->numbr); d = cos((double) force_number(tmp)->numbr);
DEREF(tmp); DEREF(tmp);
return make_number((AWKNUM) d); return make_number((AWKNUM) d);
} }
/* do_rand --- do the rand function */ /* do_rand --- do the rand function */
static bool firstrand = true; static bool firstrand = true;
/* Some systems require this array to be integer aligned. Sigh. */ /* Some systems require this array to be integer aligned. Sigh. */
#define SIZEOF_STATE 256 #define SIZEOF_STATE 256
skipping to change at line 2637 skipping to change at line 2641
/* don't need to srandom(1), we're changing the seed below */ /* don't need to srandom(1), we're changing the seed below */
firstrand = false; firstrand = false;
(void) setstate(state); (void) setstate(state);
} }
if (nargs == 0) if (nargs == 0)
srandom((unsigned int) (save_seed = (long) time((time_t *) 0))); srandom((unsigned int) (save_seed = (long) time((time_t *) 0)));
else { else {
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("srand: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "srand") ;
srandom((unsigned int) (save_seed = (long) force_number(tmp)->num br)); srandom((unsigned int) (save_seed = (long) force_number(tmp)->num br));
DEREF(tmp); DEREF(tmp);
} }
return make_number((AWKNUM) ret); return make_number((AWKNUM) ret);
} }
/* do_match --- match a regexp, set RSTART and RLENGTH, /* do_match --- match a regexp, set RSTART and RLENGTH,
* optional third arg is array filled with text of * optional third arg is array filled with text of
* subpatterns enclosed in parens and start and len info. * subpatterns enclosed in parens and start and len info.
*/ */
skipping to change at line 3230 skipping to change at line 3234
NODE *zero = make_number(0.0); NODE *zero = make_number(0.0);
NODE *result; NODE *result;
if (name[0] == 'g') { if (name[0] == 'g') {
if (name[1] == 'e') if (name[1] == 'e')
flags = GENSUB; flags = GENSUB;
else else
flags = GSUB; flags = GSUB;
} }
bool need_free = false;
if (flags == 0 || flags == GSUB) { if (flags == 0 || flags == GSUB) {
/* sub or gsub */ /* sub or gsub */
if (nargs != 2) if (nargs != 2)
fatal(_("%s: can be called indirectly only with two argum ents"), name); fatal(_("%s: can be called indirectly only with two argum ents"), name);
replace = POP_STRING(); replace = POP_STRING();
regex = POP(); /* the regex */ regex = POP(); /* the regex */
/* /*
* push regex * push regex
* push replace * push replace
* push $0 * push $0
*/ */
if ((regex->flags & REGEX) != 0) if ((regex->flags & REGEX) != 0)
regex = regex->typed_re; regex = regex->typed_re;
else else {
regex = make_regnode(Node_regex, regex); regex = make_regnode(Node_regex, regex);
need_free = true;
}
PUSH(regex); PUSH(regex);
PUSH(replace); PUSH(replace);
lhs = r_get_field(zero, (Func_ptr *) 0, true); lhs = r_get_field(zero, (Func_ptr *) 0, true);
nargs++; nargs++;
PUSH_ADDRESS(lhs); PUSH_ADDRESS(lhs);
} else { } else {
/* gensub */ /* gensub */
if (nargs == 4) if (nargs == 4)
rhs = POP(); rhs = POP();
else else
skipping to change at line 3271 skipping to change at line 3278
* push regex * push regex
* push replace * push replace
* push glob_flag * push glob_flag
* if (nargs = 3) { * if (nargs = 3) {
* push $0 * push $0
* nargs++ * nargs++
* } * }
*/ */
if ((regex->flags & REGEX) != 0) if ((regex->flags & REGEX) != 0)
regex = regex->typed_re; regex = regex->typed_re;
else else {
regex = make_regnode(Node_regex, regex); regex = make_regnode(Node_regex, regex);
need_free = true;
}
PUSH(regex); PUSH(regex);
PUSH(replace); PUSH(replace);
PUSH(glob_flag); PUSH(glob_flag);
if (rhs == NULL) { if (rhs == NULL) {
lhs = r_get_field(zero, (Func_ptr *) 0, true); lhs = r_get_field(zero, (Func_ptr *) 0, true);
rhs = *lhs; rhs = *lhs;
UPREF(rhs); UPREF(rhs);
PUSH(rhs); PUSH(rhs);
nargs++; nargs++;
} }
else else
PUSH(rhs); PUSH(rhs);
} }
unref(zero); unref(zero);
result = do_sub(nargs, flags); result = do_sub(nargs, flags);
if (need_free) {
refree(regex->re_reg[0]);
if (regex->re_reg[1] != NULL)
refree(regex->re_reg[1]);
freenode(regex);
}
if (flags != GENSUB) if (flags != GENSUB)
reset_record(); reset_record();
return result; return result;
} }
/* call_match --- call do_match indirectly */ /* call_match --- call do_match indirectly */
NODE * NODE *
call_match(int nargs) call_match(int nargs)
{ {
NODE *regex, *text, *array; NODE *regex, *text, *array;
NODE *result; NODE *result;
regex = text = array = NULL; regex = text = array = NULL;
if (nargs == 3) if (nargs == 3)
array = POP(); array = POP();
regex = POP(); regex = POP();
/* Don't need to pop the string just to push it back ... */ /* Don't need to pop the string just to push it back ... */
bool need_free = false;
if ((regex->flags & REGEX) != 0) if ((regex->flags & REGEX) != 0)
regex = regex->typed_re; regex = regex->typed_re;
else else {
regex = make_regnode(Node_regex, regex); regex = make_regnode(Node_regex, regex);
need_free = true;
}
PUSH(regex); PUSH(regex);
if (array) if (array)
PUSH(array); PUSH(array);
result = do_match(nargs); result = do_match(nargs);
if (need_free) {
refree(regex->re_reg[0]);
if (regex->re_reg[1] != NULL)
refree(regex->re_reg[1]);
freenode(regex);
}
return result; return result;
} }
/* call_split_func --- call do_split or do_pat_split indirectly */ /* call_split_func --- call do_split or do_pat_split indirectly */
NODE * NODE *
call_split_func(const char *name, int nargs) call_split_func(const char *name, int nargs)
{ {
NODE *regex, *seps; NODE *regex, *seps;
NODE *result; NODE *result;
regex = seps = NULL; regex = seps = NULL;
if (nargs < 2) if (nargs < 2)
fatal(_("indirect call to %s requires at least two arguments"), fatal(_("indirect call to %s requires at least two arguments"),
name); name);
if (nargs == 4) if (nargs == 4)
seps = POP(); seps = POP();
bool need_free = false;
if (nargs >= 3) { if (nargs >= 3) {
regex = POP_STRING(); regex = POP_STRING();
if ((regex->flags & REGEX) != 0) if ((regex->flags & REGEX) != 0)
regex = regex->typed_re; regex = regex->typed_re;
else else {
regex = make_regnode(Node_regex, regex); regex = make_regnode(Node_regex, regex);
need_free = true;
}
} else { } else {
if (name[0] == 's') { if (name[0] == 's') {
regex = make_regnode(Node_regex, FS_node->var_value); regex = make_regnode(Node_regex, FS_node->var_value);
regex->re_flags |= FS_DFLT; regex->re_flags |= FS_DFLT;
} else } else
regex = make_regnode(Node_regex, FPAT_node->var_value); regex = make_regnode(Node_regex, FPAT_node->var_value);
need_free = true;
nargs++; nargs++;
} }
/* Don't need to pop the string or the data array */ /* Don't need to pop the string or the data array */
PUSH(regex); PUSH(regex);
if (seps) if (seps)
PUSH(seps); PUSH(seps);
result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs); result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs);
if (need_free) {
refree(regex->re_reg[0]);
if (regex->re_reg[1] != NULL)
refree(regex->re_reg[1]);
freenode(regex);
}
return result; return result;
} }
/* make_integer - Convert an integer to a number node. */ /* make_integer - Convert an integer to a number node. */
static NODE * static NODE *
make_integer(uintmax_t n) make_integer(uintmax_t n)
{ {
n = adjust_uint(n); n = adjust_uint(n);
skipping to change at line 3388 skipping to change at line 3428
NODE * NODE *
do_lshift(int nargs) do_lshift(int nargs)
{ {
NODE *s1, *s2; NODE *s1, *s2;
uintmax_t uval, ushift, res; uintmax_t uval, ushift, res;
AWKNUM val, shift; AWKNUM val, shift;
POP_TWO_SCALARS(s1, s2); POP_TWO_SCALARS(s1, s2);
if (do_lint) { if (do_lint) {
if ((fixtype(s1)->flags & NUMBER) == 0) if ((fixtype(s1)->flags & NUMBER) == 0)
lintwarn(_("lshift: received non-numeric first argument") ); lintwarn(_("%s: received non-numeric first argument"), "l shift");
if ((fixtype(s2)->flags & NUMBER) == 0) if ((fixtype(s2)->flags & NUMBER) == 0)
lintwarn(_("lshift: received non-numeric second argument" )); lintwarn(_("%s: received non-numeric second argument"), " lshift");
} }
val = force_number(s1)->numbr; val = force_number(s1)->numbr;
shift = force_number(s2)->numbr; shift = force_number(s2)->numbr;
if (val < 0 || shift < 0) if (val < 0 || shift < 0)
fatal(_("lshift(%f, %f): negative values are not allowed"), val, shift); fatal(_("lshift(%f, %f): negative values are not allowed"), val, shift);
if (do_lint) { if (do_lint) {
if (double_to_int(val) != val || double_to_int(shift) != shift) if (double_to_int(val) != val || double_to_int(shift) != shift)
lintwarn(_("lshift(%f, %f): fractional values will be tru ncated"), val, shift); lintwarn(_("lshift(%f, %f): fractional values will be tru ncated"), val, shift);
skipping to change at line 3427 skipping to change at line 3467
NODE * NODE *
do_rshift(int nargs) do_rshift(int nargs)
{ {
NODE *s1, *s2; NODE *s1, *s2;
uintmax_t uval, ushift, res; uintmax_t uval, ushift, res;
AWKNUM val, shift; AWKNUM val, shift;
POP_TWO_SCALARS(s1, s2); POP_TWO_SCALARS(s1, s2);
if (do_lint) { if (do_lint) {
if ((fixtype(s1)->flags & NUMBER) == 0) if ((fixtype(s1)->flags & NUMBER) == 0)
lintwarn(_("rshift: received non-numeric first argument") ); lintwarn(_("%s: received non-numeric first argument"), "r shift");
if ((fixtype(s2)->flags & NUMBER) == 0) if ((fixtype(s2)->flags & NUMBER) == 0)
lintwarn(_("rshift: received non-numeric second argument" )); lintwarn(_("%s: received non-numeric second argument"), " rshift");
} }
val = force_number(s1)->numbr; val = force_number(s1)->numbr;
shift = force_number(s2)->numbr; shift = force_number(s2)->numbr;
if (val < 0 || shift < 0) if (val < 0 || shift < 0)
fatal(_("rshift(%f, %f): negative values are not allowed"), val, shift); fatal(_("rshift(%f, %f): negative values are not allowed"), val, shift);
if (do_lint) { if (do_lint) {
if (double_to_int(val) != val || double_to_int(shift) != shift) if (double_to_int(val) != val || double_to_int(shift) != shift)
lintwarn(_("rshift(%f, %f): fractional values will be tru ncated"), val, shift); lintwarn(_("rshift(%f, %f): fractional values will be tru ncated"), val, shift);
skipping to change at line 3462 skipping to change at line 3502
} }
/* do_and --- perform an & operation */ /* do_and --- perform an & operation */
NODE * NODE *
do_and(int nargs) do_and(int nargs)
{ {
NODE *s1; NODE *s1;
uintmax_t res, uval; uintmax_t res, uval;
AWKNUM val; AWKNUM val;
int i;
res = ~0; /* start off with all ones */ res = ~(uintmax_t) 0; /* start off with all ones */
if (nargs < 2) if (nargs < 2)
fatal(_("and: called with less than two arguments")); fatal(_("%s: called with less than two arguments"), "and");
for (i = 1; nargs > 0; nargs--, i++) { for (; nargs > 0; nargs--) {
s1 = POP_SCALAR(); s1 = POP_SCALAR();
if (do_lint && (fixtype(s1)->flags & NUMBER) == 0) if (do_lint && (fixtype(s1)->flags & NUMBER) == 0)
lintwarn(_("and: argument %d is non-numeric"), i); lintwarn(_("%s: argument %d is non-numeric"), "and", narg s);
val = force_number(s1)->numbr; val = force_number(s1)->numbr;
if (val < 0) if (val < 0)
fatal(_("and: argument %d negative value %g is not allowe d"), i, val); fatal(_("%s: argument %d negative value %g is not allowed "), "and", nargs, val);
uval = (uintmax_t) val; uval = (uintmax_t) val;
res &= uval; res &= uval;
DEREF(s1); DEREF(s1);
} }
return make_integer(res); return make_integer(res);
} }
/* do_or --- perform an | operation */ /* do_or --- perform an | operation */
NODE * NODE *
do_or(int nargs) do_or(int nargs)
{ {
NODE *s1; NODE *s1;
uintmax_t res, uval; uintmax_t res, uval;
AWKNUM val; AWKNUM val;
int i;
res = 0; res = 0;
if (nargs < 2) if (nargs < 2)
fatal(_("or: called with less than two arguments")); fatal(_("%s: called with less than two arguments"), "or");
for (i = 1; nargs > 0; nargs--, i++) { for (; nargs > 0; nargs--) {
s1 = POP_SCALAR(); s1 = POP_SCALAR();
if (do_lint && (fixtype(s1)->flags & NUMBER) == 0) if (do_lint && (fixtype(s1)->flags & NUMBER) == 0)
lintwarn(_("or: argument %d is non-numeric"), i); lintwarn(_("%s: argument %d is non-numeric"), "or", nargs );
val = force_number(s1)->numbr; val = force_number(s1)->numbr;
if (val < 0) if (val < 0)
fatal(_("or: argument %d negative value %g is not allowed "), i, val); fatal(_("%s: argument %d negative value %g is not allowed "), "or", nargs, val);
uval = (uintmax_t) val; uval = (uintmax_t) val;
res |= uval; res |= uval;
DEREF(s1); DEREF(s1);
} }
return make_integer(res); return make_integer(res);
} }
/* do_xor --- perform an ^ operation */ /* do_xor --- perform an ^ operation */
NODE * NODE *
do_xor(int nargs) do_xor(int nargs)
{ {
NODE *s1; NODE *s1;
uintmax_t res, uval; uintmax_t res, uval;
AWKNUM val; AWKNUM val;
int i;
if (nargs < 2) if (nargs < 2)
fatal(_("xor: called with less than two arguments")); fatal(_("%s: called with less than two arguments"), "xor");
res = 0; /* silence compiler warning */ res = 0; /* start with all zeroes */
for (i = 1; nargs > 0; nargs--, i++) { for (; nargs > 0; nargs--) {
s1 = POP_SCALAR(); s1 = POP_SCALAR();
if (do_lint && (fixtype(s1)->flags & NUMBER) == 0) if (do_lint && (fixtype(s1)->flags & NUMBER) == 0)
lintwarn(_("xor: argument %d is non-numeric"), i); lintwarn(_("%s: argument %d is non-numeric"), "xor", narg s);
val = force_number(s1)->numbr; val = force_number(s1)->numbr;
if (val < 0) if (val < 0)
fatal(_("xor: argument %d negative value %g is not allowe d"), i, val); fatal(_("%s: argument %d negative value %g is not allowed "), "xor", nargs, val);
uval = (uintmax_t) val; uval = (uintmax_t) val;
if (i == 1) res ^= uval;
res = uval;
else
res ^= uval;
DEREF(s1); DEREF(s1);
} }
return make_integer(res); return make_integer(res);
} }
/* do_compl --- perform a ~ operation */ /* do_compl --- perform a ~ operation */
NODE * NODE *
do_compl(int nargs) do_compl(int nargs)
{ {
NODE *tmp; NODE *tmp;
double d; double d;
uintmax_t uval; uintmax_t uval;
tmp = POP_SCALAR(); tmp = POP_SCALAR();
if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0) if (do_lint && (fixtype(tmp)->flags & NUMBER) == 0)
lintwarn(_("compl: received non-numeric argument")); lintwarn(_("%s: received non-numeric argument"), "compl");
d = force_number(tmp)->numbr; d = force_number(tmp)->numbr;
DEREF(tmp); DEREF(tmp);
if (d < 0) if (d < 0)
fatal(_("compl(%f): negative value is not allowed"), d); fatal(_("compl(%f): negative value is not allowed"), d);
if (do_lint && double_to_int(d) != d) if (do_lint && double_to_int(d) != d)
lintwarn(_("compl(%f): fractional value will be truncated"), d); lintwarn(_("compl(%f): fractional value will be truncated"), d);
uval = (uintmax_t) d; uval = (uintmax_t) d;
skipping to change at line 3987 skipping to change at line 4021
result = POP_PARAM(); result = POP_PARAM();
if (result->type != Node_var_array) if (result->type != Node_var_array)
fatal(_("intdiv: third argument is not an array")); fatal(_("intdiv: third argument is not an array"));
assoc_clear(result); assoc_clear(result);
denominator = POP_SCALAR(); denominator = POP_SCALAR();
numerator = POP_SCALAR(); numerator = POP_SCALAR();
if (do_lint) { if (do_lint) {
if ((fixtype(numerator)->flags & NUMBER) == 0) if ((fixtype(numerator)->flags & NUMBER) == 0)
lintwarn(_("intdiv: received non-numeric first argument") ); lintwarn(_("%s: received non-numeric first argument"), "i ntdiv");
if ((fixtype(denominator)->flags & NUMBER) == 0) if ((fixtype(denominator)->flags & NUMBER) == 0)
lintwarn(_("intdiv: received non-numeric second argument" )); lintwarn(_("%s: received non-numeric second argument"), " intdiv");
} }
(void) force_number(numerator); (void) force_number(numerator);
(void) force_number(denominator); (void) force_number(denominator);
num = double_to_int(get_number_d(numerator)); num = double_to_int(get_number_d(numerator));
denom = double_to_int(get_number_d(denominator)); denom = double_to_int(get_number_d(denominator));
if (denom == 0.0) if (denom == 0.0)
fatal(_("intdiv: division by zero attempted")); fatal(_("intdiv: division by zero attempted"));
skipping to change at line 4048 skipping to change at line 4082
assoc_clear(dbg); assoc_clear(dbg);
} }
else else
dbg = NULL; dbg = NULL;
arg = POP(); arg = POP();
switch (arg->type) { switch (arg->type) {
case Node_var_array: case Node_var_array:
/* Node_var_array is never UPREF'ed */ /* Node_var_array is never UPREF'ed */
res = "array"; res = "array";
deref = false; deref = false;
if (dbg) if (dbg) {
assoc_set(dbg, make_string("array_type", 10), make_string (arg->array_funcs->name, strlen(arg->array_funcs->name))); assoc_set(dbg, make_string("array_type", 10), make_string (arg->array_funcs->name, strlen(arg->array_funcs->name)));
if (arg == PROCINFO_node) {
int i;
for (i = 0; i < BLOCK_MAX; i++) {
char *p;
size_t nl = strlen(nextfree[i].name);
/*
* save values before we create new
* array elements so that we have a
* snapshot at a consistent moment in
* time
*/
long hw = nextfree[i].highwater;
long active;
#ifdef MEMDEBUG
active = nextfree[i].active;
#else
active = hw;
{
struct block_item *ip;
for (ip = nextfree[i].freep; ip;
ip = ip->freep)
active--;
}
#endif
#define SETVAL(X, V) { \
size_t l = nl + sizeof(#X); \
emalloc(p, char *, l+1, "do_typeof"); \
sprintf(p, "%s_" #X, nextfree[i].name); \
assoc_set(dbg, make_str_node(p, l, ALREADY_MALLOCED), make_number((AWKNUM
) (V))); \
}
SETVAL(highwater, hw)
SETVAL(active, active)
#undef SETVAL
}
}
}
break; break;
case Node_val: case Node_val:
switch (fixtype(arg)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) { switch (fixtype(arg)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
case NUMBER: case NUMBER:
res = "number"; res = "number";
break; break;
case NUMBER|USER_INPUT: case NUMBER|USER_INPUT:
res = "strnum"; res = "strnum";
break; break;
case REGEX: case REGEX:
skipping to change at line 4084 skipping to change at line 4154
res = "unknown"; res = "unknown";
} }
break; break;
} }
if (dbg) { if (dbg) {
const char *s = flags2str(arg->flags); const char *s = flags2str(arg->flags);
assoc_set(dbg, make_string("flags", 5), make_string(s, st rlen(s))); assoc_set(dbg, make_string("flags", 5), make_string(s, st rlen(s)));
} }
break; break;
case Node_var_new: case Node_var_new:
case Node_array_ref:
res = "untyped"; res = "untyped";
deref = false; deref = false;
break; break;
case Node_var: case Node_var:
/* /*
* Note: this doesn't happen because the function calling code * Note: this doesn't happen because the function calling code
* in interpret.h pushes Node_var->var_value. * in interpret.h pushes Node_var->var_value.
*/ */
fatal(_("typeof: invalid argument type `%s'"), fatal(_("typeof: invalid argument type `%s'"),
nodetype2str(arg->type)); nodetype2str(arg->type));
 End of changes. 69 change blocks. 
59 lines changed or deleted 132 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)