home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnuawk.zip / awk.h < prev    next >
C/C++ Source or Header  |  1997-05-01  |  26KB  |  883 lines

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