home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 419b.lha / GNU_Awk_v2.10_Beta / awk2.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  32KB  |  1,166 lines

  1. /*
  2.  * awk2 --- gawk parse tree interpreter 
  3.  *
  4.  * $Log:    awk2.c,v $
  5.  * Revision 1.51  89/03/31  13:25:34  david
  6.  * GNU license; MSDOS support
  7.  * 
  8.  * Revision 1.50  89/03/30  20:57:19  david
  9.  * allow for Node_rule_node (a single rule)
  10.  * avoid calling eval_condition for no pattern
  11.  * plug a memory leak in assign_number
  12.  * 
  13.  * Revision 1.49  89/03/29  14:15:07  david
  14.  * delinting
  15.  * 
  16.  * Revision 1.48  89/03/26  17:58:53  david
  17.  * changed return of do_printf to void
  18.  * 
  19.  * Revision 1.47  89/03/22  22:09:50  david
  20.  * a cleaner way to handle assignment to $n where n > 0
  21.  * 
  22.  * Revision 1.46  89/03/22  21:01:14  david
  23.  * delete some obsolete code
  24.  * 
  25.  * Revision 1.45  89/03/21  19:25:37  david
  26.  * minor cleanup
  27.  * 
  28.  * Revision 1.44  89/03/21  18:24:02  david
  29.  * bug fix in cmp_nodes: strings in which one was a prefix of the other compared equal
  30.  * 
  31.  * Revision 1.43  89/03/21  10:55:55  david
  32.  * cleanup and fix of string comparison (0 length was wrong)
  33.  * 
  34.  * Revision 1.42  89/03/15  22:01:17  david
  35.  * old case stuff removed
  36.  * new case stuff added
  37.  * fixed % operator
  38.  * strings with embedded \0 can now be compared
  39.  * 
  40.  * Revision 1.41  89/03/15  21:32:50  david
  41.  * try to free up memory in as many places as possible
  42.  * 
  43.  * Revision 1.40  88/12/15  12:57:31  david
  44.  * make casetable static
  45.  * 
  46.  * Revision 1.39  88/12/14  10:50:51  david
  47.  * dupnode() the return from a function
  48.  * 
  49.  * Revision 1.38  88/12/13  22:27:04  david
  50.  * macro-front-end tree_eval and other optimizations
  51.  * 
  52.  * Revision 1.36  88/12/08  10:51:37  david
  53.  * small correction to source file code
  54.  * 
  55.  * Revision 1.35  88/12/07  20:00:35  david
  56.  * changes for incorporating source filename into error messages
  57.  * 
  58.  * Revision 1.34  88/12/01  15:04:48  david
  59.  * cleanup and additions for source line number printing in error messages
  60.  * 
  61.  * Revision 1.33  88/11/30  15:16:10  david
  62.  * merge FREE_ONE_REFERENCE into do_deref()
  63.  * free more in do_deref
  64.  * in for (i in array) loops, make sure value of i gets freed on each iteration
  65.  * 
  66.  * Revision 1.32  88/11/29  09:55:04  david
  67.  * corrections to code that tracks value of NF -- this needs cleanup
  68.  * 
  69.  * Revision 1.31  88/11/23  21:40:47  david
  70.  * Arnold: comment cleanup
  71.  * 
  72.  * Revision 1.30  88/11/22  13:49:09  david
  73.  * Arnold: changes for case-insensitive matching
  74.  * 
  75.  * Revision 1.29  88/11/15  10:22:42  david
  76.  * Arnold: cleanup of comments and #include's
  77.  * 
  78.  * Revision 1.28  88/11/14  21:55:38  david
  79.  * Arnold: misc. cleanup and error message on bad regexp
  80.  * 
  81.  * Revision 1.27  88/11/14  21:26:52  david
  82.  * update NF on assignment to a field greater than current NF
  83.  * 
  84.  * Revision 1.26  88/11/03  15:26:20  david
  85.  * simplify call to in_array(); extensive revision of cmp_nodes and is_a_number
  86.  * 
  87.  * Revision 1.25  88/11/01  12:11:57  david
  88.  * DEBUG macro becomes DBG_P; added some debugging code; moved all the
  89.  * compound assignments (+= etc.) into op_assign()
  90.  * 
  91.  * Revision 1.24  88/10/25  10:43:05  david
  92.  * intermediate state: more code movement; Node_string et al. -> Node_val;
  93.  * add more debugging code; improve cmp_nodes
  94.  * 
  95.  * Revision 1.22  88/10/19  21:57:41  david
  96.  * replace malloc and realloc with error checking versions
  97.  * start to change handling of $0
  98.  * 
  99.  * Revision 1.21  88/10/17  20:56:13  david
  100.  * Arnold: better error messages for use of a function in the wrong context
  101.  * 
  102.  * Revision 1.20  88/10/13  21:56:41  david
  103.  * cleanup of previous changes
  104.  * change panic() to fatal()
  105.  * detect and bomb on function call with space between name and opening (
  106.  * 
  107.  * Revision 1.19  88/10/11  22:19:20  david
  108.  * cleanup 
  109.  * 
  110.  * Revision 1.18  88/10/04  21:31:33  david
  111.  * minor cleanup
  112.  * 
  113.  * Revision 1.17  88/08/22  14:01:19  david
  114.  * fix to set_field() from Jay Finlayson
  115.  * 
  116.  * Revision 1.16  88/08/09  14:51:34  david
  117.  * removed bad call to obstack_free() -- there is a lot of memory that is
  118.  * not being properly freed -- this area needs major work
  119.  * changed semantics in eval_condition -- if(expr) should test true if
  120.  * expr is a non-null string, even if the num,erical value is zero -- counter-
  121.  * intuitive but that's what's in the book
  122.  * 
  123.  * Revision 1.15  88/06/13  18:02:58  david
  124.  * separate exit value from fact that exit has been called [from Arnold]
  125.  * 
  126.  * Revision 1.14  88/06/07  23:39:48  david
  127.  * insubstantial changes
  128.  * 
  129.  * Revision 1.13  88/06/06  11:26:39  david
  130.  * get rid of some obsolete code
  131.  * change interface of set_field()
  132.  * 
  133.  * Revision 1.12  88/06/05  22:21:36  david
  134.  * local variables are now kept on a stack
  135.  * 
  136.  * Revision 1.11  88/06/01  22:06:50  david
  137.  * make sure incases of Node_param_list that the variable is looked up
  138.  * 
  139.  * Revision 1.10  88/05/31  09:29:47  david
  140.  * expunge Node_local_var
  141.  * 
  142.  * Revision 1.9  88/05/30  09:52:55  david
  143.  * be prepared for NULL return from make_regexp()
  144.  * fix fatal() call
  145.  * 
  146.  * Revision 1.8  88/05/26  22:48:48  david
  147.  * fixed regexp matching code
  148.  * 
  149.  * Revision 1.7  88/05/16  21:27:09  david
  150.  * comment out obstack_free in interpret() -- it is done in do_file() anyway
  151.  * and was definitely free'ing stuff it shouldn't have
  152.  * change call of func_call() a bit
  153.  * allow get_lhs to be called with other Node types -- return 0; used in
  154.  * do_sub()
  155.  * 
  156.  * Revision 1.6  88/05/13  22:00:03  david
  157.  * generalized *_BINDING macros and moved them to awk.h
  158.  * changes to function calling (mostly elsewhere)
  159.  * put into use the Node_var_array type
  160.  * 
  161.  * Revision 1.5  88/05/09  21:22:27  david
  162.  * finally (I hope) got the code right in assign_number
  163.  * 
  164.  * Revision 1.4  88/05/04  12:23:30  david
  165.  * fflush(stdout) on prints if FAST not def'ed
  166.  * all the assign_* cases were returning the wrong thing
  167.  * fixed Node_in_array code
  168.  * code in assign_number was freeing memory it shouldn't have
  169.  * 
  170.  * Revision 1.3  88/04/15  13:12:38  david
  171.  * additional error message
  172.  * 
  173.  * Revision 1.2  88/04/12  16:03:24  david
  174.  * fixed previously intoduced bug: all matches succeeded
  175.  * 
  176.  * Revision 1.1  88/04/08  15:15:01  david
  177.  * Initial revision
  178.  *  Revision 1.7  88/04/08  14:48:33  david changes from
  179.  * Arnold Robbins 
  180.  *
  181.  * Revision 1.6  88/03/28  14:13:50  david *** empty log message *** 
  182.  *
  183.  * Revision 1.5  88/03/23  22:17:37  david mostly delinting -- a couple of bug
  184.  * fixes 
  185.  *
  186.  * Revision 1.4  88/03/18  21:00:10  david Baseline -- hoefully all the
  187.  * functionality of the new awk added. Just debugging and tuning to do. 
  188.  *
  189.  * Revision 1.3  87/11/14  15:16:21  david added user-defined functions with
  190.  * return and do-while loops 
  191.  *
  192.  * Revision 1.2  87/10/29  21:45:44  david added support for array membership
  193.  * test, as in:  if ("yes" in answers) ... this involved one more case: for
  194.  * Node_in_array and rearrangment of the code in assoc_lookup, so that the
  195.  * element can be located without being created 
  196.  *
  197.  * Revision 1.1  87/10/27  15:23:28  david Initial revision 
  198.  *
  199.  */
  200.  
  201. /* 
  202.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  203.  * 
  204.  * This file is part of GAWK, the GNU implementation of the
  205.  * AWK Progamming Language.
  206.  * 
  207.  * GAWK is free software; you can redistribute it and/or modify
  208.  * it under the terms of the GNU General Public License as published by
  209.  * the Free Software Foundation; either version 1, or (at your option)
  210.  * any later version.
  211.  * 
  212.  * GAWK is distributed in the hope that it will be useful,
  213.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  214.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  215.  * GNU General Public License for more details.
  216.  * 
  217.  * You should have received a copy of the GNU General Public License
  218.  * along with GAWK; see the file COPYING.  If not, write to
  219.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  220.  */
  221.  
  222. #include "awk.h"
  223.  
  224. extern void do_print();
  225. extern void do_printf();
  226. extern NODE *func_call();
  227. extern NODE *do_match();
  228. extern NODE *do_sub();
  229. extern NODE *do_getline();
  230. extern int in_array();
  231. extern void do_delete();
  232.  
  233. extern double pow();
  234.  
  235. static int eval_condition();
  236. static int is_a_number();
  237. static NODE *op_assign();
  238.  
  239. NODE *_t;        /* used as a temporary in macros */
  240. #ifdef MSDOS
  241. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  242. #endif
  243. NODE *_result;        /* holds result of tree_eval, for possible freeing */
  244. NODE *ret_node;
  245.  
  246. /* More of that debugging stuff */
  247. #ifdef    DEBUG
  248. #define DBG_P(X) print_debug X
  249. #else
  250. #define DBG_P(X)
  251. #endif
  252.  
  253. extern jmp_buf func_tag;
  254.  
  255. /*
  256.  * This table is used by the regexp routines to do case independant
  257.  * matching. Basically, every ascii character maps to itself, except
  258.  * uppercase letters map to lower case ones. This table has 256
  259.  * entries, which may be overkill. Note also that if the system this
  260.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  261.  * defined to the linker, so gawk should not load.
  262.  *
  263.  * Do NOT make this array static, it is used in several spots, not
  264.  * just in this file.
  265.  */
  266. #if 'a' == 97    /* it's ascii */
  267. char casetable[] = {
  268.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  269.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  270.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  271.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  272.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  273.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  274.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  275.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  276.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  277.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  278.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  279.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  280.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  281.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  282.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  283.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  284.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  285.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  286.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  287.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  288.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  289.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  290.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  291.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  292.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  293.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  294.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  295.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  296.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  297.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  298.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  299.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  300.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  301.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  302.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  303.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  304.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  305.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  306.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  307.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  308.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  309.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  310.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  311.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  312. };
  313. #else
  314. #include "You lose. You will need a translation table for your character set."
  315. #endif
  316.  
  317. /*
  318.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  319.  * statement 
  320.  */
  321. interpret(tree)
  322. NODE *tree;
  323. {
  324.     register NODE *t = NULL;    /* temporary */
  325.  
  326.     auto jmp_buf loop_tag_stack;    /* shallow binding stack for loop_tag */
  327.     static jmp_buf loop_tag;/* always the current binding */
  328.     static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  329.  
  330.     static jmp_buf rule_tag;/* tag the rule currently being run, for NEXT
  331.                  * and EXIT statements.  It is static because
  332.                  * there are no nested rules */
  333.  
  334.     register NODE **lhs;    /* lhs == Left Hand Side for assigns, etc */
  335.     register struct search *l;    /* For array_for */
  336.  
  337.  
  338.     extern NODE **fields_arr;
  339.     extern int exiting, exit_val;
  340.  
  341.     /*
  342.      * clean up temporary strings created by evaluating expressions in
  343.      * previous recursive calls 
  344.      */
  345.  
  346.     if (tree == NULL)
  347.         return 1;
  348.     sourceline = tree->source_line;
  349.     source = tree->source_file;
  350.     switch (tree->type) {
  351.     case Node_rule_list:
  352.         for (t = tree; t != NULL; t = t->rnode) {
  353.             tree = t->lnode;
  354.         /* FALL THROUGH */
  355.     case Node_rule_node:
  356.             switch (_setjmp(rule_tag)) {
  357.             case 0:    /* normal non-jump */
  358.                 /* test pattern, if any */
  359.                 if (tree->lnode == NULL 
  360.                     || eval_condition(tree->lnode)) {
  361.                     DBG_P(("Found a rule", tree->rnode));
  362.                     if (tree->rnode == NULL) {
  363.                         /*
  364.                          * special case: pattern with
  365.                          * no action is equivalent to
  366.                          * an action of {print}
  367.                          */
  368.                         NODE printnode;
  369.  
  370.                         printnode.type = Node_K_print;
  371.                         printnode.lnode = NULL;
  372.                         printnode.rnode = NULL;
  373.                         do_print(&printnode);
  374.                     } else if (tree->rnode->type == Node_illegal) {
  375.                         /*
  376.                          * An empty statement
  377.                          * (``{ }'') is different
  378.                          * from a missing statement.
  379.                          * A missing statement is
  380.                          * equal to ``{ print }'' as
  381.                          * above, but an empty
  382.                          * statement is as in C, do
  383.                          * nothing.
  384.                          */
  385.                     } else
  386.                         (void) interpret(tree->rnode);
  387.                 }
  388.                 break;
  389.             case TAG_CONTINUE:    /* NEXT statement */
  390.                 return 1;
  391.             case TAG_BREAK:
  392.                 return 0;
  393.             }
  394.             if (t == NULL)
  395.                 break;
  396.         }
  397.         break;
  398.  
  399.     case Node_statement_list:
  400.         for (t = tree; t != NULL; t = t->rnode) {
  401.             DBG_P(("Statements", t->lnode));
  402.             (void) interpret(t->lnode);
  403.         }
  404.         break;
  405.  
  406.     case Node_K_if:
  407.         DBG_P(("IF", tree->lnode));
  408.         if (eval_condition(tree->lnode)) {
  409.             DBG_P(("True", tree->rnode->lnode));
  410.             (void) interpret(tree->rnode->lnode);
  411.         } else {
  412.             DBG_P(("False", tree->rnode->rnode));
  413.             (void) interpret(tree->rnode->rnode);
  414.         }
  415.         break;
  416.  
  417.     case Node_K_while:
  418.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  419.  
  420.         DBG_P(("WHILE", tree->lnode));
  421.         while (eval_condition(tree->lnode)) {
  422.             switch (_setjmp(loop_tag)) {
  423.             case 0:    /* normal non-jump */
  424.                 DBG_P(("DO", tree->rnode));
  425.                 (void) interpret(tree->rnode);
  426.                 break;
  427.             case TAG_CONTINUE:    /* continue statement */
  428.                 break;
  429.             case TAG_BREAK:    /* break statement */
  430.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  431.                 return 1;
  432.             default:
  433.                 cant_happen();
  434.             }
  435.         }
  436.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  437.         break;
  438.  
  439.     case Node_K_do:
  440.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  441.  
  442.         do {
  443.             switch (_setjmp(loop_tag)) {
  444.             case 0:    /* normal non-jump */
  445.                 DBG_P(("DO", tree->rnode));
  446.                 (void) interpret(tree->rnode);
  447.                 break;
  448.             case TAG_CONTINUE:    /* continue statement */
  449.                 break;
  450.             case TAG_BREAK:    /* break statement */
  451.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  452.                 return 1;
  453.             default:
  454.                 cant_happen();
  455.             }
  456.             DBG_P(("WHILE", tree->lnode));
  457.         } while (eval_condition(tree->lnode));
  458.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  459.         break;
  460.  
  461.     case Node_K_for:
  462.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  463.  
  464.         DBG_P(("FOR", tree->forloop->init));
  465.         (void) interpret(tree->forloop->init);
  466.  
  467.         DBG_P(("FOR.WHILE", tree->forloop->cond));
  468.         while (eval_condition(tree->forloop->cond)) {
  469.             switch (_setjmp(loop_tag)) {
  470.             case 0:    /* normal non-jump */
  471.                 DBG_P(("FOR.DO", tree->lnode));
  472.                 (void) interpret(tree->lnode);
  473.                 /* fall through */
  474.             case TAG_CONTINUE:    /* continue statement */
  475.                 DBG_P(("FOR.INCR", tree->forloop->incr));
  476.                 (void) interpret(tree->forloop->incr);
  477.                 break;
  478.             case TAG_BREAK:    /* break statement */
  479.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  480.                 return 1;
  481.             default:
  482.                 cant_happen();
  483.             }
  484.         }
  485.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  486.         break;
  487.  
  488.     case Node_K_arrayfor:
  489. #define hakvar forloop->init
  490. #define arrvar forloop->incr
  491.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  492.         DBG_P(("AFOR.VAR", tree->hakvar));
  493.         lhs = get_lhs(tree->hakvar, 1);
  494.         t = tree->arrvar;
  495.         if (tree->arrvar->type == Node_param_list)
  496.             t = stack_ptr[tree->arrvar->param_cnt];
  497.         for (l = assoc_scan(t); l; l = assoc_next(l)) {
  498.             deref = *lhs;
  499.             do_deref();
  500.             *lhs = dupnode(l->retval);
  501.             if (field_num == 0)
  502.                 set_record(fields_arr[0]->stptr,
  503.                     fields_arr[0]->stlen);
  504.             DBG_P(("AFOR.NEXTIS", *lhs));
  505.             switch (_setjmp(loop_tag)) {
  506.             case 0:
  507.                 DBG_P(("AFOR.DO", tree->lnode));
  508.                 (void) interpret(tree->lnode);
  509.             case TAG_CONTINUE:
  510.                 break;
  511.  
  512.             case TAG_BREAK:
  513.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  514.                 field_num = -1;
  515.                 return 1;
  516.             default:
  517.                 cant_happen();
  518.             }
  519.         }
  520.         field_num = -1;
  521.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  522.         break;
  523.  
  524.     case Node_K_break:
  525.         DBG_P(("BREAK", NULL));
  526.         if (loop_tag_valid == 0)
  527.             fatal("unexpected break");
  528.         _longjmp(loop_tag, TAG_BREAK);
  529.         break;
  530.  
  531.     case Node_K_continue:
  532.         DBG_P(("CONTINUE", NULL));
  533.         if (loop_tag_valid == 0)
  534.             fatal("unexpected continue");
  535.         _longjmp(loop_tag, TAG_CONTINUE);
  536.         break;
  537.  
  538.     case Node_K_print:
  539.         DBG_P(("PRINT", tree));
  540.         do_print(tree);
  541.         break;
  542.  
  543.     case Node_K_printf:
  544.         DBG_P(("PRINTF", tree));
  545.         do_printf(tree);
  546.         break;
  547.  
  548.     case Node_K_next:
  549.         DBG_P(("NEXT", NULL));
  550.         _longjmp(rule_tag, TAG_CONTINUE);
  551.         break;
  552.  
  553.     case Node_K_exit:
  554.         /*
  555.          * In A,K,&W, p. 49, it says that an exit statement "...
  556.          * causes the program to behave as if the end of input had
  557.          * occurred; no more input is read, and the END actions, if
  558.          * any are executed." This implies that the rest of the rules
  559.          * are not done. So we immediately break out of the main loop.
  560.          */
  561.         DBG_P(("EXIT", NULL));
  562.         exiting = 1;
  563.         if (tree)
  564.             exit_val = (int) force_number(tree_eval(tree->lnode));
  565.         free_result();
  566.         _longjmp(rule_tag, TAG_BREAK);
  567.         break;
  568.  
  569.     case Node_K_return:
  570.         DBG_P(("RETURN", NULL));
  571.         ret_node = dupnode(tree_eval(tree->lnode));
  572.         ret_node->flags |= TEMP;
  573.         _longjmp(func_tag, TAG_RETURN);
  574.         break;
  575.  
  576.     default:
  577.         /*
  578.          * Appears to be an expression statement.  Throw away the
  579.          * value. 
  580.          */
  581.         DBG_P(("E", NULL));
  582.         (void) tree_eval(tree);
  583.         free_result();
  584.         break;
  585.     }
  586.     return 1;
  587. }
  588.  
  589. /* evaluate a subtree, allocating strings on a temporary stack. */
  590.  
  591. NODE *
  592. r_tree_eval(tree)
  593. NODE *tree;
  594. {
  595.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  596.     int i;
  597.     register NODE **lhs;
  598.     int di;
  599.     AWKNUM x, x2;
  600.     long lx;
  601.     struct re_pattern_buffer *rp;
  602.     extern NODE **fields_arr;
  603.  
  604.     if (tree->type != Node_var)
  605.         source = tree->source_file;
  606.     sourceline = tree->source_line;
  607.     switch (tree->type) {
  608.     case Node_and:
  609.         DBG_P(("AND", tree));
  610.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  611.                         && eval_condition(tree->rnode)));
  612.  
  613.     case Node_or:
  614.         DBG_P(("OR", tree));
  615.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  616.                         || eval_condition(tree->rnode)));
  617.  
  618.     case Node_not:
  619.         DBG_P(("NOT", tree));
  620.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  621.  
  622.         /* Builtins */
  623.     case Node_builtin:
  624.         DBG_P(("builtin", tree));
  625.         return ((*tree->proc) (tree->subnode));
  626.  
  627.     case Node_K_getline:
  628.         DBG_P(("GETLINE", tree));
  629.         return (do_getline(tree));
  630.  
  631.     case Node_in_array:
  632.         DBG_P(("IN_ARRAY", tree));
  633.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  634.  
  635.     case Node_K_match:
  636.         DBG_P(("MATCH", tree));
  637.         return do_match(tree);
  638.  
  639.     case Node_sub:
  640.     case Node_gsub:
  641.         DBG_P(("SUB", tree));
  642.         return do_sub(tree);
  643.  
  644.     case Node_func_call:
  645.         DBG_P(("func_call", tree));
  646.         return func_call(tree->rnode, tree->lnode);
  647.  
  648.     case Node_K_delete:
  649.         DBG_P(("DELETE", tree));
  650.         do_delete(tree->lnode, tree->rnode);
  651.         return Nnull_string;
  652.  
  653.         /* unary operations */
  654.  
  655.     case Node_var:
  656.     case Node_var_array:
  657.     case Node_param_list:
  658.     case Node_subscript:
  659.     case Node_field_spec:
  660.         DBG_P(("var_type ref", tree));
  661.         lhs = get_lhs(tree, 0);
  662.         field_num = -1;
  663.         deref = 0;
  664.         return *lhs;
  665.  
  666.     case Node_unary_minus:
  667.         DBG_P(("UMINUS", tree));
  668.         x = -force_number(tree_eval(tree->subnode));
  669.         free_result();
  670.         return tmp_number(x);
  671.  
  672.     case Node_cond_exp:
  673.         DBG_P(("?:", tree));
  674.         if (eval_condition(tree->lnode)) {
  675.             DBG_P(("True", tree->rnode->lnode));
  676.             return tree_eval(tree->rnode->lnode);
  677.         }
  678.             DBG_P(("False", tree->rnode->rnode));
  679.             return tree_eval(tree->rnode->rnode);
  680.  
  681.     case Node_match:
  682.     case Node_nomatch:
  683.         DBG_P(("ASSIGN_[no]match", tree));
  684.         t1 = force_string(tree_eval(tree->lnode));
  685.         if (tree->rnode->type == Node_regex) {
  686.             rp = tree->rnode->rereg;
  687.             if (!strict && ((IGNORECASE_node->var_value->numbr != 0)
  688.                 ^ (tree->rnode->re_case != 0))) {
  689.                 /* recompile since case sensitivity differs */
  690.                 rp = tree->rnode->rereg =
  691.                     mk_re_parse(tree->rnode->re_text,
  692.                     (IGNORECASE_node->var_value->numbr != 0));
  693.                 tree->rnode->re_case = (IGNORECASE_node->var_value->numbr != 0);
  694.             }
  695.         } else {
  696.             rp = make_regexp(force_string(tree_eval(tree->rnode)),
  697.                     (IGNORECASE_node->var_value->numbr != 0));
  698.             if (rp == NULL)
  699.                 cant_happen();
  700.         }
  701.         i = re_search(rp, t1->stptr, t1->stlen, 0, t1->stlen,
  702.             (struct re_registers *) NULL);
  703.         i = (i == -1) ^ (tree->type == Node_match);
  704.         free_temp(t1);
  705.         return tmp_number((AWKNUM) i);
  706.  
  707.     case Node_func:
  708.         fatal("function `%s' called with space between name and (,\n%s",
  709.             tree->lnode->param,
  710.             "or used in other expression context");
  711.  
  712.         /* assignments */
  713.     case Node_assign:
  714.         DBG_P(("ASSIGN", tree));
  715.         r = tree_eval(tree->rnode);
  716.         lhs = get_lhs(tree->lnode, 1);
  717.         *lhs = dupnode(r);
  718.         do_deref();
  719.         if (field_num == 0)
  720.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  721.         field_num = -1;
  722.         return *lhs;
  723.  
  724.         /* other assignment types are easier because they are numeric */
  725.     case Node_preincrement:
  726.     case Node_predecrement:
  727.     case Node_postincrement:
  728.     case Node_postdecrement:
  729.     case Node_assign_exp:
  730.     case Node_assign_times:
  731.     case Node_assign_quotient:
  732.     case Node_assign_mod:
  733.     case Node_assign_plus:
  734.     case Node_assign_minus:
  735.         return op_assign(tree);
  736.     }
  737.  
  738.     /*
  739.      * Note that if TREE is invalid, gawk will probably bomb in one of
  740.      * these tree_evals here.  
  741.      */
  742.     /* evaluate subtrees in order to do binary operation, then keep going */
  743.     t1 = tree_eval(tree->lnode);
  744.     t2 = tree_eval(tree->rnode);
  745.  
  746.     switch (tree->type) {
  747.     case Node_concat:
  748.         DBG_P(("CONCAT", tree));
  749.         t1 = force_string(t1);
  750.         t2 = force_string(t2);
  751.  
  752.         r = newnode(Node_val);
  753.         r->flags = (STR|TEMP);
  754.         r->stlen = t1->stlen + t2->stlen;
  755.         r->stref = 1;
  756.         emalloc(r->stptr, char *, r->stlen + 1, "tree_eval");
  757.         bcopy(t1->stptr, r->stptr, t1->stlen);
  758.         bcopy(t2->stptr, r->stptr + t1->stlen, t2->stlen);
  759.         r->stptr[r->stlen] = '\0';
  760.         free_temp(t1);
  761.         free_temp(t2);
  762.         return r;
  763.  
  764.     case Node_geq:
  765.     case Node_leq:
  766.     case Node_greater:
  767.     case Node_less:
  768.     case Node_notequal:
  769.     case Node_equal:
  770.         di = cmp_nodes(t1, t2);
  771.         free_temp(t1);
  772.         free_temp(t2);
  773.         switch (tree->type) {
  774.         case Node_equal:
  775.             DBG_P(("EQUAL", tree));
  776.             return tmp_number((AWKNUM) (di == 0));
  777.         case Node_notequal:
  778.             DBG_P(("NOT_EQUAL", tree));
  779.             return tmp_number((AWKNUM) (di != 0));
  780.         case Node_less:
  781.             DBG_P(("LESS_THAN", tree));
  782.             return tmp_number((AWKNUM) (di < 0));
  783.         case Node_greater:
  784.             DBG_P(("GREATER_THAN", tree));
  785.             return tmp_number((AWKNUM) (di > 0));
  786.         case Node_leq:
  787.             DBG_P(("LESS_THAN_EQUAL", tree));
  788.             return tmp_number((AWKNUM) (di <= 0));
  789.         case Node_geq:
  790.             DBG_P(("GREATER_THAN_EQUAL", tree));
  791.             return tmp_number((AWKNUM) (di >= 0));
  792.         }
  793.         break;
  794.     }
  795.  
  796.     (void) force_number(t1);
  797.     (void) force_number(t2);
  798.  
  799.     switch (tree->type) {
  800.     case Node_exp:
  801.         DBG_P(("EXPONENT", tree));
  802.         x = pow((double) t1->numbr, (double) t2->numbr);
  803.         free_temp(t1);
  804.         free_temp(t2);
  805.         return tmp_number(x);
  806.  
  807.     case Node_times:
  808.         DBG_P(("MULT", tree));
  809.         x = t1->numbr * t2->numbr;
  810.         free_temp(t1);
  811.         free_temp(t2);
  812.         return tmp_number(x);
  813.  
  814.     case Node_quotient:
  815.         DBG_P(("DIVIDE", tree));
  816.         x = t2->numbr;
  817.         free_temp(t2);
  818.         if (x == (AWKNUM) 0) {
  819.             free_temp(t1);
  820.             return tmp_number((AWKNUM) 0);
  821.         } else {
  822.             x = t1->numbr / x;
  823.             free_temp(t1);
  824.             return tmp_number(x);
  825.         }
  826.  
  827.     case Node_mod:
  828.         DBG_P(("MODULUS", tree));
  829.         x = t2->numbr;
  830.         free_temp(t2);
  831.         if (x == (AWKNUM) 0) {
  832.             free_temp(t1);
  833.             return tmp_number((AWKNUM) 0);
  834.         }
  835.         lx = t1->numbr / x;    /* assignment to long truncates */
  836.         x2 = lx * x;
  837.         x = t1->numbr - x2;
  838.         free_temp(t1);
  839.         return tmp_number(x);
  840.  
  841.     case Node_plus:
  842.         DBG_P(("PLUS", tree));
  843.         x = t1->numbr + t2->numbr;
  844.         free_temp(t1);
  845.         free_temp(t2);
  846.         return tmp_number(x);
  847.  
  848.     case Node_minus:
  849.         DBG_P(("MINUS", tree));
  850.         x = t1->numbr - t2->numbr;
  851.         free_temp(t1);
  852.         free_temp(t2);
  853.         return tmp_number(x);
  854.  
  855.     default:
  856.         fatal("illegal type (%d) in tree_eval", tree->type);
  857.     }
  858.     return 0;
  859. }
  860.  
  861. /*
  862.  * This makes numeric operations slightly more efficient. Just change the
  863.  * value of a numeric node, if possible 
  864.  */
  865. void
  866. assign_number(ptr, value)
  867. NODE **ptr;
  868. AWKNUM value;
  869. {
  870.     extern NODE *deref;
  871.     register NODE *n = *ptr;
  872.  
  873. #ifdef DEBUG
  874.     if (n->type != Node_val)
  875.         cant_happen();
  876. #endif
  877.     if (n == Nnull_string) {
  878.         *ptr = make_number(value);
  879.         deref = 0;
  880.         return;
  881.     }
  882.     if (n->stref > 1) {
  883.         *ptr = make_number(value);
  884.         return;
  885.     }
  886.     if ((n->flags & STR) && (n->flags & (MALLOC|TEMP)))
  887.         free(n->stptr);
  888.     n->numbr = value;
  889.     n->flags |= NUM;
  890.     n->flags &= ~STR;
  891.     n->stref = 0;
  892.     deref = 0;
  893. }
  894.  
  895.  
  896. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  897. static int
  898. eval_condition(tree)
  899. NODE *tree;
  900. {
  901.     register NODE *t1;
  902.     int ret;
  903.  
  904.     if (tree == NULL)    /* Null trees are the easiest kinds */
  905.         return 1;
  906.     if (tree->type == Node_line_range) {
  907.         /*
  908.          * Node_line_range is kind of like Node_match, EXCEPT: the
  909.          * lnode field (more properly, the condpair field) is a node
  910.          * of a Node_cond_pair; whether we evaluate the lnode of that
  911.          * node or the rnode depends on the triggered word.  More
  912.          * precisely:  if we are not yet triggered, we tree_eval the
  913.          * lnode; if that returns true, we set the triggered word. 
  914.          * If we are triggered (not ELSE IF, note), we tree_eval the
  915.          * rnode, clear triggered if it succeeds, and perform our
  916.          * action (regardless of success or failure).  We want to be
  917.          * able to begin and end on a single input record, so this
  918.          * isn't an ELSE IF, as noted above.
  919.          */
  920.         if (!tree->triggered)
  921.             if (!eval_condition(tree->condpair->lnode))
  922.                 return 0;
  923.             else
  924.                 tree->triggered = 1;
  925.         /* Else we are triggered */
  926.         if (eval_condition(tree->condpair->rnode))
  927.             tree->triggered = 0;
  928.         return 1;
  929.     }
  930.  
  931.     /*
  932.      * Could just be J.random expression. in which case, null and 0 are
  933.      * false, anything else is true 
  934.      */
  935.  
  936.     t1 = tree_eval(tree);
  937.     if (t1->flags & STR)
  938.         ret = t1->stlen != 0;
  939.     else
  940.         ret = t1->numbr != 0.0;
  941.     free_temp(t1);
  942.     return ret;
  943. }
  944.  
  945. /*
  946.  * strtod() would have been better, except (1) real awk is needlessly
  947.  * restrictive in what strings it will consider to be numbers, and (2) I
  948.  * couldn't find the public domain version anywhere handy. 
  949.  */
  950. static int
  951. is_a_number(str)    /* does the string str have pure-numeric syntax? */
  952. char *str;        /* don't convert it, assume that atof is better */
  953. {
  954.     if (*str == 0)
  955.         return 0;    /* null string is not equal to 0 */
  956.  
  957.     if (*str == '-')
  958.         str++;
  959.     if (*str == 0)
  960.         return 0;
  961.     /* must be either . or digits (.4 is legal) */
  962.     if (*str != '.' && !isdigit(*str))
  963.         return 0;
  964.     while (isdigit(*str))
  965.         str++;
  966.     if (*str == '.') {
  967.         str++;
  968.         while (isdigit(*str))
  969.             str++;
  970.     }
  971.  
  972.     /*
  973.      * curiously, real awk DOESN'T consider "1E1" to be equal to 10! Or
  974.      * even equal to 1E1 for that matter!  For a laugh, try:
  975.      * awk 'BEGIN {if ("1E1" == 1E1) print "eq"; else print "neq"; exit}'
  976.      * Since this behavior is QUITE curious, I include the code for the
  977.      * adventurous. One might also feel like skipping leading whitespace
  978.      * (awk doesn't) and allowing a leading + (awk doesn't).
  979.      */
  980. #ifdef Allow_Exponents
  981.     if (*str == 'e' || *str == 'E') {
  982.         str++;
  983.         if (*str == '+' || *str == '-')
  984.             str++;
  985.         if (!isdigit(*str))
  986.             return 0;
  987.         while (isdigit(*str))
  988.             str++;
  989.     }
  990. #endif
  991.     /*
  992.      * if we have digested the whole string, we are
  993.      * successful 
  994.      */
  995.     return (*str == 0);
  996. }
  997.  
  998. int
  999. cmp_nodes(t1, t2)
  1000. NODE *t1, *t2;
  1001. {
  1002.     AWKNUM d;
  1003.     int ret;
  1004.     int len1, len2;
  1005.  
  1006.     if (t1 == t2)
  1007.         return 0;
  1008.     if ((t1->flags & NUM)) {
  1009.         if ((t2->flags & NUM))
  1010.             d = t1->numbr - t2->numbr;
  1011.         else if (is_a_number(t2->stptr))
  1012.             d = t1->numbr - force_number(t2);
  1013.         else {
  1014.             t1 = force_string(t1);
  1015.             goto strings;
  1016.         }
  1017.         if (d == 0.0)    /* from profiling, this is most common */
  1018.             return 0;
  1019.         if (d > 0.0)
  1020.             return 1;
  1021.         return -1;
  1022.     }
  1023.     if ((t2->flags & NUM)) {
  1024.         if (is_a_number(t1->stptr))
  1025.             d = force_number(t1) - t2->numbr;
  1026.         else {
  1027.             t2 = force_string(t2);
  1028.             goto strings;
  1029.         }
  1030.         if (d == 0.0)    /* from profiling, this is most common */
  1031.             return 0;
  1032.         if (d > 0.0)
  1033.             return 1;
  1034.         return -1;
  1035.     }
  1036.     if (is_a_number(t1->stptr) && is_a_number(t2->stptr)) {
  1037.         /*
  1038.          * following two statements are this way because force_number
  1039.          * is a macro
  1040.          */
  1041.         d = force_number(t1);
  1042.         d = d - force_number(t2);
  1043.         if (d == 0.0)    /* from profiling, this is most common */
  1044.             return 0;
  1045.         if (d > 0.0)
  1046.             return 1;
  1047.         return -1;
  1048.     }
  1049.  
  1050. strings:
  1051.     len1 = t1->stlen;
  1052.     len2 = t2->stlen;
  1053.     if (len1 == 0) {
  1054.         if (len2 == 0)
  1055.             return 0;
  1056.         else
  1057.             return -1;
  1058.     } else if (len2 == 0)
  1059.         return 1;
  1060.     ret = memcmp(t1->stptr, t2->stptr, len1 <= len2 ? len1 : len2);
  1061.     if (ret == 0 && len1 != len2)
  1062.         return len1 < len2 ? -1: 1;
  1063.     return ret;
  1064. }
  1065.  
  1066. #ifdef NOMEMCMP
  1067. /*
  1068.  * memcmp --- compare strings.
  1069.  *
  1070.  * We use our own routine since it has to act like strcmp() for return
  1071.  * value, and the BSD manual says bcmp() only returns zero/non-zero.
  1072.  */
  1073.  
  1074. static int
  1075. memcmp (s1, s2, l)
  1076. register char *s1, *s2;
  1077. register int l;
  1078. {
  1079.     for (; l--; s1++, s2++) {
  1080.         if (*s1 != *s2)
  1081.             return (*s1 - *s2);
  1082.     }
  1083.     return (*--s1 - *--s2);
  1084. }
  1085. #endif
  1086.  
  1087. static NODE *
  1088. op_assign(tree)
  1089. NODE *tree;
  1090. {
  1091.     AWKNUM rval, lval;
  1092.     NODE **lhs;
  1093.     AWKNUM t1, t2;
  1094.     long ltemp;
  1095.  
  1096.     lhs = get_lhs(tree->lnode, 1);
  1097.     lval = force_number(*lhs);
  1098.  
  1099.     switch(tree->type) {
  1100.     case Node_preincrement:
  1101.     case Node_predecrement:
  1102.         DBG_P(("+-X", tree));
  1103.         assign_number(lhs,
  1104.             lval + (tree->type == Node_preincrement ? 1.0 : -1.0));
  1105.         do_deref();
  1106.         if (field_num == 0)
  1107.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  1108.         field_num = -1;
  1109.         return *lhs;
  1110.  
  1111.     case Node_postincrement:
  1112.     case Node_postdecrement:
  1113.         DBG_P(("X+-", tree));
  1114.         assign_number(lhs,
  1115.             lval + (tree->type == Node_postincrement ? 1.0 : -1.0));
  1116.         do_deref();
  1117.         if (field_num == 0)
  1118.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  1119.         field_num = -1;
  1120.         return tmp_number(lval);
  1121.     }
  1122.  
  1123.     rval = force_number(tree_eval(tree->rnode));
  1124.     free_result();
  1125.     switch(tree->type) {
  1126.     case Node_assign_exp:
  1127.         DBG_P(("ASSIGN_exp", tree));
  1128.         assign_number(lhs, (AWKNUM) pow((double) lval, (double) rval));
  1129.         break;
  1130.  
  1131.     case Node_assign_times:
  1132.         DBG_P(("ASSIGN_times", tree));
  1133.         assign_number(lhs, lval * rval);
  1134.         break;
  1135.  
  1136.     case Node_assign_quotient:
  1137.         DBG_P(("ASSIGN_quotient", tree));
  1138.         assign_number(lhs, lval / rval);
  1139.         break;
  1140.  
  1141.     case Node_assign_mod:
  1142.         DBG_P(("ASSIGN_mod", tree));
  1143.         ltemp = lval / rval;    /* assignment to long truncates */
  1144.         t1 = ltemp * rval;
  1145.         t2 = lval - t1;
  1146.         assign_number(lhs, t2);
  1147.         break;
  1148.  
  1149.     case Node_assign_plus:
  1150.         DBG_P(("ASSIGN_plus", tree));
  1151.         assign_number(lhs, lval + rval);
  1152.         break;
  1153.  
  1154.     case Node_assign_minus:
  1155.         DBG_P(("ASSIGN_minus", tree));
  1156.         assign_number(lhs, lval - rval);
  1157.         break;
  1158.     }
  1159.     do_deref();
  1160.     if (field_num == 0)
  1161.         set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  1162.     field_num = -1;
  1163.     return *lhs;
  1164. }
  1165.  
  1166.