Main Page | Class List | Directories | File List | Class Members | File Members

builtin.c File Reference

#include "awk.h"
#include <math.h>
#include "random.h"

Go to the source code of this file.

Defines

#define CHAR_BIT   8
#define TYPE_SIGNED(t)   (! ((t) 0 < (t) -1))
#define TYPE_MINIMUM(t)
#define TYPE_MAXIMUM(t)   ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
#define INTMAX_MIN   TYPE_MINIMUM (intmax_t)
#define UINTMAX_MAX   TYPE_MAXIMUM (uintmax_t)
#define SIZE_MAX   ((size_t) -1)
#define Floor(n)   floor(n)
#define Ceil(n)   ceil(n)
#define DEFAULT_G_PRECISION   6
#define GAWK_RANDOM_MAX   0x7fffffffL
#define bchunk(s, l)
#define bchunk_one(s)
#define chksize(l)
#define INITIAL_OUT_SIZE   512
#define parse_next_arg()

Functions

char *initstate P ((unsigned long seed, char *state, long n))
static void efwrite (const void *ptr, size_t size, size_t count, FILE *fp, const char *from, struct redirect *rp, int flush)
NODEdo_exp (NODE *tree)
static FILE * stdfile (const char *name, size_t len)
NODEdo_fflush (NODE *tree)
NODEdo_index (NODE *tree)
double double_to_int (double d)
NODEdo_int (NODE *tree)
NODEdo_length (NODE *tree)
NODEdo_log (NODE *tree)
NODEformat_tree (const char *fmt_string, size_t n0, register NODE *carg, long num_args)
NODEdo_sprintf (NODE *tree)
static FILE * redirect_to_fp (NODE *tree, struct redirect **rpp)
void do_printf (NODE *tree)
NODEdo_sqrt (NODE *tree)
NODEdo_substr (NODE *tree)
NODEdo_strftime (NODE *tree)
NODEdo_systime (NODE *tree ATTRIBUTE_UNUSED)
NODEdo_mktime (NODE *tree)
NODEdo_system (NODE *tree)
void do_print (register NODE *tree)
void do_print_rec (register NODE *tree)
NODEdo_tolower (NODE *tree)
NODEdo_toupper (NODE *tree)
NODEdo_atan2 (NODE *tree)
NODEdo_sin (NODE *tree)
NODEdo_cos (NODE *tree)
NODEdo_rand (NODE *tree ATTRIBUTE_UNUSED)
NODEdo_srand (NODE *tree)
NODEdo_match (NODE *tree)
static NODEsub_common (NODE *tree, long how_many, int backdigs)
NODEdo_gsub (NODE *tree)
NODEdo_sub (NODE *tree)
NODEdo_gensub (NODE *tree)
NODEdo_lshift (NODE *tree)
NODEdo_rshift (NODE *tree)
NODEdo_and (NODE *tree)
NODEdo_or (NODE *tree)
NODEdo_xor (NODE *tree)
NODEdo_compl (NODE *tree)
NODEdo_strtonum (NODE *tree)
AWKNUM nondec2awknum (char *str, size_t len)
NODEdo_dcgettext (NODE *tree)
NODEdo_dcngettext (NODE *tree)
NODEdo_bindtextdomain (NODE *tree)

Variables

NODE ** fields_arr
int output_is_tty
NODE ** fmt_list
static int firstrand = TRUE
static char state [512]


Define Documentation

#define bchunk s,
 ) 
 

Value:

if (l) { \
        while ((l) > ofre) { \
                long olen = obufout - obuf; \
                erealloc(obuf, char *, osiz * 2, "format_tree"); \
                ofre += osiz; \
                osiz *= 2; \
                obufout = obuf + olen; \
        } \
        memcpy(obufout, s, (size_t) (l)); \
        obufout += (l); \
        ofre -= (l); \
}

Referenced by format_tree().

#define bchunk_one  ) 
 

Value:

{ \
        if (ofre < 1) { \
                long olen = obufout - obuf; \
                erealloc(obuf, char *, osiz * 2, "format_tree"); \
                ofre += osiz; \
                osiz *= 2; \
                obufout = obuf + olen; \
        } \
        *obufout++ = *s; \
        --ofre; \
}

Referenced by format_tree().

#define Ceil n   )     ceil(n)
 

Definition at line 93 of file builtin.c.

Referenced by double_to_int().

#define CHAR_BIT   8
 

Definition at line 45 of file builtin.c.

Referenced by do_lshift(), and do_rshift().

#define chksize  ) 
 

Value:

if ((l) > ofre) { \
        long olen = obufout - obuf; \
        erealloc(obuf, char *, osiz * 2, "format_tree"); \
        obufout = obuf + olen; \
        ofre += osiz; \
        osiz *= 2; \
}

Referenced by format_tree().

#define DEFAULT_G_PRECISION   6
 

Definition at line 96 of file builtin.c.

Referenced by format_tree().

#define Floor n   )     floor(n)
 

Definition at line 92 of file builtin.c.

Referenced by double_to_int().

#define GAWK_RANDOM_MAX   0x7fffffffL
 

Definition at line 108 of file builtin.c.

Referenced by do_rand().

#define INITIAL_OUT_SIZE   512
 

Referenced by format_tree().

#define INTMAX_MIN   TYPE_MINIMUM (intmax_t)
 

Definition at line 57 of file builtin.c.

Referenced by format_tree().

 
#define parse_next_arg  ) 
 

Value:

{ \
        if (argnum > 0) { \
                if (cur_arg > 1) \
                        fatal(_("must use `count$' on all formats or none")); \
                arg = the_args[argnum]; \
        } else if (used_dollar) { \
                fatal(_("must use `count$' on all formats or none")); \
                arg = 0; /* shutup the compiler */ \
        } else if (cur_arg >= num_args) { \
                arg = 0; /* shutup the compiler */ \
                toofew = TRUE; \
                break; \
        } else { \
                arg = the_args[cur_arg]; \
                cur_arg++; \
        } \
}

Referenced by format_tree().

#define SIZE_MAX   ((size_t) -1)
 

Definition at line 64 of file builtin.c.

Referenced by do_substr().

#define TYPE_MAXIMUM  )     ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
 

Definition at line 54 of file builtin.c.

#define TYPE_MINIMUM  ) 
 

Value:

((t) (TYPE_SIGNED (t) \
                              ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))

Definition at line 52 of file builtin.c.

#define TYPE_SIGNED  )     (! ((t) 0 < (t) -1))
 

Definition at line 49 of file builtin.c.

#define UINTMAX_MAX   TYPE_MAXIMUM (uintmax_t)
 

Definition at line 60 of file builtin.c.

Referenced by format_tree().


Function Documentation

NODE* do_and NODE tree  ) 
 

Definition at line 2477 of file builtin.c.

References _, AWKNUM, do_lint, double_to_int(), exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, tree_eval, and uintmax_t.

02478 {
02479         NODE *s1, *s2;
02480         uintmax_t uleft, uright, res;
02481         AWKNUM left, right;
02482 
02483         s1 = tree_eval(tree->lnode);
02484         s2 = tree_eval(tree->rnode->lnode);
02485         left = force_number(s1);
02486         right = force_number(s2);
02487 
02488         if (do_lint) {
02489                 if ((s1->flags & (NUMCUR|NUMBER)) == 0)
02490                         lintwarn(_("and: received non-numeric first argument"));
02491                 if ((s2->flags & (NUMCUR|NUMBER)) == 0)
02492                         lintwarn(_("and: received non-numeric first argument"));
02493                 if (left < 0 || right < 0)
02494                         lintwarn(_("and(%lf, %lf): negative values will give strange results"), left, right);
02495                 if (double_to_int(left) != left || double_to_int(right) != right)
02496                         lintwarn(_("and(%lf, %lf): fractional values will be truncated"), left, right);
02497         }
02498 
02499         free_temp(s1);
02500         free_temp(s2);
02501 
02502         uleft = (uintmax_t) left;
02503         uright = (uintmax_t) right;
02504 
02505         res = uleft & uright;
02506         return tmp_number((AWKNUM) res);
02507 }

NODE* do_atan2 NODE tree  ) 
 

Definition at line 1693 of file builtin.c.

References _, AWKNUM, do_lint, exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, and tree_eval.

01694 {
01695         NODE *t1, *t2;
01696         double d1, d2;
01697 
01698         t1 = tree_eval(tree->lnode);
01699         t2 = tree_eval(tree->rnode->lnode);
01700         if (do_lint) {
01701                 if ((t1->flags & (NUMCUR|NUMBER)) == 0)
01702                         lintwarn(_("atan2: received non-numeric first argument"));
01703                 if ((t2->flags & (NUMCUR|NUMBER)) == 0)
01704                         lintwarn(_("atan2: received non-numeric second argument"));
01705         }
01706         d1 = force_number(t1);
01707         d2 = force_number(t2);
01708         free_temp(t1);
01709         free_temp(t2);
01710         return tmp_number((AWKNUM) atan2(d1, d2));
01711 }

NODE* do_bindtextdomain NODE tree  ) 
 

Definition at line 2893 of file builtin.c.

References bindtextdomain, force_string, free_temp, NULL, TEXTDOMAIN, tmp_string(), and tree_eval.

02894 {
02895         NODE *tmp, *t1, *t2;
02896         char *directory, *domain;
02897         char *the_result;
02898 
02899         t1 = t2 = NULL;
02900         /* set defaults */
02901         directory = NULL;
02902         domain = TEXTDOMAIN;
02903 
02904         tmp = tree->lnode;      /* first argument */
02905         t1 = force_string(tree_eval(tmp));
02906         if (t1->stlen > 0)
02907                 directory = t1->stptr;
02908 
02909         tree = tree->rnode;     /* second argument */
02910         if (tree != NULL) {
02911                 tmp = tree->lnode;
02912                 t2 = force_string(tree_eval(tmp));
02913                 domain = t2->stptr;
02914         }
02915 
02916         the_result = bindtextdomain(domain, directory);
02917 
02918         free_temp(t1);
02919         if (t2 != NULL)
02920                 free_temp(t2);
02921 
02922         return tmp_string(the_result, strlen(the_result));
02923 }

NODE* do_compl NODE tree  ) 
 

Definition at line 2582 of file builtin.c.

References _, AWKNUM, do_lint, double_to_int(), exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, tree_eval, and uintmax_t.

02583 {
02584         NODE *tmp;
02585         double d;
02586         uintmax_t uval;
02587 
02588         tmp = tree_eval(tree->lnode);
02589         d = force_number(tmp);
02590         free_temp(tmp);
02591 
02592         if (do_lint) {
02593                 if ((tmp->flags & (NUMCUR|NUMBER)) == 0)
02594                         lintwarn(_("compl: received non-numeric argument"));
02595                 if (d < 0)
02596                         lintwarn(_("compl(%lf): negative value will give strange results"), d);
02597                 if (double_to_int(d) != d)
02598                         lintwarn(_("compl(%lf): fractional value will be truncated"), d);
02599         }
02600 
02601         uval = (uintmax_t) d;
02602         uval = ~ uval;
02603         return tmp_number((AWKNUM) uval);
02604 }

NODE* do_cos NODE tree  ) 
 

Definition at line 1732 of file builtin.c.

References _, AWKNUM, do_lint, exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, and tree_eval.

01733 {
01734         NODE *tmp;
01735         double d;
01736 
01737         tmp = tree_eval(tree->lnode);
01738         if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
01739                 lintwarn(_("cos: received non-numeric argument"));
01740         d = cos((double) force_number(tmp));
01741         free_temp(tmp);
01742         return tmp_number((AWKNUM) d);
01743 }

NODE* do_dcgettext NODE tree  ) 
 

Definition at line 2791 of file builtin.c.

References dcgettext, force_string, free_temp, NULL, TEXTDOMAIN, tmp_string(), and tree_eval.

Referenced by snode().

02792 {
02793         NODE *tmp, *t1, *t2;
02794         char *string;
02795         char *the_result;
02796 #if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
02797         int lc_cat;
02798         char *domain;
02799 #endif /* ENABLE_NLS */
02800 
02801         tmp = tree->lnode;      /* first argument */
02802         t1 = force_string(tree_eval(tmp));
02803         string = t1->stptr;
02804 
02805         t2 = NULL;
02806 #if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
02807         tree = tree->rnode;     /* second argument */
02808         if (tree != NULL) {
02809                 tmp = tree->lnode;
02810                 t2 = force_string(tree_eval(tmp));
02811                 domain = t2->stptr;
02812         } else
02813                 domain = TEXTDOMAIN;
02814 
02815         if (tree && tree->rnode != NULL) {      /* third argument */
02816                 lc_cat = localecategory_from_argument(tree->rnode);
02817         } else
02818                 lc_cat = LC_MESSAGES;
02819 
02820         the_result = dcgettext(domain, string, lc_cat);
02821 #else
02822         the_result = string;
02823 #endif
02824         free_temp(t1);
02825         if (t2 != NULL)
02826                 free_temp(t2);
02827 
02828         return tmp_string(the_result, strlen(the_result));
02829 }

NODE* do_dcngettext NODE tree  ) 
 

Definition at line 2832 of file builtin.c.

References dcngettext, double_to_int(), force_number, force_string, free_temp, NULL, TEXTDOMAIN, tmp_string(), and tree_eval.

Referenced by snode().

02833 {
02834         NODE *tmp, *t1, *t2, *t3;
02835         char *string1, *string2;
02836         unsigned long number;
02837         char *the_result;
02838 #if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
02839         int lc_cat;
02840         char *domain;
02841 #endif /* ENABLE_NLS */
02842 
02843         tmp = tree->lnode;      /* first argument */
02844         t1 = force_string(tree_eval(tmp));
02845         string1 = t1->stptr;
02846 
02847         tmp = tree->rnode->lnode;       /* second argument */
02848         t2 = force_string(tree_eval(tmp));
02849         string2 = t2->stptr;
02850 
02851         tmp = tree->rnode->rnode->lnode;        /* third argument */
02852         number = (unsigned long) double_to_int(force_number(tree_eval(tmp)));
02853 
02854         t3 = NULL;
02855 #if ENABLE_NLS && HAVE_LC_MESSAGES && HAVE_DCGETTEXT
02856         tree = tree->rnode->rnode->rnode;       /* fourth argument */
02857         if (tree != NULL) {
02858                 tmp = tree->lnode;
02859                 t3 = force_string(tree_eval(tmp));
02860                 domain = t3->stptr;
02861         } else
02862                 domain = TEXTDOMAIN;
02863 
02864         if (tree && tree->rnode != NULL) {      /* fifth argument */
02865                 lc_cat = localecategory_from_argument(tree->rnode);
02866         } else
02867                 lc_cat = LC_MESSAGES;
02868 
02869         the_result = dcngettext(domain, string1, string2, number, lc_cat);
02870 #else
02871         the_result = (number == 1 ? string1 : string2);
02872 #endif
02873         free_temp(t1);
02874         free_temp(t2);
02875         if (t3 != NULL)
02876                 free_temp(t3);
02877 
02878         return tmp_string(the_result, strlen(the_result));
02879 }

NODE* do_exp NODE tree  ) 
 

Definition at line 145 of file builtin.c.

References _, AWKNUM, do_lint, errno, exp, exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, tree_eval, and warning().

00146 {
00147         NODE *tmp;
00148         double d, res;
00149 
00150         tmp = tree_eval(tree->lnode);
00151         if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
00152                 lintwarn(_("exp: received non-numeric argument"));
00153         d = force_number(tmp);
00154         free_temp(tmp);
00155         errno = 0;
00156         res = exp(d);
00157         if (errno == ERANGE)
00158                 warning(_("exp: argument %g is out of range"), d);
00159         return tmp_number((AWKNUM) res);
00160 }

NODE* do_fflush NODE tree  ) 
 

Definition at line 186 of file builtin.c.

References _, AWKNUM, redirect::flag, flush_io(), force_string, redirect::fp, free_temp, getredirect(), NULL, RED_APPEND, RED_PIPE, RED_WRITE, redirect::status, stdfile(), tmp_number, tree_eval, and warning().

00187 {
00188         struct redirect *rp;
00189         NODE *tmp;
00190         FILE *fp;
00191         int status = 0;
00192         const char *file;
00193 
00194         /* fflush() --- flush stdout */
00195         if (tree == NULL) {
00196                 status = fflush(stdout);
00197                 return tmp_number((AWKNUM) status);
00198         }
00199 
00200         tmp = tree_eval(tree->lnode);
00201         tmp = force_string(tmp);
00202         file = tmp->stptr;
00203 
00204         /* fflush("") --- flush all */
00205         if (tmp->stlen == 0) {
00206                 status = flush_io();
00207                 free_temp(tmp);
00208                 return tmp_number((AWKNUM) status);
00209         }
00210 
00211         rp = getredirect(tmp->stptr, tmp->stlen);
00212         status = -1;
00213         if (rp != NULL) {
00214                 if ((rp->flag & (RED_WRITE|RED_APPEND)) == 0) {
00215                         if (rp->flag & RED_PIPE)
00216                                 warning(_("fflush: cannot flush: pipe `%s' opened for reading, not writing"),
00217                                         file);
00218                         else
00219                                 warning(_("fflush: cannot flush: file `%s' opened for reading, not writing"),
00220                                         file);
00221                         free_temp(tmp);
00222                         return tmp_number((AWKNUM) status);
00223                 }
00224                 fp = rp->fp;
00225                 if (fp != NULL)
00226                         status = fflush(fp);
00227         } else if ((fp = stdfile(tmp->stptr, tmp->stlen)) != NULL) {
00228                 status = fflush(fp);
00229         } else {
00230                 status = -1;
00231                 warning(_("fflush: `%s' is not an open file, pipe or co-process"), file);
00232         }
00233         free_temp(tmp);
00234         return tmp_number((AWKNUM) status);
00235 }

NODE* do_gensub NODE tree  ) 
 

Definition at line 2260 of file builtin.c.

References _, exp_node::flags, force_number, force_string, free_temp, LONG_MAX, make_string, STRCUR, STRING, sub_common(), TEMP, tree_eval, TRUE, and warning().

Referenced by snode().

02261 {
02262         NODE n1, n2, n3, *t, *tmp, *target, *ret;
02263         long how_many = 1;      /* default is one substitution */
02264         double d;
02265 
02266         /*
02267          * We have to pull out the value of the global flag, and
02268          * build up a tree without the flag in it, turning it into the
02269          * kind of tree that sub_common() expects.  It helps to draw
02270          * a picture of this ...
02271          */
02272         n1 = *tree;
02273         n2 = *(tree->rnode);
02274         n1.rnode = & n2;
02275 
02276         t = tree_eval(n2.rnode->lnode); /* value of global flag */
02277 
02278         tmp = force_string(tree_eval(n2.rnode->rnode->lnode));  /* target */
02279 
02280         /*
02281          * We make copy of the original target string, and pass that
02282          * in to sub_common() as the target to make the substitution in.
02283          * We will then return the result string as the return value of
02284          * this function.
02285          */
02286         target = make_string(tmp->stptr, tmp->stlen);
02287         free_temp(tmp);
02288 
02289         n3 = *(n2.rnode->rnode);
02290         n3.lnode = target;
02291         n2.rnode = & n3;
02292 
02293         if ((t->flags & (STRCUR|STRING)) != 0) {
02294                 if (t->stlen > 0 && (t->stptr[0] == 'g' || t->stptr[0] == 'G'))
02295                         how_many = -1;
02296                 else
02297                         how_many = 1;
02298         } else {
02299                 d = force_number(t);
02300                 if (d < 1)
02301                         how_many = 1;
02302                 else if (d < LONG_MAX)
02303                         how_many = d;
02304                 else
02305                         how_many = LONG_MAX;
02306                 if (d == 0)
02307                         warning(_("gensub: third argument of 0 treated as 1"));
02308         }
02309 
02310         free_temp(t);
02311 
02312         ret = sub_common(&n1, how_many, TRUE);
02313         free_temp(ret);
02314 
02315         /*
02316          * Note that we don't care what sub_common() returns, since the
02317          * easiest thing for the programmer is to return the string, even
02318          * if no substitutions were done.
02319          */
02320         target->flags |= TEMP;
02321         return target;
02322 }

NODE* do_gsub NODE tree  ) 
 

Definition at line 2244 of file builtin.c.

References FALSE, and sub_common().

Referenced by snode().

02245 {
02246         return sub_common(tree, -1, FALSE);
02247 }

NODE* do_index NODE tree  ) 
 

Definition at line 305 of file builtin.c.

References _, AWKNUM, casetable, do_lint, exp_node::flags, force_string, free_temp, IGNORECASE, lintwarn, memset(), STRCUR, STREQN, STRING, strncasecmp, tmp_number, and tree_eval.

00306 {
00307         NODE *s1, *s2;
00308         register const char *p1, *p2;
00309         register size_t l1, l2;
00310         long ret;
00311 #ifdef MBS_SUPPORT
00312         size_t mbclen = 0;
00313         mbstate_t mbs1, mbs2;
00314         if (gawk_mb_cur_max > 1) {
00315                 memset(&mbs1, 0, sizeof(mbstate_t));
00316                 memset(&mbs2, 0, sizeof(mbstate_t));
00317         }
00318 #endif
00319 
00320 
00321         s1 = tree_eval(tree->lnode);
00322         s2 = tree_eval(tree->rnode->lnode);
00323         if (do_lint) {
00324                 if ((s1->flags & (STRING|STRCUR)) == 0)
00325                         lintwarn(_("index: received non-string first argument"));
00326                 if ((s2->flags & (STRING|STRCUR)) == 0)
00327                         lintwarn(_("index: received non-string second argument"));
00328         }
00329         force_string(s1);
00330         force_string(s2);
00331         p1 = s1->stptr;
00332         p2 = s2->stptr;
00333         l1 = s1->stlen;
00334         l2 = s2->stlen;
00335         ret = 0;
00336 
00337         /*
00338          * Icky special case, index(foo, "") should return 1,
00339          * since both bwk awk and mawk do, and since match("foo", "")
00340          * returns 1. This makes index("", "") work, too, fwiw.
00341          */
00342         if (l2 == 0) {
00343                 ret = 1;
00344                 goto out;
00345         }
00346 
00347         /* IGNORECASE will already be false if posix */
00348         if (IGNORECASE) {
00349                 while (l1 > 0) {
00350                         if (l2 > l1)
00351                                 break;
00352 #ifdef MBS_SUPPORT
00353                         if (gawk_mb_cur_max > 1) {
00354                                 if (strncasecmpmbs(p1, mbs1, p2, mbs2, l2) == 0) {
00355                                         ret = 1 + s1->stlen - l1;
00356                                         break;
00357                                 }
00358                                 /* Update l1, and p1.  */
00359                                 mbclen = mbrlen(p1, l1, &mbs1);
00360                                 if ((mbclen == 1) || (mbclen == (size_t) -1)
00361                                         || (mbclen == (size_t) -2) || (mbclen == 0)) {
00362                                         /* We treat it as a singlebyte character.  */
00363                                         mbclen = 1;
00364                                 }
00365                                 l1 -= mbclen;
00366                                 p1 += mbclen;
00367                         } else {
00368 #endif
00369                         if (casetable[(unsigned char)*p1] == casetable[(unsigned char)*p2]
00370                             && (l2 == 1 || strncasecmp(p1, p2, l2) == 0)) {
00371                                 ret = 1 + s1->stlen - l1;
00372                                 break;
00373                         }
00374                         l1--;
00375                         p1++;
00376 #ifdef MBS_SUPPORT
00377                         }
00378 #endif
00379                 }
00380         } else {
00381                 while (l1 > 0) {
00382                         if (l2 > l1)
00383                                 break;
00384                         if (*p1 == *p2
00385                             && (l2 == 1 || STREQN(p1, p2, l2))) {
00386                                 ret = 1 + s1->stlen - l1;
00387                                 break;
00388                         }
00389 #ifdef MBS_SUPPORT
00390                         if (gawk_mb_cur_max > 1) {
00391                                 mbclen = mbrlen(p1, l1, &mbs1);
00392                                 if ((mbclen == 1) || (mbclen == (size_t) -1) ||
00393                                         (mbclen == (size_t) -2) || (mbclen == 0)) {
00394                                         /* We treat it as a singlebyte character.  */
00395                                         mbclen = 1;
00396                                 }
00397                                 l1 -= mbclen;
00398                                 p1 += mbclen;
00399                         } else {
00400                                 l1--;
00401                                 p1++;
00402                         }
00403 #else
00404                         l1--;
00405                         p1++;
00406 #endif
00407                 }
00408         }
00409 out:
00410         free_temp(s1);
00411         free_temp(s2);
00412         return tmp_number((AWKNUM) ret);
00413 }

NODE* do_int NODE tree  ) 
 

Definition at line 430 of file builtin.c.

References _, AWKNUM, do_lint, double_to_int(), exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, and tree_eval.

00431 {
00432         NODE *tmp;
00433         double d;
00434 
00435         tmp = tree_eval(tree->lnode);
00436         if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
00437                 lintwarn(_("int: received non-numeric argument"));
00438         d = force_number(tmp);
00439         d = double_to_int(d);
00440         free_temp(tmp);
00441         return tmp_number((AWKNUM) d);
00442 }

NODE* do_length NODE tree  ) 
 

Definition at line 447 of file builtin.c.

References _, AWKNUM, do_lint, exp_node::flags, force_string, free_temp, lintwarn, STRCUR, STRING, tmp_number, and tree_eval.

Referenced by snode().

00448 {
00449         NODE *tmp;
00450         size_t len;
00451 
00452         tmp = tree_eval(tree->lnode);
00453         if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
00454                 lintwarn(_("length: received non-string argument"));
00455         len = force_string(tmp)->stlen;
00456         free_temp(tmp);
00457         return tmp_number((AWKNUM) len);
00458 }

NODE* do_log NODE tree  ) 
 

Definition at line 463 of file builtin.c.

References _, AWKNUM, do_lint, exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, tree_eval, and warning().

00464 {
00465         NODE *tmp;
00466         double d, arg;
00467 
00468         tmp = tree_eval(tree->lnode);
00469         if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
00470                 lintwarn(_("log: received non-numeric argument"));
00471         arg = (double) force_number(tmp);
00472         if (arg < 0.0)
00473                 warning(_("log: received negative argument %g"), arg);
00474         d = log(arg);
00475         free_temp(tmp);
00476         return tmp_number((AWKNUM) d);
00477 }

NODE* do_lshift NODE tree  ) 
 

Definition at line 2403 of file builtin.c.

References _, AWKNUM, CHAR_BIT, do_lint, double_to_int(), exp_node::flags, force_number, free_temp, lintwarn, NUMBER, NUMCUR, tmp_number, tree_eval, and uintmax_t.

02404 {
02405         NODE *s1, *s2;
02406         uintmax_t uval, ushift, res;
02407         AWKNUM val, shift;
02408 
02409         s1 = tree_eval(tree->lnode);
02410         s2 = tree_eval(tree->rnode->lnode);
02411         val = force_number(s1);
02412         shift = force_number(s2);
02413 
02414         if (do_lint) {
02415                 if ((s1->flags & (NUMCUR|NUMBER)) == 0)
02416                         lintwarn(_("lshift: received non-numeric first argument"));
02417                 if ((s2->flags & (NUMCUR|NUMBER)) == 0)
02418                         lintwarn(_("lshift: received non-numeric first argument"));
02419                 if (val < 0 || shift < 0)
02420                         lintwarn(_("lshift(%lf, %lf): negative values will give strange results"), val, shift);
02421                 if (double_to_int(val) != val || double_to_int(shift) != shift)
02422                         lintwarn(_("lshift(%lf, %lf): fractional values will be truncated"), val, shift);
02423                 if (shift >= sizeof(uintmax_t) * CHAR_BIT)
02424                         lintwarn(_("lshift(%lf, %lf): too large shift value will give strange results"), val, shift);
02425         }
02426 
02427         free_temp(s1);
02428         free_temp(s2);
02429 
02430         uval = (uintmax_t) val;
02431         ushift = (uintmax_t) shift;
02432 
02433         res = uval << ushift;
02434         return tmp_number((AWKNUM) res);
02435 }

NODE* do_match NODE tree  ) 
 

Definition at line 1801 of file builtin.c.

References _, assoc_clear(), assoc_lookup(), AWKNUM, emalloc, erealloc, FALSE, fatal, force_string, free(), free_temp, get_param, make_number, make_string, memcpy, Node_var_array, NULL, re_update(), REEND, research(), RESTART, RLENGTH_node, RSTART_node, stptr, SUBPATEND, SUBPATSTART, SUBSEP_node, tmp_number, tmp_string(), tree_eval, TRUE, exp_node::type, and unref().

Referenced by snode().

01802 {
01803         NODE *t1, *dest, *it;
01804         int rstart, len, ii;
01805         AWKNUM rlength;
01806         Regexp *rp;
01807         regoff_t s;
01808         char *start;
01809         char *buf = NULL;
01810         char buff[100];
01811         size_t amt, oldamt = 0, ilen, slen;
01812         char *subsepstr;
01813         size_t subseplen;
01814 
01815         t1 = force_string(tree_eval(tree->lnode));
01816         tree = tree->rnode;
01817         rp = re_update(tree->lnode);
01818 
01819         dest = NULL;
01820         if (tree->rnode != NULL) {      /* 3rd optional arg for the subpatterns */
01821                 dest = get_param(tree->rnode->lnode);
01822                 if (dest->type != Node_var_array)
01823                         fatal(_("match: third argument is not an array"));
01824 
01825                 assoc_clear(dest);
01826         }
01827         
01828         rstart = research(rp, t1->stptr, 0, t1->stlen, TRUE);
01829         if (rstart >= 0) {      /* match succeded */
01830                 rstart++;       /* 1-based indexing */
01831                 rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr);
01832         
01833                 /* Build the array only if the caller wants the optional subpatterns */
01834                 if (dest != NULL) {
01835                         subsepstr = SUBSEP_node->var_value->stptr;
01836                         subseplen = SUBSEP_node->var_value->stlen;
01837 
01838                         for (ii = 0; ii < NUMSUBPATS(rp, t1->stptr); ii++) {
01839                                 /*
01840                                  * Loop over all the subpats; some of them may have
01841                                  * matched even if all of them did not.
01842                                  */
01843                                 if ((s = SUBPATSTART(rp, t1->stptr, ii)) != -1) {
01844                                         start = t1->stptr + s;
01845                                         len = SUBPATEND(rp, t1->stptr, ii) - s;
01846         
01847                                         it = make_string(start, len);
01848                                         /*
01849                                          * assoc_lookup() does free_temp() on 2nd arg.
01850                                          */
01851                                         *assoc_lookup(dest, tmp_number((AWKNUM) (ii)), FALSE) = it;
01852         
01853                                         sprintf(buff, "%d", ii);
01854                                         ilen = strlen(buff);
01855                                         amt = ilen + subseplen + strlen("length") + 2;
01856         
01857                                         if (oldamt == 0) {
01858                                                 emalloc(buf, char *, amt, "do_match");
01859                                         } else if (amt > oldamt) {
01860                                                 erealloc(buf, char *, amt, "do_match");
01861                                         }
01862                                         oldamt = amt;
01863                                         memcpy(buf, buff, ilen);
01864                                         memcpy(buf + ilen, subsepstr, subseplen);
01865                                         memcpy(buf + ilen + subseplen, "start", 6);
01866         
0186