home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnuawk.zip / eval.c < prev    next >
C/C++ Source or Header  |  1997-05-06  |  43KB  |  1,721 lines

  1. /*
  2.  * eval.c - gawk parse tree interpreter 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Programming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  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
  24.  */
  25.  
  26. #include "awk.h"
  27.  
  28. #include <assert.h>
  29.  
  30. extern double pow P((double x, double y));
  31. extern double modf P((double x, double *yp));
  32. extern double fmod P((double x, double y));
  33.  
  34. static int eval_condition P((NODE *tree));
  35. static NODE *op_assign P((NODE *tree));
  36. static NODE *func_call P((NODE *name, NODE *arg_list));
  37. static NODE *match_op P((NODE *tree));
  38. static void push_args P((int count, NODE *arglist, NODE **oldstack, char *func_name));
  39. static void pop_fcall_stack P((void));
  40. static void pop_fcall P((void));
  41. static int in_function P((void));
  42. char *nodetype2str P((NODETYPE type));
  43. char *flags2str P((int flagval));
  44.  
  45. #if __GNUC__ < 2
  46. NODE *_t;        /* used as a temporary in macros */
  47. #endif
  48. #ifdef MSDOS
  49. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  50. #endif
  51. NODE *ret_node;
  52. int OFSlen;
  53. int ORSlen;
  54. int OFMTidx;
  55. int CONVFMTidx;
  56.  
  57. /* Macros and variables to save and restore function and loop bindings */
  58. /*
  59.  * the val variable allows return/continue/break-out-of-context to be
  60.  * caught and diagnosed
  61.  */
  62. #define PUSH_BINDING(stack, x, val) (memcpy((char *)(stack), (char *)(x), sizeof(jmp_buf)), val++)
  63. #define RESTORE_BINDING(stack, x, val) (memcpy((char *)(x), (char *)(stack), sizeof(jmp_buf)), val--)
  64.  
  65. static jmp_buf loop_tag;        /* always the current binding */
  66. static int loop_tag_valid = FALSE;    /* nonzero when loop_tag valid */
  67. static int func_tag_valid = FALSE;
  68. static jmp_buf func_tag;
  69. extern int exiting, exit_val;
  70.  
  71. /*
  72.  * This table is used by the regexp routines to do case independant
  73.  * matching. Basically, every ascii character maps to itself, except
  74.  * uppercase letters map to lower case ones. This table has 256
  75.  * entries, for ISO 8859-1. Note also that if the system this
  76.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  77.  * defined to the linker, so gawk should not load.
  78.  *
  79.  * Do NOT make this array static, it is used in several spots, not
  80.  * just in this file.
  81.  */
  82. #if 'a' == 97    /* it's ascii */
  83. char casetable[] = {
  84.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  85.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  86.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  87.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  88.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  89.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  90.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  91.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  92.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  93.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  94.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  95.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  96.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  97.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  98.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  99.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  100.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  101.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  102.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  103.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  104.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  105.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  106.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  107.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  108.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  109.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  110.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  111.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  112. #ifndef USE_PURE_ASCII
  113.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  114.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  115.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  116.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  117.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  118.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  119.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  120.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  121.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  122.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  123.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327',
  124.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337',
  125.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  126.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  127.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  128.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  129. #else
  130.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  131.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  132.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  133.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  134.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  135.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  136.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  137.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  138.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  139.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  140.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  141.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  142.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  143.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  144.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  145.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  146. #endif
  147. };
  148. #else
  149. #include "You lose. You will need a translation table for your character set."
  150. #endif
  151.  
  152. /*
  153.  * This table maps node types to strings for debugging.
  154.  * KEEP IN SYNC WITH awk.h!!!!
  155.  */
  156. static char *nodetypes[] = {
  157.     "Node_illegal",
  158.     "Node_times",
  159.     "Node_quotient",
  160.     "Node_mod",
  161.     "Node_plus",
  162.     "Node_minus",
  163.     "Node_cond_pair",
  164.     "Node_subscript",
  165.     "Node_concat",
  166.     "Node_exp",
  167.     "Node_preincrement",
  168.     "Node_predecrement",
  169.     "Node_postincrement",
  170.     "Node_postdecrement",
  171.     "Node_unary_minus",
  172.     "Node_field_spec",
  173.     "Node_assign",
  174.     "Node_assign_times",
  175.     "Node_assign_quotient",
  176.     "Node_assign_mod",
  177.     "Node_assign_plus",
  178.     "Node_assign_minus",
  179.     "Node_assign_exp",
  180.     "Node_and",
  181.     "Node_or",
  182.     "Node_equal",
  183.     "Node_notequal",
  184.     "Node_less",
  185.     "Node_greater",
  186.     "Node_leq",
  187.     "Node_geq",
  188.     "Node_match",
  189.     "Node_nomatch",
  190.     "Node_not",
  191.     "Node_rule_list",
  192.     "Node_rule_node",
  193.     "Node_statement_list",
  194.     "Node_if_branches",
  195.     "Node_expression_list",
  196.     "Node_param_list",
  197.     "Node_K_if",
  198.     "Node_K_while",    
  199.     "Node_K_for",
  200.     "Node_K_arrayfor",
  201.     "Node_K_break",
  202.     "Node_K_continue",
  203.     "Node_K_print",
  204.     "Node_K_printf",
  205.     "Node_K_next",
  206.     "Node_K_exit",
  207.     "Node_K_do",
  208.     "Node_K_return",
  209.     "Node_K_delete",
  210.     "Node_K_getline",
  211.     "Node_K_function",
  212.     "Node_K_nextfile",
  213.     "Node_redirect_output",
  214.     "Node_redirect_append",
  215.     "Node_redirect_pipe",
  216.     "Node_redirect_pipein",
  217.     "Node_redirect_input",
  218.     "Node_var",
  219.     "Node_var_array",
  220.     "Node_val",
  221.     "Node_builtin",
  222.     "Node_line_range",
  223.     "Node_in_array",
  224.     "Node_func",
  225.     "Node_func_call",
  226.     "Node_cond_exp",
  227.     "Node_regex",
  228.     "Node_hashnode",
  229.     "Node_ahash",
  230.     "Node_NF",
  231.     "Node_NR",
  232.     "Node_FNR",
  233.     "Node_FS",
  234.     "Node_RS",
  235.     "Node_FIELDWIDTHS",
  236.     "Node_IGNORECASE",
  237.     "Node_OFS",
  238.     "Node_ORS",
  239.     "Node_OFMT",
  240.     "Node_CONVFMT",
  241.     "Node_final",
  242.     NULL
  243. };
  244.  
  245. char *
  246. nodetype2str(type)
  247. NODETYPE type;
  248. {
  249.     static char buf[40];
  250.  
  251.     if (type >= Node_illegal && type <= Node_final)
  252.         return nodetypes[(int) type];
  253.  
  254.     sprintf(buf, "unknown nodetype %d", (int) type);
  255.     return buf;
  256. }
  257.  
  258. /* flags2str --- make a flags value readable */
  259.  
  260. char *
  261. flags2str(flagval)
  262. int flagval;
  263. {
  264.     static char buffer[BUFSIZ];
  265.     char *sp;
  266.  
  267.     sp = buffer;
  268.  
  269.     if (flagval & MALLOC) {
  270.         strcpy(sp, "MALLOC");
  271.         sp += strlen(sp);
  272.     }
  273.     if (flagval & TEMP) {
  274.         if (sp != buffer)
  275.             *sp++ = '|';
  276.         strcpy(sp, "TEMP");
  277.         sp += strlen(sp);
  278.     }
  279.     if (flagval & PERM) {
  280.         if (sp != buffer)
  281.             *sp++ = '|';
  282.         strcpy(sp, "PERM");
  283.         sp += strlen(sp);
  284.     }
  285.     if (flagval & STRING) {
  286.         if (sp != buffer)
  287.             *sp++ = '|';
  288.         strcpy(sp, "STRING");
  289.         sp += strlen(sp);
  290.     }
  291.     if (flagval & STR) {
  292.         if (sp != buffer)
  293.             *sp++ = '|';
  294.         strcpy(sp, "STR");
  295.         sp += strlen(sp);
  296.     }
  297.     if (flagval & NUM) {
  298.         if (sp != buffer)
  299.             *sp++ = '|';
  300.         strcpy(sp, "NUM");
  301.         sp += strlen(sp);
  302.     }
  303.     if (flagval & NUMBER) {
  304.         if (sp != buffer)
  305.             *sp++ = '|';
  306.         strcpy(sp, "NUMBER");
  307.         sp += strlen(sp);
  308.     }
  309.     if (flagval & MAYBE_NUM) {
  310.         if (sp != buffer)
  311.             *sp++ = '|';
  312.         strcpy(sp, "MAYBE_NUM");
  313.         sp += strlen(sp);
  314.     }
  315.     if (flagval & ARRAYMAXED) {
  316.         if (sp != buffer)
  317.             *sp++ = '|';
  318.         strcpy(sp, "ARRAYMAXED");
  319.         sp += strlen(sp);
  320.     }
  321.     if (flagval & SCALAR) {
  322.         if (sp != buffer)
  323.             *sp++ = '|';
  324.         strcpy(sp, "SCALAR");
  325.         sp += strlen(sp);
  326.     }
  327.     if (flagval & FUNC) {
  328.         if (sp != buffer)
  329.             *sp++ = '|';
  330.         strcpy(sp, "FUNC");
  331.         sp += strlen(sp);
  332.     }
  333.     if (flagval & FIELD) {
  334.         if (sp != buffer)
  335.             *sp++ = '|';
  336.         strcpy(sp, "FIELD");
  337.         sp += strlen(sp);
  338.     }
  339.  
  340.     return buffer;
  341. }
  342.  
  343. /*
  344.  * interpret:
  345.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  346.  * statement 
  347.  */
  348. int
  349. interpret(tree)
  350. register NODE *volatile tree;
  351. {
  352.     jmp_buf volatile loop_tag_stack; /* shallow binding stack for loop_tag */
  353.     static jmp_buf rule_tag; /* tag the rule currently being run, for NEXT
  354.                   * and EXIT statements.  It is static because
  355.                   * there are no nested rules */
  356.     register NODE *volatile t = NULL;    /* temporary */
  357.     NODE **volatile lhs;    /* lhs == Left Hand Side for assigns, etc */
  358.     NODE *volatile stable_tree;
  359.     int volatile traverse = TRUE;    /* True => loop thru tree (Node_rule_list) */
  360.  
  361.     /* avoid false source indications */
  362.     source = NULL;
  363.     sourceline = 0;
  364.  
  365.     if (tree == NULL)
  366.         return 1;
  367.     sourceline = tree->source_line;
  368.     source = tree->source_file;
  369.     switch (tree->type) {
  370.     case Node_rule_node:
  371.         traverse = FALSE;  /* False => one for-loop iteration only */
  372.         /* FALL THROUGH */
  373.     case Node_rule_list:
  374.         for (t = tree; t != NULL; t = t->rnode) {
  375.             if (traverse)
  376.                 tree = t->lnode;
  377.             sourceline = tree->source_line;
  378.             source = tree->source_file;
  379.             switch (setjmp(rule_tag)) {
  380.             case 0:    /* normal non-jump */
  381.                 /* test pattern, if any */
  382.                 if (tree->lnode == NULL ||
  383.                     eval_condition(tree->lnode))
  384.                     (void) interpret(tree->rnode);
  385.                 break;
  386.             case TAG_CONTINUE:    /* NEXT statement */
  387.                 return 1;
  388.             case TAG_BREAK:
  389.                 return 0;
  390.             default:
  391.                 cant_happen();
  392.             }
  393.             if (! traverse)     /* case Node_rule_node */
  394.                 break;        /* don't loop */
  395.         }
  396.         break;
  397.  
  398.     case Node_statement_list:
  399.         for (t = tree; t != NULL; t = t->rnode)
  400.             (void) interpret(t->lnode);
  401.         break;
  402.  
  403.     case Node_K_if:
  404.         if (eval_condition(tree->lnode))
  405.             (void) interpret(tree->rnode->lnode);
  406.         else
  407.             (void) interpret(tree->rnode->rnode);
  408.         break;
  409.  
  410.     case Node_K_while:
  411.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  412.  
  413.         stable_tree = tree;
  414.         while (eval_condition(stable_tree->lnode)) {
  415.             switch (setjmp(loop_tag)) {
  416.             case 0:    /* normal non-jump */
  417.                 (void) interpret(stable_tree->rnode);
  418.                 break;
  419.             case TAG_CONTINUE:    /* continue statement */
  420.                 break;
  421.             case TAG_BREAK:    /* break statement */
  422.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  423.                 return 1;
  424.             default:
  425.                 cant_happen();
  426.             }
  427.         }
  428.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  429.         break;
  430.  
  431.     case Node_K_do:
  432.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  433.         stable_tree = tree;
  434.         do {
  435.             switch (setjmp(loop_tag)) {
  436.             case 0:    /* normal non-jump */
  437.                 (void) interpret(stable_tree->rnode);
  438.                 break;
  439.             case TAG_CONTINUE:    /* continue statement */
  440.                 break;
  441.             case TAG_BREAK:    /* break statement */
  442.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  443.                 return 1;
  444.             default:
  445.                 cant_happen();
  446.             }
  447.         } while (eval_condition(stable_tree->lnode));
  448.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  449.         break;
  450.  
  451.     case Node_K_for:
  452.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  453.         (void) interpret(tree->forloop->init);
  454.         stable_tree = tree;
  455.         while (eval_condition(stable_tree->forloop->cond)) {
  456.             switch (setjmp(loop_tag)) {
  457.             case 0:    /* normal non-jump */
  458.                 (void) interpret(stable_tree->lnode);
  459.                 /* fall through */
  460.             case TAG_CONTINUE:    /* continue statement */
  461.                 (void) interpret(stable_tree->forloop->incr);
  462.                 break;
  463.             case TAG_BREAK:    /* break statement */
  464.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  465.                 return 1;
  466.             default:
  467.                 cant_happen();
  468.             }
  469.         }
  470.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  471.         break;
  472.  
  473.     case Node_K_arrayfor:
  474.         {
  475.         volatile struct search l;    /* For array_for */
  476.         Func_ptr after_assign = NULL;
  477.  
  478. #define hakvar forloop->init
  479. #define arrvar forloop->incr
  480.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  481.         lhs = get_lhs(tree->hakvar, &after_assign);
  482.         t = tree->arrvar;
  483.         if (t->type == Node_param_list)
  484.             t = stack_ptr[t->param_cnt];
  485.         stable_tree = tree;
  486.         if ((t->flags & SCALAR) != 0)
  487.             fatal("attempt to use scalar as array");
  488.         for (assoc_scan(t, (struct search *)&l);
  489.              l.retval;
  490.              assoc_next((struct search *)&l)) {
  491.             unref(*((NODE **) lhs));
  492.             *lhs = dupnode(l.retval);
  493.             if (after_assign)
  494.                 (*after_assign)();
  495.             switch (setjmp(loop_tag)) {
  496.             case 0:
  497.                 (void) interpret(stable_tree->lnode);
  498.             case TAG_CONTINUE:
  499.                 break;
  500.  
  501.             case TAG_BREAK:
  502.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  503.                 return 1;
  504.             default:
  505.                 cant_happen();
  506.             }
  507.         }
  508.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  509.         break;
  510.         }
  511.  
  512.     case Node_K_break:
  513.         if (! loop_tag_valid) {
  514.             /*
  515.              * Old AT&T nawk treats break outside of loops like
  516.              * next. New ones catch it at parse time. Allow it if
  517.              * do_traditional is on, and complain if lint.
  518.              */
  519.             static int warned = FALSE;
  520.  
  521.             if (do_lint && ! warned) {
  522.                 warning("use of `break' outside a loop is not portable");
  523.                 warned = TRUE;
  524.             }
  525.             if (! do_traditional || do_posix)
  526.                 fatal("use of `break' outside a loop is not allowed");
  527.             if (in_function())
  528.                 pop_fcall_stack();
  529.             longjmp(rule_tag, TAG_CONTINUE);
  530.         } else
  531.             longjmp(loop_tag, TAG_BREAK);
  532.         break;
  533.  
  534.     case Node_K_continue:
  535.         if (! loop_tag_valid) {
  536.             /*
  537.              * Old AT&T nawk treats continue outside of loops like
  538.              * next. New ones catch it at parse time. Allow it if
  539.              * do_traditional is on, and complain if lint.
  540.              */
  541.             static int warned = FALSE;
  542.  
  543.             if (do_lint && ! warned) {
  544.                 warning("use of `continue' outside a loop is not portable");
  545.                 warned = TRUE;
  546.             }
  547.             if (! do_traditional || do_posix)
  548.                 fatal("use of `continue' outside a loop is not allowed");
  549.             if (in_function())
  550.                 pop_fcall_stack();
  551.             longjmp(rule_tag, TAG_CONTINUE);
  552.         } else
  553.             longjmp(loop_tag, TAG_CONTINUE);
  554.         break;
  555.  
  556.     case Node_K_print:
  557.         do_print(tree);
  558.         break;
  559.  
  560.     case Node_K_printf:
  561.         do_printf(tree);
  562.         break;
  563.  
  564.     case Node_K_delete:
  565.         do_delete(tree->lnode, tree->rnode);
  566.         break;
  567.  
  568.     case Node_K_next:
  569.         if (in_function())
  570.             pop_fcall_stack();
  571.         longjmp(rule_tag, TAG_CONTINUE);
  572.         break;
  573.  
  574.     case Node_K_nextfile:
  575.         if (in_function())
  576.             pop_fcall_stack();
  577.         do_nextfile();
  578.         break;
  579.  
  580.     case Node_K_exit:
  581.         /*
  582.          * In A,K,&W, p. 49, it says that an exit statement "...
  583.          * causes the program to behave as if the end of input had
  584.          * occurred; no more input is read, and the END actions, if
  585.          * any are executed." This implies that the rest of the rules
  586.          * are not done. So we immediately break out of the main loop.
  587.          */
  588.         exiting = TRUE;
  589.         if (tree->lnode != NULL) {
  590.             t = tree_eval(tree->lnode);
  591.             exit_val = (int) force_number(t);
  592.             free_temp(t);
  593.         }
  594.         longjmp(rule_tag, TAG_BREAK);
  595.         break;
  596.  
  597.     case Node_K_return:
  598.         t = tree_eval(tree->lnode);
  599.         ret_node = dupnode(t);
  600.         free_temp(t);
  601.         longjmp(func_tag, TAG_RETURN);
  602.         break;
  603.  
  604.     default:
  605.         /*
  606.          * Appears to be an expression statement.  Throw away the
  607.          * value. 
  608.          */
  609.         if (do_lint && tree->type == Node_var)
  610.             warning("statement has no effect");
  611.         t = tree_eval(tree);
  612.         free_temp(t);
  613.         break;
  614.     }
  615.     return 1;
  616. }
  617.  
  618. /* r_tree_eval --- evaluate a subtree */
  619.  
  620. NODE *
  621. r_tree_eval(tree, iscond)
  622. register NODE *tree;
  623. int iscond;
  624. {
  625.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  626.     register NODE **lhs;
  627.     register int di;
  628.     AWKNUM x, x1, x2;
  629.     long lx;
  630. #ifdef _CRAY
  631.     long lx2;
  632. #endif
  633.     char namebuf[100];
  634.  
  635. #ifdef DEBUG
  636.     if (tree == NULL)
  637.         return Nnull_string;
  638.     else if (tree->type == Node_val) {
  639.         if (tree->stref <= 0)
  640.             cant_happen();
  641.         return tree;
  642.     } else if (tree->type == Node_var) {
  643.         if (tree->var_value->stref <= 0)
  644.             cant_happen();
  645.         return tree->var_value;
  646.     }
  647. #endif
  648.  
  649.     if (tree->type == Node_param_list) {
  650.         int paramnum = tree->param_cnt + 1;
  651.  
  652.         tree = stack_ptr[tree->param_cnt];
  653.         if (tree == NULL)
  654.             return Nnull_string;
  655.         sprintf(namebuf, "parameter #%d", paramnum);
  656.         tree->vname = namebuf;
  657.     }
  658.  
  659.     switch (tree->type) {
  660.     case Node_var:
  661.         return tree->var_value;
  662.  
  663.     case Node_and:
  664.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  665.                         && eval_condition(tree->rnode)));
  666.  
  667.     case Node_or:
  668.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  669.                         || eval_condition(tree->rnode)));
  670.  
  671.     case Node_not:
  672.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  673.  
  674.         /* Builtins */
  675.     case Node_builtin:
  676.         return (*tree->proc)(tree->subnode);
  677.  
  678.     case Node_K_getline:
  679.         return (do_getline(tree));
  680.  
  681.     case Node_in_array:
  682.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  683.  
  684.     case Node_func_call:
  685.         return func_call(tree->rnode, tree->lnode);
  686.  
  687.         /* unary operations */
  688.     case Node_NR:
  689.     case Node_FNR:
  690.     case Node_NF:
  691.     case Node_FIELDWIDTHS:
  692.     case Node_FS:
  693.     case Node_RS:
  694.     case Node_field_spec:
  695.     case Node_subscript:
  696.     case Node_IGNORECASE:
  697.     case Node_OFS:
  698.     case Node_ORS:
  699.     case Node_OFMT:
  700.     case Node_CONVFMT:
  701.         lhs = get_lhs(tree, (Func_ptr *) NULL);
  702.         return *lhs;
  703.  
  704.     case Node_var_array:
  705.         fatal("attempt to use array `%s' in a scalar context",
  706.             tree->vname);
  707.  
  708.     case Node_unary_minus:
  709.         t1 = tree_eval(tree->subnode);
  710.         x = -force_number(t1);
  711.         free_temp(t1);
  712.         return tmp_number(x);
  713.  
  714.     case Node_cond_exp:
  715.         if (eval_condition(tree->lnode))
  716.             return tree_eval(tree->rnode->lnode);
  717.         return tree_eval(tree->rnode->rnode);
  718.  
  719.     case Node_match:
  720.     case Node_nomatch:
  721.     case Node_regex:
  722.         return match_op(tree);
  723.  
  724.     case Node_func:
  725.         fatal("function `%s' called with space between name and (,\n%s",
  726.             tree->lnode->param,
  727.             "or used in other expression context");
  728.  
  729.         /* assignments */
  730.     case Node_assign:
  731.         {
  732.         Func_ptr after_assign = NULL;
  733.  
  734.         if (iscond && do_lint)
  735.             warning("assignment used in conditional context");
  736.         r = tree_eval(tree->rnode);
  737.         lhs = get_lhs(tree->lnode, &after_assign);
  738.         if (r != *lhs) {
  739.             NODE *save;
  740.  
  741.             save = *lhs;
  742.             *lhs = dupnode(r);
  743.             unref(save);
  744.         }
  745.         free_temp(r);
  746.         tree->lnode->flags |= SCALAR;
  747.         if (after_assign)
  748.             (*after_assign)();
  749.         return *lhs;
  750.         }
  751.  
  752.     case Node_concat:
  753.         {
  754.         NODE **treelist;
  755.         NODE **strlist;
  756.         NODE *save_tree;
  757.         register NODE **treep;
  758.         register NODE **strp;
  759.         register size_t len;
  760.         char *str;
  761.         register char *dest;
  762.         int count;
  763.  
  764.         /*
  765.          * This is an efficiency hack for multiple adjacent string
  766.          * concatenations, to avoid recursion and string copies.
  767.          *
  768.          * Node_concat trees grow downward to the left, so
  769.          * descend to lowest (first) node, accumulating nodes
  770.          * to evaluate to strings as we go.
  771.          */
  772.  
  773.         /*
  774.          * But first, no arbitrary limits. Count the number of
  775.          * nodes and malloc the treelist and strlist arrays.
  776.          * There will be count + 1 items to concatenate. We
  777.          * also leave room for an extra pointer at the end to
  778.          * use as a sentinel.  Thus, start count at 2.
  779.          */
  780.         save_tree = tree;
  781.         for (count = 2; tree && tree->type == Node_concat; tree = tree->lnode)
  782.             count++;
  783.         tree = save_tree;
  784.         emalloc(treelist, NODE **, sizeof(NODE *) * count, "tree_eval");
  785.         emalloc(strlist, NODE **, sizeof(NODE *) * count, "tree_eval");
  786.  
  787.         /* Now, here we go. */
  788.         treep = treelist;
  789.         while (tree && tree->type == Node_concat) {
  790.             *treep++ = tree->rnode;
  791.             tree = tree->lnode;
  792.         }
  793.         *treep = tree;
  794.         /*
  795.          * Now, evaluate to strings in LIFO order, accumulating
  796.          * the string length, so we can do a single malloc at the
  797.          * end.
  798.          */
  799.         strp = strlist;
  800.         len = 0;
  801.         while (treep >= treelist) {
  802.             *strp = force_string(tree_eval(*treep--));
  803.             len += (*strp)->stlen;
  804.             strp++;
  805.         }
  806.         *strp = NULL;
  807.         emalloc(str, char *, len+2, "tree_eval");
  808.         str[len] = str[len+1] = '\0';    /* for good measure */
  809.         dest = str;
  810.         strp = strlist;
  811.         while (*strp) {
  812.             memcpy(dest, (*strp)->stptr, (*strp)->stlen);
  813.             dest += (*strp)->stlen;
  814.             free_temp(*strp);
  815.             strp++;
  816.         }
  817.         r = make_str_node(str, len, ALREADY_MALLOCED);
  818.         r->flags |= TEMP;
  819.  
  820.         free(strlist);
  821.         free(treelist);
  822.         }
  823.         return r;
  824.  
  825.     /* other assignment types are easier because they are numeric */
  826.     case Node_preincrement:
  827.     case Node_predecrement:
  828.     case Node_postincrement:
  829.     case Node_postdecrement:
  830.     case Node_assign_exp:
  831.     case Node_assign_times:
  832.     case Node_assign_quotient:
  833.     case Node_assign_mod:
  834.     case Node_assign_plus:
  835.     case Node_assign_minus:
  836.         return op_assign(tree);
  837.     default:
  838.         break;    /* handled below */
  839.     }
  840.  
  841.     /* evaluate subtrees in order to do binary operation, then keep going */
  842.     t1 = tree_eval(tree->lnode);
  843.     t2 = tree_eval(tree->rnode);
  844.  
  845.     switch (tree->type) {
  846.     case Node_geq:
  847.     case Node_leq:
  848.     case Node_greater:
  849.     case Node_less:
  850.     case Node_notequal:
  851.     case Node_equal:
  852.         di = cmp_nodes(t1, t2);
  853.         free_temp(t1);
  854.         free_temp(t2);
  855.         switch (tree->type) {
  856.         case Node_equal:
  857.             return tmp_number((AWKNUM) (di == 0));
  858.         case Node_notequal:
  859.             return tmp_number((AWKNUM) (di != 0));
  860.         case Node_less:
  861.             return tmp_number((AWKNUM) (di < 0));
  862.         case Node_greater:
  863.             return tmp_number((AWKNUM) (di > 0));
  864.         case Node_leq:
  865.             return tmp_number((AWKNUM) (di <= 0));
  866.         case Node_geq:
  867.             return tmp_number((AWKNUM) (di >= 0));
  868.         default:
  869.             cant_happen();
  870.         }
  871.         break;
  872.     default:
  873.         break;    /* handled below */
  874.     }
  875.  
  876.     x1 = force_number(t1);
  877.     free_temp(t1);
  878.     x2 = force_number(t2);
  879.     free_temp(t2);
  880.     switch (tree->type) {
  881.     case Node_exp:
  882.         if ((lx = x2) == x2 && lx >= 0) {    /* integer exponent */
  883.             if (lx == 0)
  884.                 x = 1;
  885.             else if (lx == 1)
  886.                 x = x1;
  887.             else {
  888.                 /* doing it this way should be more precise */
  889.                 for (x = x1; --lx; )
  890.                     x *= x1;
  891.             }
  892.         } else
  893.             x = pow((double) x1, (double) x2);
  894.         return tmp_number(x);
  895.  
  896.     case Node_times:
  897.         return tmp_number(x1 * x2);
  898.  
  899.     case Node_quotient:
  900.         if (x2 == 0)
  901.             fatal("division by zero attempted");
  902. #ifdef _CRAY
  903.         /* special case for integer division, put in for Cray */
  904.         lx2 = x2;
  905.         if (lx2 == 0)
  906.             return tmp_number(x1 / x2);
  907.         lx = (long) x1 / lx2;
  908.         if (lx * x2 == x1)
  909.             return tmp_number((AWKNUM) lx);
  910.         else
  911. #endif
  912.             return tmp_number(x1 / x2);
  913.  
  914.     case Node_mod:
  915.         if (x2 == 0)
  916.             fatal("division by zero attempted in mod");
  917. #ifdef HAVE_FMOD
  918.         return tmp_number(fmod(x1, x2));
  919. #else    /* ! HAVE_FMOD */
  920.         (void) modf(x1 / x2, &x);
  921.         return tmp_number(x1 - x * x2);
  922. #endif    /* ! HAVE_FMOD */
  923.  
  924.     case Node_plus:
  925.         return tmp_number(x1 + x2);
  926.  
  927.     case Node_minus:
  928.         return tmp_number(x1 - x2);
  929.  
  930.     case Node_var_array:
  931.         fatal("attempt to use array `%s' in a scalar context",
  932.             tree->vname);
  933.  
  934.     default:
  935.         fatal("illegal type (%s) in tree_eval", nodetype2str(tree->type));
  936.     }
  937.     return 0;
  938. }
  939.  
  940. /* eval_condition --- is TREE true or false? Returns 0==false, non-zero==true */
  941.  
  942. static int
  943. eval_condition(tree)
  944. register NODE *tree;
  945. {
  946.     register NODE *t1;
  947.     register int ret;
  948.  
  949.     if (tree == NULL)    /* Null trees are the easiest kinds */
  950.         return TRUE;
  951.     if (tree->type == Node_line_range) {
  952.         /*
  953.          * Node_line_range is kind of like Node_match, EXCEPT: the
  954.          * lnode field (more properly, the condpair field) is a node
  955.          * of a Node_cond_pair; whether we evaluate the lnode of that
  956.          * node or the rnode depends on the triggered word.  More
  957.          * precisely:  if we are not yet triggered, we tree_eval the
  958.          * lnode; if that returns true, we set the triggered word. 
  959.          * If we are triggered (not ELSE IF, note), we tree_eval the
  960.          * rnode, clear triggered if it succeeds, and perform our
  961.          * action (regardless of success or failure).  We want to be
  962.          * able to begin and end on a single input record, so this
  963.          * isn't an ELSE IF, as noted above.
  964.          */
  965.         if (! tree->triggered)
  966.             if (! eval_condition(tree->condpair->lnode))
  967.                 return FALSE;
  968.             else
  969.                 tree->triggered = TRUE;
  970.         /* Else we are triggered */
  971.         if (eval_condition(tree->condpair->rnode))
  972.             tree->triggered = FALSE;
  973.         return TRUE;
  974.     }
  975.  
  976.     /*
  977.      * Could just be J.random expression. in which case, null and 0 are
  978.      * false, anything else is true 
  979.      */
  980.  
  981.     t1 = m_tree_eval(tree, TRUE);
  982.     if (t1->flags & MAYBE_NUM)
  983.         (void) force_number(t1);
  984.     if (t1->flags & NUMBER)
  985.         ret = (t1->numbr != 0.0);
  986.     else
  987.         ret = (t1->stlen != 0);
  988.     free_temp(t1);
  989.     return ret;
  990. }
  991.  
  992. /* cmp_nodes --- compare two nodes, returning negative, 0, positive */
  993.  
  994. int
  995. cmp_nodes(t1, t2)
  996. register NODE *t1, *t2;
  997. {
  998.     register int ret;
  999.     register size_t len1, len2;
  1000.     register int l;
  1001.     int ldiff;
  1002.  
  1003.     if (t1 == t2)
  1004.         return 0;
  1005.     if (t1->flags & MAYBE_NUM)
  1006.         (void) force_number(t1);
  1007.     if (t2->flags & MAYBE_NUM)
  1008.         (void) force_number(t2);
  1009.     if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
  1010.         if (t1->numbr == t2->numbr)
  1011.             return 0;
  1012.         /* don't subtract, in case one or both are infinite */
  1013.         else if (t1->numbr < t2->numbr)
  1014.             return -1;
  1015.         else
  1016.             return 1;
  1017.     }
  1018.     (void) force_string(t1);
  1019.     (void) force_string(t2);
  1020.     len1 = t1->stlen;
  1021.     len2 = t2->stlen;
  1022.     ldiff = len1 - len2;
  1023.     if (len1 == 0 || len2 == 0)
  1024.         return ldiff;
  1025.     l = (ldiff <= 0 ? len1 : len2);
  1026.     if (IGNORECASE) {
  1027.         register unsigned char *cp1 = (unsigned char *) t1->stptr;
  1028.         register unsigned char *cp2 = (unsigned char *) t2->stptr;
  1029.  
  1030.         for (ret = 0; l-- > 0 && ret == 0; cp1++, cp2++)
  1031.             ret = casetable[*cp1] - casetable[*cp2];
  1032.     } else
  1033.         ret = memcmp(t1->stptr, t2->stptr, l);
  1034.     return (ret == 0 ? ldiff : ret);
  1035. }
  1036.  
  1037. /* op_assign --- do +=, -=, etc. */
  1038.  
  1039. static NODE *
  1040. op_assign(tree)
  1041. register NODE *tree;
  1042. {
  1043.     AWKNUM rval, lval;
  1044.     NODE **lhs;
  1045.     AWKNUM t1, t2;
  1046.     long ltemp;
  1047.     NODE *tmp;
  1048.     Func_ptr after_assign = NULL;
  1049.  
  1050.     lhs = get_lhs(tree->lnode, &after_assign);
  1051.     lval = force_number(*lhs);
  1052.  
  1053.     /*
  1054.      * Can't unref *lhs until we know the type; doing so
  1055.      * too early breaks   x += x   sorts of things.
  1056.      */
  1057.     switch(tree->type) {
  1058.     case Node_preincrement:
  1059.     case Node_predecrement:
  1060.         unref(*lhs);
  1061.         *lhs = make_number(lval +
  1062.                    (tree->type == Node_preincrement ? 1.0 : -1.0));
  1063.         tree->lnode->flags |= SCALAR;
  1064.         if (after_assign)
  1065.             (*after_assign)();
  1066.         return *lhs;
  1067.  
  1068.     case Node_postincrement:
  1069.     case Node_postdecrement:
  1070.         unref(*lhs);
  1071.         *lhs = make_number(lval +
  1072.                    (tree->type == Node_postincrement ? 1.0 : -1.0));
  1073.         tree->lnode->flags |= SCALAR;
  1074.         if (after_assign)
  1075.             (*after_assign)();
  1076.         return tmp_number(lval);
  1077.     default:
  1078.         break;    /* handled below */
  1079.     }
  1080.  
  1081.     tmp = tree_eval(tree->rnode);
  1082.     rval = force_number(tmp);
  1083.     free_temp(tmp);
  1084.  
  1085.     /*
  1086.      * Do this again; the lhs and the rhs could both be fields.
  1087.      * Accessing the rhs could cause the lhs to have moved around.
  1088.      * (Yet another special case. Gack.)
  1089.      */
  1090.     lhs = get_lhs(tree->lnode, &after_assign);
  1091.  
  1092.     unref(*lhs);
  1093.     switch(tree->type) {
  1094.     case Node_assign_exp:
  1095.         if ((ltemp = rval) == rval) {    /* integer exponent */
  1096.             if (ltemp == 0)
  1097.                 *lhs = make_number((AWKNUM) 1);
  1098.             else if (ltemp == 1)
  1099.                 *lhs = make_number(lval);
  1100.             else {
  1101.                 /* doing it this way should be more precise */
  1102.                 for (t1 = t2 = lval; --ltemp; )
  1103.                     t1 *= t2;
  1104.                 *lhs = make_number(t1);
  1105.             }
  1106.         } else
  1107.             *lhs = make_number((AWKNUM) pow((double) lval, (double) rval));
  1108.         break;
  1109.  
  1110.     case Node_assign_times:
  1111.         *lhs = make_number(lval * rval);
  1112.         break;
  1113.  
  1114.     case Node_assign_quotient:
  1115.         if (rval == (AWKNUM) 0)
  1116.             fatal("division by zero attempted in /=");
  1117. #ifdef _CRAY
  1118.         /* special case for integer division, put in for Cray */
  1119.         ltemp = rval;
  1120.         if (ltemp == 0) {
  1121.             *lhs = make_number(lval / rval);
  1122.             break;
  1123.         }
  1124.         ltemp = (long) lval / ltemp;
  1125.         if (ltemp * lval == rval)
  1126.             *lhs = make_number((AWKNUM) ltemp);
  1127.         else
  1128. #endif    /* _CRAY */
  1129.             *lhs = make_number(lval / rval);
  1130.         break;
  1131.  
  1132.     case Node_assign_mod:
  1133.         if (rval == (AWKNUM) 0)
  1134.             fatal("division by zero attempted in %%=");
  1135. #ifdef HAVE_FMOD
  1136.         *lhs = make_number(fmod(lval, rval));
  1137. #else    /* ! HAVE_FMOD */
  1138.         (void) modf(lval / rval, &t1);
  1139.         t2 = lval - rval * t1;
  1140.         *lhs = make_number(t2);
  1141. #endif    /* ! HAVE_FMOD */
  1142.         break;
  1143.  
  1144.     case Node_assign_plus:
  1145.         *lhs = make_number(lval + rval);
  1146.         break;
  1147.  
  1148.     case Node_assign_minus:
  1149.         *lhs = make_number(lval - rval);
  1150.         break;
  1151.     default:
  1152.         cant_happen();
  1153.     }
  1154.     tree->lnode->flags |= SCALAR;
  1155.     if (after_assign)
  1156.         (*after_assign)();
  1157.     return *lhs;
  1158. }
  1159.  
  1160. static struct fcall {
  1161.     char *fname;
  1162.     unsigned long count;
  1163.     NODE *arglist;
  1164.     NODE **prevstack;
  1165.     NODE **stack;
  1166. } *fcall_list = NULL;
  1167.  
  1168. static long fcall_list_size = 0;
  1169. static long curfcall = -1;
  1170.  
  1171. /* in_function --- return true/false if we need to unwind awk functions */
  1172.  
  1173. static int
  1174. in_function()
  1175. {
  1176.     return (curfcall >= 0);
  1177. }
  1178.  
  1179. /* pop_fcall --- pop off a single function call */
  1180.  
  1181. static void
  1182. pop_fcall()
  1183. {
  1184.     NODE *n, **sp, *arg, *argp;
  1185.     int count;
  1186.     struct fcall *f;
  1187.  
  1188.     assert(curfcall >= 0);
  1189.     f = & fcall_list[curfcall];
  1190.     stack_ptr = f->prevstack;
  1191.  
  1192.     /*
  1193.      * here, we pop each parameter and check whether
  1194.      * it was an array.  If so, and if the arg. passed in was
  1195.      * a simple variable, then the value should be copied back.
  1196.      * This achieves "call-by-reference" for arrays.
  1197.      */
  1198.     sp = f->stack;
  1199.     count = f->count;
  1200.  
  1201.     for (argp = f->arglist; count > 0 && argp != NULL; argp = argp->rnode) {
  1202.         arg = argp->lnode;
  1203.         if (arg->type == Node_param_list)
  1204.             arg = stack_ptr[arg->param_cnt];
  1205.         n = *sp++;
  1206.         if ((arg->type == Node_var || arg->type == Node_var_array)
  1207.             && n->type == Node_var_array) {
  1208.             /* should we free arg->var_value ? */
  1209.             arg->var_array = n->var_array;
  1210.             arg->type = Node_var_array;
  1211.             arg->array_size = n->array_size;
  1212.             arg->table_size = n->table_size;
  1213.             arg->flags = n->flags;
  1214.         }
  1215.         /* n->lnode overlays the array size, don't unref it if array */
  1216.         if (n->type != Node_var_array)
  1217.             unref(n->lnode);
  1218.         freenode(n);
  1219.         count--;
  1220.     }
  1221.     while (count-- > 0) {
  1222.         n = *sp++;
  1223.         /* if n is a local array, all the elements should be freed */
  1224.         if (n->type == Node_var_array)
  1225.             assoc_clear(n);
  1226.         unref(n->lnode);
  1227.         freenode(n);
  1228.     }
  1229.     if (f->stack)
  1230.         free((char *) f->stack);
  1231.     memset(f, '\0', sizeof(struct fcall));
  1232.     curfcall--;
  1233. }
  1234.  
  1235. /* pop_fcall_stack --- pop off all function args, don't leak memory */
  1236.  
  1237. static void
  1238. pop_fcall_stack()
  1239. {
  1240.     while (curfcall >= 0)
  1241.         pop_fcall();
  1242. }
  1243.  
  1244. /* push_args --- push function arguments onto the stack */
  1245.  
  1246. static void
  1247. push_args(count, arglist, oldstack, func_name)
  1248. int count;
  1249. NODE *arglist;
  1250. NODE **oldstack;
  1251. char *func_name;
  1252. {
  1253.     struct fcall *f;
  1254.     NODE *arg, *argp, *r, **sp, *n;
  1255.  
  1256.     if (fcall_list_size == 0) {    /* first time */
  1257.         emalloc(fcall_list, struct fcall *, 10 * sizeof(struct fcall),
  1258.             "push_args");
  1259.         fcall_list_size = 10;
  1260.     }
  1261.  
  1262.     if (++curfcall >= fcall_list_size) {
  1263.         fcall_list_size *= 2;
  1264.         erealloc(fcall_list, struct fcall *,
  1265.             fcall_list_size * sizeof(struct fcall), "push_args");
  1266.     }
  1267.     f = & fcall_list[curfcall];
  1268.     memset(f, '\0', sizeof(struct fcall));
  1269.  
  1270.     if (count > 0)
  1271.         emalloc(f->stack, NODE **, count*sizeof(NODE *), "func_call");
  1272.     f->count = count;
  1273.     f->fname = func_name;    /* not used, for debugging, just in case */
  1274.     f->arglist = arglist;
  1275.     f->prevstack = oldstack;
  1276.  
  1277.     sp = f->stack;
  1278.  
  1279.     /* for each calling arg. add NODE * on stack */
  1280.     for (argp = arglist; count > 0 && argp != NULL; argp = argp->rnode) {
  1281.         arg = argp->lnode;
  1282.         getnode(r);
  1283.         r->type = Node_var;
  1284.  
  1285.         /* call by reference for arrays; see below also */
  1286.         if (arg->type == Node_param_list)
  1287.             arg = f->prevstack[arg->param_cnt];
  1288.         if (arg->type == Node_var_array)
  1289.             *r = *arg;
  1290.         else {
  1291.             n = tree_eval(arg);
  1292.             r->lnode = dupnode(n);
  1293.             r->rnode = (NODE *) NULL;
  1294.               if ((n->flags & SCALAR) != 0)
  1295.                   r->flags |= SCALAR;
  1296.             free_temp(n);
  1297.           }
  1298.         *sp++ = r;
  1299.         count--;
  1300.     }
  1301.     if (argp != NULL)    /* left over calling args. */
  1302.         warning(
  1303.             "function `%s' called with more arguments than declared",
  1304.             func_name);
  1305.  
  1306.     /* add remaining params. on stack with null value */
  1307.     while (count-- > 0) {
  1308.         getnode(r);
  1309.         r->type = Node_var;
  1310.         r->lnode = Nnull_string;
  1311.         r->flags &= ~SCALAR;
  1312.         r->rnode = (NODE *) NULL;
  1313.         *sp++ = r;
  1314.     }
  1315.  
  1316.     /*
  1317.      * We have to reassign f. Why, you may ask?  It is possible that
  1318.      * other functions were called during the course of tree_eval()-ing
  1319.      * the arguments to this function. As a result of that, fcall_list
  1320.      * may have been realloc()'ed, with the result that f is now
  1321.      * pointing into free()'d space.  This was a nasty one to track down.
  1322.      */
  1323.     f = & fcall_list[curfcall];
  1324.  
  1325.     stack_ptr = f->stack;
  1326. }
  1327.  
  1328. /* func_call --- call a function, call by reference for arrays */
  1329.  
  1330. NODE **stack_ptr;
  1331.  
  1332. static NODE *
  1333. func_call(name, arg_list)
  1334. NODE *name;        /* name is a Node_val giving function name */
  1335. NODE *arg_list;        /* Node_expression_list of calling args. */
  1336. {
  1337.     register NODE *r;
  1338.     NODE *f;
  1339.     jmp_buf volatile func_tag_stack;
  1340.     jmp_buf volatile loop_tag_stack;
  1341.     int volatile save_loop_tag_valid = FALSE;
  1342.     NODE *save_ret_node;
  1343.     extern NODE *ret_node;
  1344.  
  1345.     /* retrieve function definition node */
  1346.     f = lookup(name->stptr);
  1347.     if (f == NULL || f->type != Node_func)
  1348.         fatal("function `%s' not defined", name->stptr);
  1349. #ifdef FUNC_TRACE
  1350.     fprintf(stderr, "function %s called\n", name->stptr);
  1351. #endif
  1352.     push_args(f->lnode->param_cnt, arg_list, stack_ptr, name->stptr);
  1353.  
  1354.     /*
  1355.      * Execute function body, saving context, as a return statement
  1356.      * will longjmp back here.
  1357.      *
  1358.      * Have to save and restore the loop_tag stuff so that a return
  1359.      * inside a loop in a function body doesn't scrog any loops going
  1360.      * on in the main program.  We save the necessary info in variables
  1361.      * local to this function so that function nesting works OK.
  1362.      * We also only bother to save the loop stuff if we're in a loop
  1363.      * when the function is called.
  1364.      */
  1365.     if (loop_tag_valid) {
  1366.         int junk = 0;
  1367.  
  1368.         save_loop_tag_valid = (volatile int) loop_tag_valid;
  1369.         PUSH_BINDING(loop_tag_stack, loop_tag, junk);
  1370.         loop_tag_valid = FALSE;
  1371.     }
  1372.     PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
  1373.     save_ret_node = ret_node;
  1374.     ret_node = Nnull_string;    /* default return value */
  1375.     if (setjmp(func_tag) == 0)
  1376.         (void) interpret(f->rnode);
  1377.  
  1378.     r = ret_node;
  1379.     ret_node = (NODE *) save_ret_node;
  1380.     RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
  1381.     pop_fcall();
  1382.  
  1383.     /* Restore the loop_tag stuff if necessary. */
  1384.     if (save_loop_tag_valid) {
  1385.         int junk = 0;
  1386.  
  1387.         loop_tag_valid = (int) save_loop_tag_valid;
  1388.         RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
  1389.     }
  1390.  
  1391.     if ((r->flags & PERM) == 0)
  1392.         r->flags |= TEMP;
  1393.     return r;
  1394. }
  1395.  
  1396. /*
  1397.  * r_get_lhs:
  1398.  * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
  1399.  * value of the var, or where to store the var's new value 
  1400.  */
  1401.  
  1402. NODE **
  1403. r_get_lhs(ptr, assign)
  1404. register NODE *ptr;
  1405. Func_ptr *assign;
  1406. {
  1407.     register NODE **aptr = NULL;
  1408.     register NODE *n;
  1409.  
  1410.     if (assign)
  1411.         *assign = NULL;    /* for safety */
  1412.     if (ptr->type == Node_param_list)
  1413.         ptr = stack_ptr[ptr->param_cnt];
  1414.  
  1415.     switch (ptr->type) {
  1416.     case Node_var_array:
  1417.         fatal("attempt to use array `%s' in a scalar context",
  1418.             ptr->vname);
  1419.  
  1420.     case Node_var:
  1421.         aptr = &(ptr->var_value);
  1422. #ifdef DEBUG
  1423.         if (ptr->var_value->stref <= 0)
  1424.             cant_happen();
  1425. #endif
  1426.         break;
  1427.  
  1428.     case Node_FIELDWIDTHS:
  1429.         aptr = &(FIELDWIDTHS_node->var_value);
  1430.         if (assign != NULL)
  1431.             *assign = set_FIELDWIDTHS;
  1432.         break;
  1433.  
  1434.     case Node_RS:
  1435.         aptr = &(RS_node->var_value);
  1436.         if (assign != NULL)
  1437.             *assign = set_RS;
  1438.         break;
  1439.  
  1440.     case Node_FS:
  1441.         aptr = &(FS_node->var_value);
  1442.         if (assign != NULL)
  1443.             *assign = set_FS;
  1444.         break;
  1445.  
  1446.     case Node_FNR:
  1447.         unref(FNR_node->var_value);
  1448.         FNR_node->var_value = make_number((AWKNUM) FNR);
  1449.         aptr = &(FNR_node->var_value);
  1450.         if (assign != NULL)
  1451.             *assign = set_FNR;
  1452.         break;
  1453.  
  1454.     case Node_NR:
  1455.         unref(NR_node->var_value);
  1456.         NR_node->var_value = make_number((AWKNUM) NR);
  1457.         aptr = &(NR_node->var_value);
  1458.         if (assign != NULL)
  1459.             *assign = set_NR;
  1460.         break;
  1461.  
  1462.     case Node_NF:
  1463.         if (NF == -1)
  1464.             (void) get_field(HUGE-1, assign); /* parse record */
  1465.         unref(NF_node->var_value);
  1466.         NF_node->var_value = make_number((AWKNUM) NF);
  1467.         aptr = &(NF_node->var_value);
  1468.         if (assign != NULL)
  1469.             *assign = set_NF;
  1470.         break;
  1471.  
  1472.     case Node_IGNORECASE:
  1473.         aptr = &(IGNORECASE_node->var_value);
  1474.         if (assign != NULL)
  1475.             *assign = set_IGNORECASE;
  1476.         break;
  1477.  
  1478.     case Node_OFMT:
  1479.         aptr = &(OFMT_node->var_value);
  1480.         if (assign != NULL)
  1481.             *assign = set_OFMT;
  1482.         break;
  1483.  
  1484.     case Node_CONVFMT:
  1485.         aptr = &(CONVFMT_node->var_value);
  1486.         if (assign != NULL)
  1487.             *assign = set_CONVFMT;
  1488.         break;
  1489.  
  1490.     case Node_ORS:
  1491.         aptr = &(ORS_node->var_value);
  1492.         if (assign != NULL)
  1493.             *assign = set_ORS;
  1494.         break;
  1495.  
  1496.     case Node_OFS:
  1497.         aptr = &(OFS_node->var_value);
  1498.         if (assign != NULL)
  1499.             *assign = set_OFS;
  1500.         break;
  1501.  
  1502.     case Node_param_list:
  1503.         aptr = &(stack_ptr[ptr->param_cnt]->var_value);
  1504.         break;
  1505.  
  1506.     case Node_field_spec:
  1507.         {
  1508.         int field_num;
  1509.  
  1510.         n = tree_eval(ptr->lnode);
  1511.         field_num = (int) force_number(n);
  1512.         free_temp(n);
  1513.         if (field_num < 0)
  1514.             fatal("attempt to access field %d", field_num);
  1515.         if (field_num == 0 && field0_valid) {    /* short circuit */
  1516.             aptr = &fields_arr[0];
  1517.             if (assign != NULL)
  1518.                 *assign = reset_record;
  1519.             break;
  1520.         }
  1521.         aptr = get_field(field_num, assign);
  1522.         break;
  1523.         }
  1524.     case Node_subscript:
  1525.         n = ptr->lnode;
  1526.         if (n->type == Node_param_list) {
  1527.             int i = n->param_cnt + 1;
  1528.  
  1529.             n = stack_ptr[n->param_cnt];
  1530.             if ((n->flags & SCALAR) != 0)
  1531.                 fatal("attempt to use scalar parameter %d as an array", i);
  1532.         } else if (n->type == Node_func) {
  1533.             fatal("attempt to use function `%s' as array",
  1534.                 n->lnode->param);
  1535.         }
  1536.         aptr = assoc_lookup(n, concat_exp(ptr->rnode));
  1537.         break;
  1538.  
  1539.     case Node_func:
  1540.         fatal("`%s' is a function, assignment is not allowed",
  1541.             ptr->lnode->param);
  1542.  
  1543.     case Node_builtin:
  1544.         fatal("assignment is not allowed to result of builtin function");
  1545.     default:
  1546.         cant_happen();
  1547.     }
  1548.     return aptr;
  1549. }
  1550.  
  1551. /* match_op --- do ~ and !~ */
  1552.  
  1553. static NODE *
  1554. match_op(tree)
  1555. register NODE *tree;
  1556. {
  1557.     register NODE *t1;
  1558.     register Regexp *rp;
  1559.     int i;
  1560.     int match = TRUE;
  1561.     int kludge_need_start = FALSE;    /* FIXME: --- see below */
  1562.  
  1563.     if (tree->type == Node_nomatch)
  1564.         match = FALSE;
  1565.     if (tree->type == Node_regex)
  1566.         t1 = *get_field(0, (Func_ptr *) 0);
  1567.     else {
  1568.         t1 = force_string(tree_eval(tree->lnode));
  1569.         tree = tree->rnode;
  1570.     }
  1571.     rp = re_update(tree);
  1572.     /*
  1573.      * FIXME:
  1574.      *
  1575.      * Any place where research() is called with a last parameter of
  1576.      * FALSE, we need to use the avoid_dfa test. This is the only place
  1577.      * at the moment.
  1578.      *
  1579.      * A new or improved dfa that distinguishes beginning/end of
  1580.      * string from beginning/end of line will allow us to get rid of
  1581.      * this temporary hack.
  1582.      *
  1583.      * The avoid_dfa() function is in re.c; it is not very smart.
  1584.      */
  1585.     if (avoid_dfa(tree, t1->stptr, t1->stlen))
  1586.         kludge_need_start = TRUE;
  1587.     i = research(rp, t1->stptr, 0, t1->stlen, kludge_need_start);
  1588.     i = (i == -1) ^ (match == TRUE);
  1589.     free_temp(t1);
  1590.     return tmp_number((AWKNUM) i);
  1591. }
  1592.  
  1593. /* set_IGNORECASE --- update IGNORECASE as appropriate */
  1594.  
  1595. void
  1596. set_IGNORECASE()
  1597. {
  1598.     static int warned = FALSE;
  1599.  
  1600.     if ((do_lint || do_traditional) && ! warned) {
  1601.         warned = TRUE;
  1602.         warning("IGNORECASE not supported in compatibility mode");
  1603.     }
  1604.     if (do_traditional)
  1605.         IGNORECASE = FALSE;
  1606.     else if ((IGNORECASE_node->var_value->flags & (STRING|STR)) != 0) {
  1607.         if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
  1608.             IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
  1609.         else
  1610.             IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
  1611.     } else if ((IGNORECASE_node->var_value->flags & (NUM|NUMBER)) != 0)
  1612.         IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
  1613.     else
  1614.         IGNORECASE = FALSE;        /* shouldn't happen */
  1615.     set_FS_if_not_FIELDWIDTHS();
  1616. }
  1617.  
  1618. /* set_OFS --- update OFS related variables when OFS assigned to */
  1619.  
  1620. void
  1621. set_OFS()
  1622. {
  1623.     OFS = force_string(OFS_node->var_value)->stptr;
  1624.     OFSlen = OFS_node->var_value->stlen;
  1625.     OFS[OFSlen] = '\0';
  1626. }
  1627.  
  1628. /* set_ORS --- update ORS related variables when ORS assigned to */
  1629.  
  1630. void
  1631. set_ORS()
  1632. {
  1633.     ORS = force_string(ORS_node->var_value)->stptr;
  1634.     ORSlen = ORS_node->var_value->stlen;
  1635.     ORS[ORSlen] = '\0';
  1636. }
  1637.  
  1638. /* fmt_ok --- is the conversion format a valid one? */
  1639.  
  1640. NODE **fmt_list = NULL;
  1641. static int fmt_ok P((NODE *n));
  1642. static int fmt_index P((NODE *n));
  1643.  
  1644. static int
  1645. fmt_ok(n)
  1646. NODE *n;
  1647. {
  1648.     NODE *tmp = force_string(n);
  1649.     char *p = tmp->stptr;
  1650.  
  1651.     if (*p++ != '%')
  1652.         return 0;
  1653.     while (*p && strchr(" +-#", *p) != NULL)    /* flags */
  1654.         p++;
  1655.     while (*p && isdigit(*p))    /* width - %*.*g is NOT allowed */
  1656.         p++;
  1657.     if (*p == '\0' || (*p != '.' && ! isdigit(*p)))
  1658.         return 0;
  1659.     if (*p == '.')
  1660.         p++;
  1661.     while (*p && isdigit(*p))    /* precision */
  1662.         p++;
  1663.     if (*p == '\0' || strchr("efgEG", *p) == NULL)
  1664.         return 0;
  1665.     if (*++p != '\0')
  1666.         return 0;
  1667.     return 1;
  1668. }
  1669.  
  1670. /* fmt_index --- track values of OFMT and CONVFMT to keep semantics correct */
  1671.  
  1672. static int
  1673. fmt_index(n)
  1674. NODE *n;
  1675. {
  1676.     register int ix = 0;
  1677.     static int fmt_num = 4;
  1678.     static int fmt_hiwater = 0;
  1679.  
  1680.     if (fmt_list == NULL)
  1681.         emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
  1682.     (void) force_string(n);
  1683.     while (ix < fmt_hiwater) {
  1684.         if (cmp_nodes(fmt_list[ix], n) == 0)
  1685.             return ix;
  1686.         ix++;
  1687.     }
  1688.     /* not found */
  1689.     n->stptr[n->stlen] = '\0';
  1690.     if (do_lint && ! fmt_ok(n))
  1691.         warning("bad %sFMT specification",
  1692.                 n == CONVFMT_node->var_value ? "CONV"
  1693.               : n == OFMT_node->var_value ? "O"
  1694.               : "");
  1695.  
  1696.     if (fmt_hiwater >= fmt_num) {
  1697.         fmt_num *= 2;
  1698.         emalloc(fmt_list, NODE **, fmt_num, "fmt_index");
  1699.     }
  1700.     fmt_list[fmt_hiwater] = dupnode(n);
  1701.     return fmt_hiwater++;
  1702. }
  1703.  
  1704. /* set_OFMT --- track OFMT correctly */
  1705.  
  1706. void
  1707. set_OFMT()
  1708. {
  1709.     OFMTidx = fmt_index(OFMT_node->var_value);
  1710.     OFMT = fmt_list[OFMTidx]->stptr;
  1711. }
  1712.  
  1713. /* set_CONVFMT --- track CONVFMT correctly */
  1714.  
  1715. void
  1716. set_CONVFMT()
  1717. {
  1718.     CONVFMTidx = fmt_index(CONVFMT_node->var_value);
  1719.     CONVFMT = fmt_list[CONVFMTidx]->stptr;
  1720. }
  1721.