~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to eval.c

  • Committer: Arnold D. Robbins
  • Date: 2010-07-16 11:47:02 UTC
  • Revision ID: git-v1:315bd501ca696bc3e3c938b4604d8dac7a6f512f
Tags: gawk-3.1.5
Move to gawk 3.1.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 */
4
4
 
5
5
/* 
6
 
 * Copyright (C) 1986, 1988, 1989, 1991-2004 the Free Software Foundation, Inc.
 
6
 * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
7
7
 * 
8
8
 * This file is part of GAWK, the GNU implementation of the
9
9
 * AWK Programming Language.
20
20
 * 
21
21
 * You should have received a copy of the GNU General Public License
22
22
 * along with this program; if not, write to the Free Software
23
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24
24
 */
25
25
 
26
26
#include "awk.h"
322
322
                { FUNC, "FUNC" },
323
323
                { FIELD, "FIELD" },
324
324
                { INTLSTR, "INTLSTR" },
 
325
#ifdef WSTRCUR
 
326
                { WSTRCUR, "WSTRCUR" },
 
327
#endif
325
328
                { 0,    NULL },
326
329
        };
327
330
 
375
378
 */
376
379
 
377
380
static inline void
378
 
make_scalar P((NODE *tree))
 
381
make_scalar(NODE *tree)
379
382
{
380
383
        switch (tree->type) {
381
384
        case Node_var_array:
517
520
                                        NODE *t1;
518
521
                                        Regexp *rp;
519
522
                                        /* see comments in match_op() code about this. */
520
 
                                        int kludge_need_start = FALSE;
 
523
                                        int kludge_need_start = 0;
521
524
 
522
525
                                        t1 = force_string(switch_value);
523
526
                                        rp = re_update(case_stmt->lnode);
524
527
 
525
528
                                        if (avoid_dfa(tree, t1->stptr, t1->stlen))
526
 
                                                kludge_need_start = TRUE;
 
529
                                                kludge_need_start = RE_NEED_START;
527
530
                                        match_found = (research(rp, t1->stptr, 0, t1->stlen, kludge_need_start) >= 0);
528
531
                                        if (t1 != switch_value)
529
532
                                                free_temp(t1);
879
882
        return 1;
880
883
}
881
884
 
 
885
/*
 
886
 * calc_exp_posint --- calculate x^n for positive integral n,
 
887
 * using exponentiation by squaring without recursion.
 
888
 */
 
889
 
 
890
static AWKNUM
 
891
calc_exp_posint(AWKNUM x, long n)
 
892
{
 
893
        AWKNUM mult = 1;
 
894
 
 
895
        while (n > 1) {
 
896
                if ((n % 2) == 1)
 
897
                        mult *= x;
 
898
                x *= x;
 
899
                n /= 2;
 
900
        }
 
901
        return mult * x;
 
902
}
 
903
 
 
904
/* calc_exp --- calculate x1^x2 */
 
905
 
 
906
static AWKNUM
 
907
calc_exp(AWKNUM x1, AWKNUM x2)
 
908
{
 
909
        long lx;
 
910
 
 
911
        if ((lx = x2) == x2) {          /* integer exponent */
 
912
                if (lx == 0)
 
913
                        return 1;
 
914
                return (lx > 0) ? calc_exp_posint(x1, lx)
 
915
                                : 1.0 / calc_exp_posint(x1, -lx);
 
916
        }
 
917
        return (AWKNUM) pow((double) x1, (double) x2);
 
918
}
 
919
 
882
920
/* r_tree_eval --- evaluate a subtree */
883
921
 
884
922
NODE *
888
926
        register NODE **lhs;
889
927
        register int di;
890
928
        AWKNUM x, x1, x2;
891
 
        long lx;
892
929
#ifdef _CRAY
893
930
        long lx2;
894
931
#endif
1138
1175
                        erealloc(l->stptr, char *, nlen, "interpret");
1139
1176
                        memcpy(l->stptr + l->stlen, r->stptr, r->stlen);
1140
1177
                        l->stlen += r->stlen;
 
1178
                        l->stptr[l->stlen] = '\0';
1141
1179
                } else {
1142
1180
                        char *nval;
1143
1181
                        size_t nlen = l->stlen + r->stlen + 2;
1230
1268
        unref(t2);
1231
1269
        switch (tree->type) {
1232
1270
        case Node_exp:
1233
 
                if ((lx = x2) == x2 && lx >= 0) {       /* integer exponent */
1234
 
                        if (lx == 0)
1235
 
                                x = 1;
1236
 
                        else if (lx == 1)
1237
 
                                x = x1;
1238
 
                        else {
1239
 
                                /* doing it this way should be more precise */
1240
 
                                for (x = x1; --lx; )
1241
 
                                        x *= x1;
1242
 
                        }
1243
 
                } else
1244
 
                        x = pow((double) x1, (double) x2);
1245
 
                return tmp_number(x);
 
1271
                return tmp_number(calc_exp(x1, x2));
1246
1272
 
1247
1273
        case Node_times:
1248
1274
                return tmp_number(x1 * x2);
1396
1422
{
1397
1423
        AWKNUM rval, lval;
1398
1424
        NODE **lhs;
1399
 
        AWKNUM t1, t2;
1400
 
        long ltemp;
1401
1425
        NODE *tmp;
1402
1426
        Func_ptr after_assign = NULL;
1403
1427
        int post = FALSE;
1435
1459
                break;
1436
1460
 
1437
1461
        case Node_assign_exp:
1438
 
                if ((ltemp = rval) == rval) {   /* integer exponent */
1439
 
                        if (ltemp == 0)
1440
 
                                *lhs = make_number((AWKNUM) 1);
1441
 
                        else if (ltemp == 1)
1442
 
                                *lhs = make_number(lval);
1443
 
                        else {
1444
 
                                /* doing it this way should be more precise */
1445
 
                                for (t1 = t2 = lval; --ltemp; )
1446
 
                                        t1 *= t2;
1447
 
                                *lhs = make_number(t1);
1448
 
                        }
1449
 
                } else
1450
 
                        *lhs = make_number((AWKNUM) pow((double) lval, (double) rval));
 
1462
                *lhs = make_number(calc_exp(lval, rval));
1451
1463
                break;
1452
1464
 
1453
1465
        case Node_assign_times:
1457
1469
        case Node_assign_quotient:
1458
1470
                if (rval == (AWKNUM) 0)
1459
1471
                        fatal(_("division by zero attempted in `/='"));
 
1472
        {
1460
1473
#ifdef _CRAY
 
1474
                long ltemp;
 
1475
 
1461
1476
                /* special case for integer division, put in for Cray */
1462
1477
                ltemp = rval;
1463
1478
                if (ltemp == 0) {
1470
1485
                else
1471
1486
#endif  /* _CRAY */
1472
1487
                        *lhs = make_number(lval / rval);
 
1488
        }
1473
1489
                break;
1474
1490
 
1475
1491
        case Node_assign_mod:
1478
1494
#ifdef HAVE_FMOD
1479
1495
                *lhs = make_number(fmod(lval, rval));
1480
1496
#else   /* ! HAVE_FMOD */
 
1497
        {
 
1498
                AWKNUM t1, t2;
 
1499
 
1481
1500
                (void) modf(lval / rval, &t1);
1482
1501
                t2 = lval - rval * t1;
1483
1502
                *lhs = make_number(t2);
 
1503
        }
1484
1504
#endif  /* ! HAVE_FMOD */
1485
1505
                break;
1486
1506
 
1785
1805
        }
1786
1806
 
1787
1807
#ifdef FUNC_TRACE
1788
 
        fprintf(stderr, _("function %s called\n"), name->stptr);
 
1808
        fprintf(stderr, "function `%s' called\n", name->stptr);
1789
1809
#endif
1790
1810
        push_args(f->lnode->param_cnt, arg_list, stack_ptr, name->stptr,
1791
1811
                        f->parmlist);
2059
2079
        register Regexp *rp;
2060
2080
        int i;
2061
2081
        int match = TRUE;
2062
 
        int kludge_need_start = FALSE;  /* FIXME: --- see below */
 
2082
        int kludge_need_start = 0;      /* FIXME: --- see below */
2063
2083
 
2064
2084
        if (tree->type == Node_nomatch)
2065
2085
                match = FALSE;
2074
2094
         * FIXME:
2075
2095
         *
2076
2096
         * Any place where research() is called with a last parameter of
2077
 
         * FALSE, we need to use the avoid_dfa test. This appears here and
 
2097
         * zero, we need to use the avoid_dfa test. This appears here and
2078
2098
         * in the code for Node_K_switch.
2079
2099
         *
2080
2100
         * A new or improved dfa that distinguishes beginning/end of
2084
2104
         * The avoid_dfa() function is in re.c; it is not very smart.
2085
2105
         */
2086
2106
        if (avoid_dfa(tree, t1->stptr, t1->stlen))
2087
 
                kludge_need_start = TRUE;
 
2107
                kludge_need_start = RE_NEED_START;
2088
2108
        i = research(rp, t1->stptr, 0, t1->stlen, kludge_need_start);
2089
2109
        i = (i == -1) ^ (match == TRUE);
2090
2110
        free_temp(t1);
2159
2179
                        if (BINMODE == 0 && v->stlen != 0) {
2160
2180
                                /* arbitrary string, assume both */
2161
2181
                                BINMODE = 3;
2162
 
                                warning("BINMODE: arbitary string value treated as \"rw\"");
 
2182
                                warning("BINMODE: arbitrary string value treated as \"rw\"");
2163
2183
                        }
2164
2184
                } else
2165
2185
                        BINMODE = (int) force_number(BINMODE_node->var_value);
2207
2227
#else
2208
2228
        static const char float_formats[] = "efgEFG";
2209
2229
#endif
2210
 
#if ENABLE_NLS && defined(HAVE_LOCALE_H)
 
2230
#if defined(HAVE_LOCALE_H)
2211
2231
        static const char flags[] = " +-#'";
2212
2232
#else
2213
2233
        static const char flags[] = " +-#";
2369
2389
        return *lhs_p;
2370
2390
}
2371
2391
 
2372
 
/* update_ERRNO --- update the value of ERRNO */
 
2392
/* update_ERRNO_saved --- update the value of ERRNO based on argument */
2373
2393
 
2374
2394
void
2375
 
update_ERRNO()
 
2395
update_ERRNO_saved(int errcode)
2376
2396
{
2377
2397
        char *cp;
2378
2398
 
2379
 
        cp = strerror(errno);
 
2399
        cp = strerror(errcode);
2380
2400
        cp = gettext(cp);
2381
2401
        unref(ERRNO_node->var_value);
2382
2402
        ERRNO_node->var_value = make_string(cp, strlen(cp));
2383
2403
}
2384
2404
 
 
2405
/* update_ERRNO --- update the value of ERRNO based on errno */
 
2406
 
 
2407
void
 
2408
update_ERRNO()
 
2409
{
 
2410
        update_ERRNO_saved(errno);
 
2411
}
 
2412
 
2385
2413
/* comp_func --- array index comparison function for qsort */
2386
2414
 
2387
2415
static int