home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 11 / AUCD11B.iso / LANGUAGES / WraithSet / AwkStuff / GawkSrc / h / awk < prev    next >
Encoding:
Text File  |  1999-10-27  |  25.7 KB  |  898 lines

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989, 1991-1999 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. /* ------------------------------ Includes ------------------------------ */
  27.  
  28. /*
  29.  * config.h absolutely, positively, *M*U*S*T* be included before
  30.  * any system headers.  Otherwise, extreme death, destruction
  31.  * and loss of life results.
  32.  *
  33.  * Well, OK, gawk just won't work on systems using egcs and LFS.  But
  34.  * that's almost as bad.
  35.  */
  36. #ifdef HAVE_CONFIG_H
  37. #include <config.h>
  38. #endif
  39.  
  40. #ifndef _GNU_SOURCE
  41. #define _GNU_SOURCE    1    /* enable GNU extensions */
  42. #endif /* _GNU_SOURCE */
  43.  
  44. #include <stdio.h>
  45. #include <assert.h>
  46. #ifdef HAVE_LIMITS_H
  47. #include <limits.h>
  48. #endif /* HAVE_LIMITS_H */
  49. #include <ctype.h>
  50. #include <setjmp.h>
  51. #ifdef HAVE_LOCALE_H
  52. #include <locale.h>
  53. #endif /* HAVE_LOCALE_H */
  54. #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
  55. #include <stdarg.h>
  56. #else
  57. #include <varargs.h>
  58. #endif
  59. #include <signal.h>
  60. #include <time.h>
  61. #include <errno.h>
  62. #if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
  63. extern int errno;
  64. #endif
  65. #ifdef HAVE_SIGNUM_H
  66. #include <signum.h>
  67. #endif
  68.  
  69. /* ----------------- System dependencies (with more includes) -----------*/
  70.  
  71. /* This section is the messiest one in the file, not a lot that can be done */
  72.  
  73. /* First, get the ctype stuff right; from Jim Meyering */
  74. #if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
  75. #define ISASCII(c) 1
  76. #else
  77. #define ISASCII(c) isascii(c)
  78. #endif
  79.  
  80. #ifdef isblank
  81. #define ISBLANK(c) (ISASCII(c) && isblank(c))
  82. #else
  83. #define ISBLANK(c) ((c) == ' ' || (c) == '\t')
  84. #endif
  85. #ifdef isgraph
  86. #define ISGRAPH(c) (ISASCII(c) && isgraph(c))
  87. #else
  88. #define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
  89. #endif
  90.  
  91. #define ISPRINT(c) (ISASCII (c) && isprint (c))
  92. #define ISDIGIT(c) (ISASCII (c) && isdigit (c))
  93. #define ISALNUM(c) (ISASCII (c) && isalnum (c))
  94. #define ISALPHA(c) (ISASCII (c) && isalpha (c))
  95. #define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
  96. #define ISLOWER(c) (ISASCII (c) && islower (c))
  97. #define ISPUNCT(c) (ISASCII (c) && ispunct (c))
  98. #define ISSPACE(c) (ISASCII (c) && isspace (c))
  99. #define ISUPPER(c) (ISASCII (c) && isupper (c))
  100. #define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
  101.  
  102.  
  103. #ifdef __STDC__
  104. #define    P(s)    s
  105. #define MALLOC_ARG_T size_t
  106. #else    /* not __STDC__ */
  107. #define    P(s)    ()
  108. #define MALLOC_ARG_T unsigned
  109. #define volatile
  110. #define const
  111. #endif    /* not __STDC__ */
  112.  
  113. #if ! defined(VMS) || (! defined(VAXC) && ! defined(__DECC))
  114. #include <sys/types.h>
  115. #include <sys/stat.h>
  116. #else    /* VMS w/ VAXC or DECC */
  117. #include <types.h>
  118. #include <stat.h>
  119. #include <file.h>    /* avoid <fcntl.h> in io.c */
  120. #ifdef __DECC
  121. /* DEC C implies DECC$SHR, which doesn't have the %g problem of VAXCRTL */
  122. #undef GFMT_WORKAROUND
  123. #endif
  124. #endif    /* VMS w/ VAXC or DECC */
  125.  
  126. #ifdef STDC_HEADERS
  127. #include <stdlib.h>
  128. #else    /* not STDC_HEADERS */
  129. #include "protos.h"
  130. #endif    /* not STDC_HEADERS */
  131.  
  132. #ifdef HAVE_STRING_H
  133. #include <string.h>
  134. #ifdef NEED_MEMORY_H
  135. #include <memory.h>
  136. #endif    /* NEED_MEMORY_H */
  137. #else    /* not HAVE_STRING_H */
  138. #ifdef HAVE_STRINGS_H
  139. #include <strings.h>
  140. #endif    /* HAVE_STRINGS_H */
  141. #endif    /* not HAVE_STRING_H */
  142.  
  143. #ifdef NeXT
  144. #if __GNUC__ < 2 || __GNUC_MINOR__ < 7
  145. #include <libc.h>
  146. #endif
  147. #undef atof
  148. #define getopt GNU_getopt
  149. #define GFMT_WORKAROUND
  150. #endif    /* NeXT */
  151.  
  152. #if defined(atarist) || defined(VMS)
  153. #include <unixlib.h>
  154. #endif    /* atarist || VMS */
  155.  
  156. #if HAVE_UNISTD_H
  157. #include <unistd.h>
  158. #endif    /* HAVE_UNISTD_H */
  159.  
  160. #ifndef HAVE_VPRINTF
  161. /* if you don't have vprintf, try this and cross your fingers. */
  162. #ifdef    HAVE_DOPRNT
  163. #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
  164. #else    /* not HAVE_DOPRNT */
  165. you
  166. lose
  167. #endif    /* not HAVE_DOPRNT */
  168. #endif    /* HAVE_VPRINTF */
  169.  
  170. #ifndef HAVE_SETLOCALE
  171. #define setlocale(locale, val)    /* nothing */
  172. #endif /* HAVE_SETLOCALE */
  173.  
  174. #ifdef VMS
  175. #include "vms/redirect.h"
  176. #endif  /*VMS*/
  177.  
  178. #ifdef atarist
  179. #include "atari/redirect.h"
  180. #endif
  181.  
  182. #define    GNU_REGEX
  183. #ifdef GNU_REGEX
  184. #include "regex.h"
  185. #include "dfa.h"
  186. typedef struct Regexp {
  187.     struct re_pattern_buffer pat;
  188.     struct re_registers regs;
  189.     struct dfa dfareg;
  190.     int dfa;
  191. } Regexp;
  192. #define    RESTART(rp,s)    (rp)->regs.start[0]
  193. #define    REEND(rp,s)    (rp)->regs.end[0]
  194. #define    SUBPATSTART(rp,s,n)    (rp)->regs.start[n]
  195. #define    SUBPATEND(rp,s,n)    (rp)->regs.end[n]
  196. #endif    /* GNU_REGEX */
  197.  
  198. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  199.  
  200. #ifndef AWKNUM
  201. #define AWKNUM    double
  202. #endif
  203.  
  204. #ifndef TRUE
  205. /* a bit hackneyed, but what the heck */
  206. #define TRUE    1
  207. #define FALSE    0
  208. #endif
  209.  
  210. /* Figure out what '\a' really is. */
  211. #ifdef __STDC__
  212. #define BELL    '\a'        /* sure makes life easy, don't it? */
  213. #else
  214. #    if 'z' - 'a' == 25    /* ascii */
  215. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  216. #            define BELL    '\207'
  217. #        else
  218. #            define BELL    '\07'
  219. #        endif
  220. #    else
  221. #        define BELL    '\057'
  222. #    endif
  223. #endif
  224.  
  225. typedef enum nodevals {
  226.     /* illegal entry == 0 */
  227.     Node_illegal,
  228.  
  229.     /* binary operators  lnode and rnode are the expressions to work on */
  230.     Node_times,
  231.     Node_quotient,
  232.     Node_mod,
  233.     Node_plus,
  234.     Node_minus,
  235.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  236.     Node_subscript,
  237.     Node_concat,
  238.     Node_exp,
  239.  
  240.     /* unary operators   subnode is the expression to work on */
  241.     Node_preincrement,
  242.     Node_predecrement,
  243.     Node_postincrement,
  244.     Node_postdecrement,
  245.     Node_unary_minus,
  246.     Node_field_spec,
  247.  
  248.     /* assignments   lnode is the var to assign to, rnode is the exp */
  249.     Node_assign,
  250.     Node_assign_times,
  251.     Node_assign_quotient,
  252.     Node_assign_mod,
  253.     Node_assign_plus,
  254.     Node_assign_minus,
  255.     Node_assign_exp,
  256.  
  257.     /* boolean binaries   lnode and rnode are expressions */
  258.     Node_and,
  259.     Node_or,
  260.  
  261.     /* binary relationals   compares lnode and rnode */
  262.     Node_equal,
  263.     Node_notequal,
  264.     Node_less,
  265.     Node_greater,
  266.     Node_leq,
  267.     Node_geq,
  268.     Node_match,
  269.     Node_nomatch,
  270.  
  271.     /* unary relationals   works on subnode */
  272.     Node_not,
  273.  
  274.     /* program structures */
  275.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  276.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  277.     Node_statement_list,    /* lnode is statement, rnode is more list */
  278.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  279.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  280.     Node_param_list,    /* lnode is a variable, rnode is more list */
  281.  
  282.     /* keywords */
  283.     Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  284.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  285.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  286.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  287.     Node_K_break,        /* no subs */
  288.     Node_K_continue,    /* no subs */
  289.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  290.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  291.     Node_K_next,        /* no subs */
  292.     Node_K_exit,        /* subnode is return value, or NULL */
  293.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  294.     Node_K_return,        /* lnode is return value */
  295.     Node_K_delete,        /* lnode is array, rnode is subscript */
  296.     Node_K_getline,        /* lnode is opt var, rnode is redirection */
  297.     Node_K_function,    /* lnode is statement list, rnode is params */
  298.     Node_K_nextfile,    /* no subs */
  299.  
  300.     /* I/O redirection for print statements */
  301.     Node_redirect_output,    /* subnode is where to redirect */
  302.     Node_redirect_append,    /* subnode is where to redirect */
  303.     Node_redirect_pipe,    /* subnode is where to redirect */
  304.     Node_redirect_pipein,    /* subnode is where to redirect */
  305.     Node_redirect_input,    /* subnode is where to redirect */
  306.  
  307.     /* Variables */
  308.     Node_var,        /* rnode is value, lnode is array stuff */
  309.     Node_var_array,        /* array is ptr to elements, asize num of eles */
  310.     Node_val,        /* node is a value - type in flags */
  311.  
  312.     /* Builtins   subnode is explist to work on, proc is func to call */
  313.     Node_builtin,
  314.  
  315.     /*
  316.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  317.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  318.      * is a flag indicating whether or not this range has been entered.
  319.      */
  320.     Node_line_range,
  321.  
  322.     /*
  323.      * boolean test of membership in array lnode is string-valued
  324.      * expression rnode is array name 
  325.      */
  326.     Node_in_array,
  327.  
  328.     Node_func,        /* lnode is param. list, rnode is body */
  329.     Node_func_call,        /* lnode is name, rnode is argument list */
  330.  
  331.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  332.     Node_regex,        /* a regexp, text, compiled, flags, etc */
  333.     Node_hashnode,        /* an identifier in the symbol table */
  334.     Node_ahash,        /* an array element */
  335.     Node_NF,        /* variables recognized in the grammar */
  336.     Node_NR,
  337.     Node_FNR,
  338.     Node_FS,
  339.     Node_RS,
  340.     Node_FIELDWIDTHS,
  341.     Node_IGNORECASE,
  342.     Node_OFS,
  343.     Node_ORS,
  344.     Node_OFMT,
  345.     Node_CONVFMT,
  346.     Node_final        /* sentry value, not legal */
  347. } NODETYPE;
  348.  
  349. /*
  350.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  351.  * space usage, at the expense of cleanliness.  Alter at own risk.
  352.  */
  353. typedef struct exp_node {
  354.     union {
  355.         struct {
  356.             union {
  357.                 struct exp_node *lptr;
  358.                 char *param_name;
  359.                 long ll;
  360.             } l;
  361.             union {
  362.                 struct exp_node *rptr;
  363.                 struct exp_node *(*pptr)();
  364.                 Regexp *preg;
  365.                 struct for_loop_header *hd;
  366.                 struct exp_node **av;
  367.                 int r_ent;    /* range entered */
  368.             } r;
  369.             union {
  370.                 struct exp_node *extra;
  371.                 long xl;
  372.             } x;
  373.             char *name;
  374.             short number;
  375.             unsigned char reflags;
  376. #                define    CASE    1
  377. #                define    CONST    2
  378. #                define    FS_DFLT    4
  379.         } nodep;
  380.         struct {
  381.             AWKNUM fltnum;    /* this is here for optimal packing of
  382.                      * the structure on many machines
  383.                      */
  384.             char *sp;
  385.             size_t slen;
  386.             long sref;
  387.             int idx;
  388.         } val;
  389.         struct {
  390.             struct exp_node *next;
  391.             char *name;
  392.             size_t length;
  393.             struct exp_node *value;
  394.         } hash;
  395. #define    hnext    sub.hash.next
  396. #define    hname    sub.hash.name
  397. #define    hlength    sub.hash.length
  398. #define    hvalue    sub.hash.value
  399.         struct {
  400.             struct exp_node *next;
  401.             struct exp_node *name;
  402.             struct exp_node *value;
  403.         } ahash;
  404. #define    ahnext    sub.ahash.next
  405. #define    ahname    sub.ahash.name
  406. #define    ahvalue    sub.ahash.value
  407.     } sub;
  408.     NODETYPE type;
  409.     unsigned short flags;
  410. #        define    MALLOC    1    /* can be free'd */
  411. #        define    TEMP    2    /* should be free'd */
  412. #        define    PERM    4    /* can't be free'd */
  413. #        define    STRING    8    /* assigned as string */
  414. #        define    STR    16    /* string value is current */
  415. #        define    NUM    32    /* numeric value is current */
  416. #        define    NUMBER    64    /* assigned as number */
  417. #        define    MAYBE_NUM 128    /* user input: if NUMERIC then
  418.                      * a NUMBER */
  419. #        define    ARRAYMAXED 256    /* array is at max size */
  420. #        define    SCALAR     512    /* used as scalar, can't be array */
  421. #        define    FUNC    1024    /* this parameter is really a
  422.                      * function name; see awk.y */
  423. #        define    FIELD    2048    /* this is a field */
  424.  
  425.     char *vname;    /* variable's name */
  426. } NODE;
  427.  
  428. #define lnode    sub.nodep.l.lptr
  429. #define nextp    sub.nodep.l.lptr
  430. #define rnode    sub.nodep.r.rptr
  431. #define source_file    sub.nodep.name
  432. #define    source_line    sub.nodep.number
  433. #define    param_cnt    sub.nodep.number
  434. #define param    sub.nodep.l.param_name
  435.  
  436. #define subnode    lnode
  437. #define proc    sub.nodep.r.pptr
  438.  
  439. #define re_reg    sub.nodep.r.preg
  440. #define re_flags sub.nodep.reflags
  441. #define re_text lnode
  442. #define re_exp    sub.nodep.x.extra
  443. #define    re_cnt    sub.nodep.number
  444.  
  445. #define forsub    lnode
  446. #define forloop    rnode->sub.nodep.r.hd
  447.  
  448. #define stptr    sub.val.sp
  449. #define stlen    sub.val.slen
  450. #define stref    sub.val.sref
  451. #define    stfmt    sub.val.idx
  452.  
  453. #define numbr    sub.val.fltnum
  454.  
  455. #define var_value lnode
  456. #define var_array sub.nodep.r.av
  457. #define array_size sub.nodep.l.ll
  458. #define table_size sub.nodep.x.xl
  459.  
  460. #define condpair lnode
  461. #define triggered sub.nodep.r.r_ent
  462.  
  463. /* a regular for loop */
  464. typedef struct for_loop_header {
  465.     NODE *init;
  466.     NODE *cond;
  467.     NODE *incr;
  468. } FOR_LOOP_HEADER;
  469.  
  470. /* for "for(iggy in foo) {" */
  471. struct search {
  472.     NODE *sym;
  473.     size_t idx;
  474.     NODE *bucket;
  475.     NODE *retval;
  476. };
  477.  
  478. /* for faster input, bypass stdio */
  479. typedef struct iobuf {
  480.     const char *name;
  481.     int fd;
  482.     char *buf;
  483.     char *off;
  484.     char *end;
  485.     size_t size;    /* this will be determined by an fstat() call */
  486.     int cnt;
  487.     long secsiz;
  488.     int flag;
  489. #        define    IOP_IS_TTY    1
  490. #        define    IOP_IS_INTERNAL    2
  491. #        define    IOP_NO_FREE    4
  492. #        define    IOP_MMAPPED    8
  493. #        define    IOP_NOFREE_OBJ    16
  494.     int (*getrec)();
  495. } IOBUF;
  496.  
  497. typedef void (*Func_ptr)();
  498.  
  499. /* structure used to dynamically maintain a linked-list of open files/pipes */
  500. struct redirect {
  501.     unsigned int flag;
  502. #        define    RED_FILE    1
  503. #        define    RED_PIPE    2
  504. #        define    RED_READ    4
  505. #        define    RED_WRITE    8
  506. #        define    RED_APPEND    16
  507. #        define    RED_NOBUF    32
  508. #        define    RED_USED    64    /* closed temporarily to reuse fd */
  509. #        define    RED_EOF        128
  510.     char *value;
  511.     FILE *fp;
  512.     FILE *ifp;    /* input fp, needed for PIPES_SIMULATED */
  513.     IOBUF *iop;
  514.     int pid;
  515.     int status;
  516.     struct redirect *prev;
  517.     struct redirect *next;
  518. };
  519.  
  520. /* structure for our source, either a command line string or a source file */
  521. struct src {
  522.        enum srctype { CMDLINE = 1, SOURCEFILE } stype;
  523.        char *val;
  524. };
  525.  
  526. /* longjmp return codes, must be nonzero */
  527. /* Continue means either for loop/while continue, or next input record */
  528. #define TAG_CONTINUE 1
  529. /* Break means either for/while break, or stop reading input */
  530. #define TAG_BREAK 2
  531. /* Return means return from a function call; leave value in ret_node */
  532. #define    TAG_RETURN 3
  533.  
  534. #ifndef LONG_MAX
  535. #define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
  536. #endif
  537. #ifndef ULONG_MAX
  538. #define ULONG_MAX (~(unsigned long)0)
  539. #endif
  540. #ifndef LONG_MIN
  541. #define LONG_MIN ((long)(-LONG_MAX - 1L))
  542. #endif
  543. #define HUGE    LONG_MAX 
  544.  
  545. /* -------------------------- External variables -------------------------- */
  546. /* gawk builtin variables */
  547. extern long NF;
  548. extern long NR;
  549. extern long FNR;
  550. extern int IGNORECASE;
  551. extern int RS_is_null;
  552. extern char *OFS;
  553. extern int OFSlen;
  554. extern char *ORS;
  555. extern int ORSlen;
  556. extern char *OFMT;
  557. extern char *CONVFMT;
  558. extern int CONVFMTidx;
  559. extern int OFMTidx;
  560. extern NODE *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
  561. extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
  562. extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
  563. extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node; 
  564. extern NODE **stack_ptr;
  565. extern NODE *Nnull_string;
  566. extern NODE **fields_arr;
  567. extern int sourceline;
  568. extern char *source;
  569. extern NODE *expression_value;
  570.  
  571. #if __GNUC__ < 2
  572. extern NODE *_t;    /* used as temporary in tree_eval */
  573. #endif
  574.  
  575. extern NODE *nextfree;
  576. extern int field0_valid;
  577. extern int do_traditional;
  578. extern int do_posix;
  579. extern int do_lint;
  580. extern int do_lint_old;
  581. extern int do_intervals;
  582. extern int in_begin_rule;
  583. extern int in_end_rule;
  584.  
  585. extern const char *myname;
  586.  
  587. extern char quote;
  588. extern char *defpath;
  589. extern char envsep;
  590.  
  591. extern char casetable[];    /* for case-independent regexp matching */
  592.  
  593. /* ------------------------- Pseudo-functions ------------------------- */
  594.  
  595. #define is_identchar(c)        (isalnum(c) || (c) == '_')
  596. #define isnondecimal(str)    (((str)[0]) == '0' && (ISDIGIT((str)[1]) \
  597.                     || (str)[1] == 'x' || (str)[1] == 'X'))
  598.  
  599. #ifdef MPROF
  600. #define    getnode(n)    emalloc(n, NODE *, sizeof(NODE), "getnode")
  601. #define    freenode(n)    free(n)
  602. #else    /* not MPROF */
  603. #define    getnode(n)    if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
  604.             else n = more_nodes()
  605. #define    freenode(n)    ((n)->flags &= ~SCALAR, (n)->nextp = nextfree, nextfree = (n))
  606. #endif    /* not MPROF */
  607.  
  608. #ifdef DEBUG
  609. #undef freenode
  610. #define    get_lhs(p, a)    r_get_lhs((p), (a))
  611. #define    m_tree_eval(t, iscond)    r_tree_eval(t, iscond)
  612. #else
  613. #define    get_lhs(p, a)    ((p)->type == Node_var ? (&(p)->var_value) : \
  614.             r_get_lhs((p), (a)))
  615. #if __GNUC__ >= 2
  616. #define    m_tree_eval(t, iscond) \
  617.                         ({NODE * _t = (t);                 \
  618.                if (_t == NULL)                 \
  619.                    _t = Nnull_string;          \
  620.                else {                          \
  621.                    switch(_t->type) {          \
  622.                    case Node_val:              \
  623.                    break;                  \
  624.                    case Node_var:              \
  625.                    _t = _t->var_value;     \
  626.                    break;                  \
  627.                    default:                    \
  628.                    _t = r_tree_eval(_t, iscond);\
  629.                    break;                  \
  630.                    }                           \
  631.                }                               \
  632.                _t;})
  633. #else
  634. #define    m_tree_eval(t, iscond)    (_t = (t), _t == NULL ? Nnull_string : \
  635.             (_t->type == Node_param_list ? \
  636.               r_tree_eval(_t, iscond) : \
  637.             (_t->type == Node_val ? _t : \
  638.             (_t->type == Node_var ? _t->var_value : \
  639.               r_tree_eval(_t, iscond)))))
  640. #endif /* __GNUC__ */
  641. #endif /* not DEBUG */
  642. #define tree_eval(t)    m_tree_eval(t, FALSE)
  643.  
  644. #define    make_number(x)    mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER))
  645. #define    tmp_number(x)    mk_number((x), (unsigned int)(MALLOC|TEMP|NUM|NUMBER))
  646.  
  647. #define    free_temp(n)    do { if ((n)->flags&TEMP) { unref(n); }} while (FALSE)
  648. #define    make_string(s, l)    make_str_node((s), (size_t) (l), FALSE)
  649. #define        SCAN            1
  650. #define        ALREADY_MALLOCED    2
  651.  
  652. #define    cant_happen()    r_fatal("internal error line %d, file: %s", \
  653.                 __LINE__, __FILE__);
  654.  
  655. #ifdef HAVE_STRINGIZE
  656. #define    emalloc(var,ty,x,str)    (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
  657.                  (fatal("%s: %s: can't allocate memory (%s)",\
  658.                     (str), #var, strerror(errno)),0))
  659. #define    erealloc(var,ty,x,str)    (void)((var=(ty)realloc((char *)var,\
  660.                           (MALLOC_ARG_T)(x))) ||\
  661.                  (fatal("%s: %s: can't allocate memory (%s)",\
  662.                     (str), #var, strerror(errno)),0))
  663. #else /* HAVE_STRINGIZE */
  664. #define    emalloc(var,ty,x,str)    (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
  665.                  (fatal("%s: %s: can't allocate memory (%s)",\
  666.                     (str), "var", strerror(errno)),0))
  667. #define    erealloc(var,ty,x,str)    (void)((var=(ty)realloc((char *)var,\
  668.                           (MALLOC_ARG_T)(x))) ||\
  669.                  (fatal("%s: %s: can't allocate memory (%s)",\
  670.                     (str), "var", strerror(errno)),0))
  671. #endif /* HAVE_STRINGIZE */
  672.  
  673. #ifdef DEBUG
  674. #define    force_number    r_force_number
  675. #define    force_string    r_force_string
  676. #else /* not DEBUG */
  677. #ifdef lint
  678. extern AWKNUM force_number();
  679. #endif
  680. #if __GNUC__ >= 2
  681. #define    force_number(n)    ({NODE *_tn = (n);\
  682.             (_tn->flags & NUM) ?_tn->numbr : r_force_number(_tn);})
  683. #define    force_string(s)    ({NODE *_ts = (s);\
  684.               ((_ts->flags & STR) && \
  685.                (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
  686.               _ts : r_force_string(_ts);})
  687. #else
  688. #ifdef MSDOS
  689. extern double _msc51bug;
  690. #define    force_number(n)    (_msc51bug=(_t = (n),\
  691.               (_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  692. #else /* not MSDOS */
  693. #define    force_number(n)    (_t = (n),\
  694.              (_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  695. #endif /* not MSDOS */
  696. #define    force_string(s)    (_t = (s),((_t->flags & STR) && \
  697.                    (_t->stfmt == -1 || \
  698.                     _t->stfmt == CONVFMTidx))? \
  699.              _t : r_force_string(_t))
  700. #endif /* not __GNUC__ */
  701. #endif /* not DEBUG */
  702.  
  703. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  704. #define    STREQN(a,b,n)    ((n) && *(a)== *(b) && \
  705.              strncmp((a), (b), (size_t) (n)) == 0)
  706.  
  707. #define fatal        set_loc(__FILE__, __LINE__), r_fatal
  708.  
  709. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  710.  
  711. /* array.c */
  712. extern NODE *concat_exp P((NODE *tree));
  713. extern void assoc_clear P((NODE *symbol));
  714. extern unsigned int hash P((const char *s, size_t len, unsigned long hsize));
  715. extern int in_array P((NODE *symbol, NODE *subs));
  716. extern NODE **assoc_lookup P((NODE *symbol, NODE *subs));
  717. extern void do_delete P((NODE *symbol, NODE *tree));
  718. extern void assoc_scan P((NODE *symbol, struct search *lookat));
  719. extern void assoc_next P((struct search *lookat));
  720. /* awktab.c */
  721. extern char *tokexpand P((void));
  722. extern char nextc P((void));
  723. extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
  724. extern NODE *install P((char *name, NODE *value));
  725. extern NODE *lookup P((const char *name));
  726. extern NODE *variable P((char *name, int can_free, NODETYPE type));
  727. extern int yyparse P((void));
  728. /* builtin.c */
  729. extern double double_to_int P((double d));
  730. extern NODE *do_exp P((NODE *tree));
  731. extern NODE *do_fflush P((NODE *tree));
  732. extern NODE *do_index P((NODE *tree));
  733. extern NODE *do_int P((NODE *tree));
  734. extern NODE *do_length P((NODE *tree));
  735. extern NODE *do_log P((NODE *tree));
  736. extern NODE *do_sprintf P((NODE *tree));
  737. extern void do_printf P((NODE *tree));
  738. extern void print_simple P((NODE *tree, FILE *fp));
  739. extern NODE *do_sqrt P((NODE *tree));
  740. extern NODE *do_substr P((NODE *tree));
  741. extern NODE *do_strftime P((NODE *tree));
  742. extern NODE *do_systime P((NODE *tree));
  743. extern NODE *do_system P((NODE *tree)); 
  744. extern void do_print P((NODE *tree));
  745. extern NODE *do_tolower P((NODE *tree));
  746. extern NODE *do_toupper P((NODE *tree));
  747. extern NODE *do_atan2 P((NODE *tree));
  748. extern NODE *do_sin P((NODE *tree));
  749. extern NODE *do_cos P((NODE *tree));
  750. extern NODE *do_rand P((NODE *tree));
  751. extern NODE *do_srand P((NODE *tree));
  752. extern NODE *do_match P((NODE *tree));
  753. extern NODE *do_gsub P((NODE *tree));
  754. extern NODE *do_sub P((NODE *tree));
  755. extern NODE *do_gensub P((NODE *tree));
  756. #ifdef BITOPS
  757. extern NODE *do_lshift P((NODE *tree));
  758. extern NODE *do_rshift P((NODE *tree));
  759. extern NODE *do_and P((NODE *tree));
  760. extern NODE *do_or P((NODE *tree));
  761. extern NODE *do_xor P((NODE *tree));
  762. extern NODE *do_compl P((NODE *tree));
  763. extern NODE *do_strtonum P((NODE *tree));
  764. #endif /* BITOPS */
  765. #if defined(BITOPS) || defined(NONDECDATA)
  766. extern AWKNUM nondec2awknum P((char *str, size_t len));
  767. #endif /* defined(BITOPS) || defined(NONDECDATA) */
  768. /* Riscos */
  769. extern NODE *do_sysvar P((NODE *tree));
  770. extern NODE *do_exists P((NODE *tree));
  771. extern NODE *do_filetype P((NODE *tree));
  772. extern NODE *do_later P((NODE *tree)); 
  773. /* eval.c */
  774. extern int interpret P((NODE *volatile tree));
  775. extern NODE *r_tree_eval P((NODE *tree, int iscond));
  776. extern int cmp_nodes P((NODE *t1, NODE *t2));
  777. extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign));
  778. extern void set_IGNORECASE P((void));
  779. void set_OFS P((void));
  780. void set_ORS P((void));
  781. void set_OFMT P((void));
  782. void set_CONVFMT P((void));
  783. /* field.c */
  784. extern void init_fields P((void));
  785. extern void set_record P((char *buf, int cnt, int freeold));
  786. extern void reset_record P((void));
  787. extern void set_NF P((void));
  788. extern NODE **get_field P((long num, Func_ptr *assign));
  789. extern NODE *do_split P((NODE *tree));
  790. extern void set_FS P((void));
  791. extern void set_FS_if_not_FIELDWIDTHS P((void));
  792. extern void set_RS P((void));
  793. extern void set_FIELDWIDTHS P((void));
  794. extern int using_fieldwidths P((void));
  795. /* gawkmisc.c */
  796. extern char *gawk_name P((const char *filespec));
  797. extern void os_arg_fixup P((int *argcp, char ***argvp));
  798. extern int os_devopen P((const char *name, int flag));
  799. extern int optimal_bufsize P((int fd, struct stat *sbuf));
  800. extern int ispath P((const char *file));
  801. extern int isdirpunct P((int c));
  802. /* io.c */
  803. extern void set_FNR P((void));
  804. extern void set_NR P((void));
  805. extern void do_input P((void));
  806. extern struct redirect *redirect P((NODE *tree, int *errflg));
  807. extern NODE *do_close P((NODE *tree));
  808. extern int flush_io P((void));
  809. extern int close_io P((void));
  810. extern int devopen P((const char *name, const char *mode));
  811. extern int pathopen P((const char *file));
  812. extern NODE *do_getline P((NODE *tree));
  813. extern void do_nextfile P((void));
  814. extern struct redirect *getredirect P((char *str, int len));
  815. /* main.c */
  816. extern int main P((int argc, char **argv));
  817. extern void load_environ P((void));
  818. extern char *arg_assign P((char *arg));
  819. extern RETSIGTYPE catchsig P((int sig, int code));
  820. /* msg.c */
  821. extern void err P((const char *s, const char *emsg, va_list argp));
  822. #if _MSC_VER == 510
  823. extern void msg P((va_list va_alist, ...));
  824. extern void error P((va_list va_alist, ...));
  825. extern void warning P((va_list va_alist, ...));
  826. extern void set_loc P((char *file, int line));
  827. extern void r_fatal P((va_list va_alist, ...));
  828. #else
  829. #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
  830. extern void msg (char *mesg, ...);
  831. extern void error (char *mesg, ...);
  832. extern void warning (char *mesg, ...);
  833. extern void set_loc (char *file, int line);
  834. extern void r_fatal (char *mesg, ...);
  835. #else
  836. extern void msg ();
  837. extern void error ();
  838. extern void warning ();
  839. extern void set_loc ();
  840. extern void r_fatal ();
  841. #endif
  842. #endif
  843. /* node.c */
  844. extern AWKNUM r_force_number P((NODE *n));
  845. extern NODE *format_val P((char *format, int index, NODE *s));
  846. extern NODE *r_force_string P((NODE *s));
  847. extern NODE *dupnode P((NODE *n));
  848. extern NODE *mk_number P((AWKNUM x, unsigned int flags));
  849. extern NODE *make_str_node P((char *s, size_t len, int scan ));
  850. extern NODE *tmp_string P((char *s, size_t len ));
  851. extern NODE *more_nodes P((void));
  852. #ifdef DEBUG
  853. extern void freenode P((NODE *it));
  854. #endif
  855. extern void unref P((NODE *tmp));
  856. extern int parse_escape P((char **string_ptr));
  857. /* re.c */
  858. extern Regexp *make_regexp P((char *s, size_t len, int ignorecase, int dfa));
  859. extern int research P((Regexp *rp, char *str, int start,
  860.                size_t len, int need_start));
  861. extern void refree P((Regexp *rp));
  862. extern void reg_error P((const char *s));
  863. extern Regexp *re_update P((NODE *t));
  864. extern void resyntax P((int syntax));
  865. extern void resetup P((void));
  866. extern int avoid_dfa P((NODE *re, char *str, size_t len));    /* temporary */
  867.  
  868. /* strncasecmp.c */
  869. extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
  870.  
  871. #if defined(atarist)
  872. #if defined(PIPES_SIMULATED)
  873. /* atari/tmpnam.c */
  874. extern char *tmpnam P((char *buf));
  875. extern char *tempnam P((const char *path, const char *base));
  876. #else
  877. #include <wait.h>
  878. #endif
  879. #include <fcntl.h>
  880. #define INVALID_HANDLE  (__SMALLEST_VALID_HANDLE - 1)
  881. #else
  882. #define INVALID_HANDLE (-1)
  883. #endif /* atarist */
  884.  
  885. #ifndef STATIC
  886. #define STATIC static
  887. #endif
  888.  
  889. #ifdef C_ALLOCA
  890. /* The __hpux check is to avoid conflicts with bison's definition of
  891.    alloca() in awktab.c.*/
  892. #if (defined(__STDC__) && __STDC__) || defined (__hpux)
  893. extern void *alloca P((unsigned));
  894. #else
  895. extern char *alloca P((unsigned));
  896. #endif
  897. #endif
  898.