home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compcomp / gnuawk / awk.h < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-10  |  16.9 KB  |  618 lines

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming 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 1, or (at your option)
  14.  * 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 GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* ------------------------------ Includes ------------------------------ */
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <setjmp.h>
  30. #include <varargs.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <errno.h>
  34.  
  35. #include "regex.h"
  36.  
  37. /* ------------------- System Functions, Variables, etc ------------------- */
  38.  
  39. #ifdef MSDOS
  40. extern errno;
  41. #endif
  42.  
  43. /* nasty nasty SunOS-ism */
  44. #ifdef sparc
  45. #include <alloca.h>
  46. #ifdef lint
  47. extern char *alloca();
  48. #endif
  49. #else
  50. extern char *alloca();
  51. #endif
  52. #ifdef SPRINTF_INT
  53. extern int sprintf();
  54. #else    /* not USG */
  55. /* nasty nasty berkelixm */
  56. #define setjmp    _setjmp
  57. #define longjmp    _longjmp
  58.  
  59. extern char *sprintf();
  60. #endif
  61. /*
  62.  * if you don't have vprintf, but you are BSD, the version defined in
  63.  * vprintf.c should do the trick.  Otherwise, use this and cross your fingers.
  64.  */
  65. #if defined(VPRINTF_MISSING) && !defined(DOPRNT_MISSING) && !defined(BSDSTDIO)
  66. #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
  67. #endif
  68.  
  69. #ifdef __STDC__
  70. extern void *malloc(unsigned), *realloc(void *, unsigned);
  71. extern void free(char *);
  72. extern char *getenv(char *);
  73.  
  74. extern char *strcpy(char *, char *), *strcat(char *, char *), *strncpy(char *, char *, int);
  75. extern int strcmp(char *, char *);
  76. extern int strncmp(char *, char *, int);
  77. extern int strncasecmp(char *, char *, int);
  78. extern char *strerror(int);
  79. extern char *strchr(char *, int);
  80. #ifndef MSDOS
  81. extern int strlen(char *);
  82. extern    char *memcpy(char *, char *, int);
  83. extern    char *memset(char *, int, int);
  84. #endif
  85. extern    int memcmp(char *, char *, int);
  86.  
  87. /* extern int fprintf(FILE *, char *, ...); */
  88. extern int fprintf();
  89. extern int vfprintf();
  90. #ifndef MSDOS
  91. extern int fwrite(char *, int, int, FILE *);
  92. #endif
  93. extern int fflush(FILE *);
  94. extern int fclose(FILE *);
  95. extern int pclose(FILE *);
  96. #ifndef MSDOS
  97. extern int fputs(char *, FILE *);
  98. #endif
  99. extern void abort();
  100. extern int isatty(int);
  101. extern void exit(int);
  102. extern int system(char *);
  103. extern int sscanf(/* char *, char *, ... */);
  104.  
  105. extern double atof(char *);
  106. extern int fstat(int, struct stat *);
  107. extern off_t lseek(int, off_t, int);
  108. extern int fseek(FILE *, long, int);
  109. extern int close(int);
  110. extern int open();
  111. extern int pipe(int *);
  112. extern int dup2(int, int);
  113. #ifndef MSDOS
  114. extern int unlink(char *);
  115. #endif
  116. extern int fork();
  117. extern int execl(/* char *, char *, ... */);
  118. extern int read(int, char *, int);
  119. extern int wait(int *);
  120. extern void _exit(int);
  121. #else
  122. extern void _exit();
  123. extern int wait();
  124. extern int read();
  125. extern int execl();
  126. extern int fork();
  127. extern int unlink();
  128. extern int dup2();
  129. extern int pipe();
  130. extern int open();
  131. extern int close();
  132. extern int fseek();
  133. extern off_t lseek();
  134. extern int fstat();
  135. extern void exit();
  136. extern int system();
  137. extern int isatty();
  138. extern void abort();
  139. extern int fputs();
  140. extern int fclose();
  141. extern int pclose();
  142. extern int fflush();
  143. extern int fwrite();
  144. extern int fprintf();
  145. extern int vfprintf();
  146. extern int sscanf();
  147. extern char *malloc(), *realloc();
  148. extern void free();
  149. extern char *getenv();
  150.  
  151. extern int strcmp();
  152. extern int strncmp();
  153. extern int strncasecmp();
  154. extern int strlen();
  155. extern char *strcpy(), *strcat(), *strncpy();
  156. extern    char *memset();
  157. extern    int memcmp();
  158. extern    char *memcpy();
  159. extern char *strerror();
  160. extern char *strchr();
  161.  
  162. extern double atof();
  163. #endif
  164.  
  165. #ifndef MSDOS
  166. extern int errno;
  167. #endif    /* MSDOS */
  168.  
  169. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  170. #define AWKNUM    double
  171.  
  172. typedef enum {
  173.     /* illegal entry == 0 */
  174.     Node_illegal,
  175.  
  176.     /* binary operators  lnode and rnode are the expressions to work on */
  177.     Node_times,
  178.     Node_quotient,
  179.     Node_mod,
  180.     Node_plus,
  181.     Node_minus,
  182.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  183.     Node_subscript,
  184.     Node_concat,
  185.     Node_exp,
  186.  
  187.     /* unary operators   subnode is the expression to work on */
  188. /*10*/    Node_preincrement,
  189.     Node_predecrement,
  190.     Node_postincrement,
  191.     Node_postdecrement,
  192.     Node_unary_minus,
  193.     Node_field_spec,
  194.  
  195.     /* assignments   lnode is the var to assign to, rnode is the exp */
  196.     Node_assign,
  197.     Node_assign_times,
  198.     Node_assign_quotient,
  199.     Node_assign_mod,
  200. /*20*/    Node_assign_plus,
  201.     Node_assign_minus,
  202.     Node_assign_exp,
  203.  
  204.     /* boolean binaries   lnode and rnode are expressions */
  205.     Node_and,
  206.     Node_or,
  207.  
  208.     /* binary relationals   compares lnode and rnode */
  209.     Node_equal,
  210.     Node_notequal,
  211.     Node_less,
  212.     Node_greater,
  213.     Node_leq,
  214. /*30*/    Node_geq,
  215.     Node_match,
  216.     Node_nomatch,
  217.  
  218.     /* unary relationals   works on subnode */
  219.     Node_not,
  220.  
  221.     /* program structures */
  222.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  223.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  224.     Node_statement_list,    /* lnode is statement, rnode is more list */
  225.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  226.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  227.     Node_param_list,    /* lnode is a variable, rnode is more list */
  228.  
  229.     /* keywords */
  230. /*40*/    Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  231.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  232.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  233.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  234.     Node_K_break,        /* no subs */
  235.     Node_K_continue,    /* no stuff */
  236.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  237.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  238.     Node_K_next,        /* no subs */
  239.     Node_K_exit,        /* subnode is return value, or NULL */
  240.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  241.     Node_K_return,
  242.     Node_K_delete,
  243.     Node_K_getline,
  244.     Node_K_function,    /* lnode is statement list, rnode is params */
  245.  
  246.     /* I/O redirection for print statements */
  247.     Node_redirect_output,    /* subnode is where to redirect */
  248.     Node_redirect_append,    /* subnode is where to redirect */
  249.     Node_redirect_pipe,    /* subnode is where to redirect */
  250.     Node_redirect_pipein,    /* subnode is where to redirect */
  251.     Node_redirect_input,    /* subnode is where to redirect */
  252.  
  253.     /* Variables */
  254.     Node_var,        /* rnode is value, lnode is array stuff */
  255.     Node_var_array,        /* array is ptr to elements, asize num of
  256.                  * eles */
  257.     Node_val,        /* node is a value - type in flags */
  258.  
  259.     /* Builtins   subnode is explist to work on, proc is func to call */
  260.     Node_builtin,
  261.  
  262.     /*
  263.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  264.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  265.      * is a flag indicating whether or not this range has been entered.
  266.      */
  267.     Node_line_range,
  268.  
  269.     /*
  270.      * boolean test of membership in array lnode is string-valued
  271.      * expression rnode is array name 
  272.      */
  273.     Node_in_array,
  274.  
  275.     Node_func,        /* lnode is param. list, rnode is body */
  276.     Node_func_call,        /* lnode is name, rnode is argument list */
  277.  
  278.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  279.     Node_regex,
  280.     Node_hashnode,
  281.     Node_ahash,
  282. } NODETYPE;
  283.  
  284. /*
  285.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  286.  * space usage, at the expense of cleanliness.  Alter at own risk.
  287.  */
  288. typedef struct exp_node {
  289.     union {
  290.         struct {
  291.             union {
  292.                 struct exp_node *lptr;
  293.                 char *param_name;
  294.                 char *retext;
  295.                 struct exp_node *nextnode;
  296.             } l;
  297.             union {
  298.                 struct exp_node *rptr;
  299.                 struct exp_node *(*pptr) ();
  300.                 struct re_pattern_buffer *preg;
  301.                 struct for_loop_header *hd;
  302.                 struct exp_node **av;
  303.                 int r_ent;    /* range entered */
  304.             } r;
  305.             char *name;
  306.             short number;
  307.             unsigned char recase;
  308.         } nodep;
  309.         struct {
  310.             AWKNUM fltnum;    /* this is here for optimal packing of
  311.                      * the structure on many machines
  312.                      */
  313.             char *sp;
  314.             short slen;
  315.             unsigned char sref;
  316.         } val;
  317.         struct {
  318.             struct exp_node *next;
  319.             char *name;
  320.             int length;
  321.             struct exp_node *value;
  322.         } hash;
  323. #define    hnext    sub.hash.next
  324. #define    hname    sub.hash.name
  325. #define    hlength    sub.hash.length
  326. #define    hvalue    sub.hash.value
  327.         struct {
  328.             struct exp_node *next;
  329.             struct exp_node *name;
  330.             struct exp_node *value;
  331.         } ahash;
  332. #define    ahnext    sub.ahash.next
  333. #define    ahname    sub.ahash.name
  334. #define    ahvalue    sub.ahash.value
  335.     } sub;
  336.     NODETYPE type;
  337.     unsigned char flags;
  338. #            define    MEM    0x7
  339. #            define    MALLOC    1    /* can be free'd */
  340. #            define    TEMP    2    /* should be free'd */
  341. #            define    PERM    4    /* can't be free'd */
  342. #            define    VAL    0x18
  343. #            define    NUM    8    /* numeric value is valid */
  344. #            define    STR    16    /* string value is valid */
  345. #            define    NUMERIC    32    /* entire field is numeric */
  346. } NODE;
  347.  
  348. #define lnode    sub.nodep.l.lptr
  349. #define nextp    sub.nodep.l.nextnode
  350. #define rnode    sub.nodep.r.rptr
  351. #define source_file    sub.nodep.name
  352. #define    source_line    sub.nodep.number
  353. #define    param_cnt    sub.nodep.number
  354. #define param    sub.nodep.l.param_name
  355.  
  356. #define subnode    lnode
  357. #define proc    sub.nodep.r.pptr
  358.  
  359. #define reexp    lnode
  360. #define rereg    sub.nodep.r.preg
  361. #define re_case sub.nodep.recase
  362. #define re_text sub.nodep.l.retext
  363.  
  364. #define forsub    lnode
  365. #define forloop    rnode->sub.nodep.r.hd
  366.  
  367. #define stptr    sub.val.sp
  368. #define stlen    sub.val.slen
  369. #define stref    sub.val.sref
  370. #define    valstat    flags
  371.  
  372. #define numbr    sub.val.fltnum
  373.  
  374. #define var_value lnode
  375. #define var_array sub.nodep.r.av
  376.  
  377. #define condpair lnode
  378. #define triggered sub.nodep.r.r_ent
  379.  
  380. #define HASHSIZE 101
  381.  
  382. typedef struct for_loop_header {
  383.     NODE *init;
  384.     NODE *cond;
  385.     NODE *incr;
  386. } FOR_LOOP_HEADER;
  387.  
  388. /* for "for(iggy in foo) {" */
  389. struct search {
  390.     int numleft;
  391.     NODE **arr_ptr;
  392.     NODE *bucket;
  393.     NODE *retval;
  394. };
  395.  
  396. /* for faster input, bypass stdio */
  397. typedef struct iobuf {
  398.     int fd;
  399.     char *buf;
  400.     char *off;
  401.     int size;    /* this will be determined by an fstat() call */
  402.     int cnt;
  403.     char *secbuf;
  404.     int secsiz;
  405.     int flag;
  406. #    define        IOP_IS_TTY    1
  407. } IOBUF;
  408.  
  409. /*
  410.  * structure used to dynamically maintain a linked-list of open files/pipes
  411.  */
  412. struct redirect {
  413.     int flag;
  414. #        define        RED_FILE    1
  415. #        define        RED_PIPE    2
  416. #        define        RED_READ    4
  417. #        define        RED_WRITE    8
  418. #        define        RED_APPEND    16
  419. #        define        RED_NOBUF    32
  420.     char *value;
  421.     FILE *fp;
  422.     IOBUF *iop;
  423.     int pid;
  424.     int status;
  425.     long offset;        /* used for dynamic management of open files */
  426.     struct redirect *prev;
  427.     struct redirect *next;
  428. };
  429.  
  430. /* longjmp return codes, must be nonzero */
  431. /* Continue means either for loop/while continue, or next input record */
  432. #define TAG_CONTINUE 1
  433. /* Break means either for/while break, or stop reading input */
  434. #define TAG_BREAK 2
  435. /* Return means return from a function call; leave value in ret_node */
  436. #define    TAG_RETURN 3
  437.  
  438. #ifdef MSDOS
  439. #define HUGE    0x7fff
  440. #else
  441. #define HUGE    0x7fffffff
  442. #endif
  443.  
  444. /* -------------------------- External variables -------------------------- */
  445. /* gawk builtin variables */
  446. extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
  447. extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  448. extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  449. extern NODE *IGNORECASE_node;
  450.  
  451. extern NODE **stack_ptr;
  452. extern NODE *Nnull_string;
  453. extern NODE *deref;
  454. extern NODE **fields_arr;
  455. extern int sourceline;
  456. extern char *source;
  457. extern NODE *expression_value;
  458.  
  459. extern NODE *variables[];
  460.  
  461. extern NODE *_t;    /* used as temporary in tree_eval */
  462.  
  463. extern char *myname;
  464.  
  465. extern int node0_valid;
  466. extern int field_num;
  467. extern int strict;
  468.  
  469. /* ------------------------- Pseudo-functions ------------------------- */
  470. #define is_identchar(c) (isalnum(c) || (c) == '_')
  471.  
  472.  
  473. #define    free_temp(n)    if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
  474. #define    tree_eval(t)    (_t = (t),(_t) == NULL ? Nnull_string : \
  475.             ((_t)->type == Node_val ? (_t) : r_tree_eval((_t))))
  476. #define    make_string(s,l)    make_str_node((s),(l),0)
  477.  
  478. #define    cant_happen()    fatal("line %d, file: %s; bailing out", \
  479.                 __LINE__, __FILE__);
  480. #ifdef MEMDEBUG
  481. #define memmsg(x,y,z,zz)    fprintf(stderr, "malloc: %s: %s: %d %0x\n", z, x, y, zz)
  482. #define free(s)    fprintf(stderr, "free: s: %0x\n", s), do_free(s)
  483. #else
  484. #define memmsg(x,y,z,zz)
  485. #endif
  486.  
  487. #define    emalloc(var,ty,x,str)    if ((var = (ty) malloc((unsigned)(x))) == NULL)\
  488.                     fatal("%s: %s: can't allocate memory (%s)",\
  489.                     (str), "var", strerror(errno)); else\
  490.                     memmsg("var", x, str, var)
  491. #define    erealloc(var,ty,x,str)    if((var=(ty)realloc((char *)var,\
  492.                         (unsigned)(x)))==NULL)\
  493.                     fatal("%s: %s: can't allocate memory (%s)",\
  494.                     (str), "var", strerror(errno)); else\
  495.                     memmsg("re: var", x, str, var)
  496. #ifdef DEBUG
  497. #define    force_number    r_force_number
  498. #define    force_string    r_force_string
  499. #else
  500. #ifdef lint
  501. extern AWKNUM force_number();
  502. #endif
  503. #ifdef MSDOS
  504. extern double _msc51bug;
  505. #define    force_number(n)    (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  506. #else
  507. #define    force_number(n)    (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  508. #endif
  509. #define    force_string(s)    (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
  510. #endif
  511.  
  512. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  513. #define    STREQN(a,b,n)    ((n) && *(a) == *(b) && strncmp((a), (b), (n)) == 0)
  514.  
  515. #define    WHOLELINE    (node0_valid ? fields_arr[0] : *get_field(0,0))
  516.  
  517. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  518. #ifdef __STDC__
  519. extern    int parse_escape(char **);
  520. extern    int devopen(char *, char *);
  521. extern    struct re_pattern_buffer *make_regexp(NODE *, int);
  522. extern    struct re_pattern_buffer *mk_re_parse(char *, int);
  523. extern    NODE *variable(char *);
  524. extern    NODE *install(NODE **, char *, NODE *);
  525. extern    NODE *lookup(NODE **, char *);
  526. extern    NODE *make_name(char *, NODETYPE);
  527. extern    int interpret(NODE *);
  528. extern    NODE *r_tree_eval(NODE *);
  529. extern    void assign_number(NODE **, double);
  530. extern    int cmp_nodes(NODE *, NODE *);
  531. extern    struct redirect *redirect(NODE *, int *);
  532. extern    int flush_io(void);
  533. extern    void print_simple(NODE *, FILE *);
  534. /* extern    void warning(char *,...); */
  535. extern    void warning();
  536. /* extern    void fatal(char *,...); */
  537. extern    void fatal();
  538. extern    void set_record(char *, int);
  539. extern    NODE **get_field(int, int);
  540. extern    NODE **get_lhs(NODE *, int);
  541. extern    void do_deref(void );
  542. extern    struct search *assoc_scan(NODE *);
  543. extern    struct search *assoc_next(struct search *);
  544. extern    NODE **assoc_lookup(NODE *, NODE *);
  545. extern    double r_force_number(NODE *);
  546. extern    NODE *r_force_string(NODE *);
  547. extern    NODE *newnode(NODETYPE);
  548. extern    NODE *dupnode(NODE *);
  549. extern    NODE *make_number(double);
  550. extern    NODE *tmp_number(double);
  551. extern    NODE *make_str_node(char *, int, int);
  552. extern    NODE *tmp_string(char *, int);
  553. extern    char *re_compile_pattern(char *, int, struct re_pattern_buffer *);
  554. extern    int re_search(struct re_pattern_buffer *, char *, int, int, int, struct re_registers *);
  555. extern    void freenode(NODE *);
  556.  
  557. #else
  558. extern    int parse_escape();
  559. extern    void freenode();
  560. extern    int devopen();
  561. extern    struct re_pattern_buffer *make_regexp();
  562. extern    struct re_pattern_buffer *mk_re_parse();
  563. extern    NODE *variable();
  564. extern    NODE *install();
  565. extern    NODE *lookup();
  566. extern    int interpret();
  567. extern    NODE *r_tree_eval();
  568. extern    void assign_number();
  569. extern    int cmp_nodes();
  570. extern    struct redirect *redirect();
  571. extern    int flush_io();
  572. extern    void print_simple();
  573. extern    void warning();
  574. extern    void fatal();
  575. extern    void set_record();
  576. extern    NODE **get_field();
  577. extern    NODE **get_lhs();
  578. extern    void do_deref();
  579. extern    struct search *assoc_scan();
  580. extern    struct search *assoc_next();
  581. extern    NODE **assoc_lookup();
  582. extern    double r_force_number();
  583. extern    NODE *r_force_string();
  584. extern    NODE *newnode();
  585. extern    NODE *dupnode();
  586. extern    NODE *make_number();
  587. extern    NODE *tmp_number();
  588. extern    NODE *make_str_node();
  589. extern    NODE *tmp_string();
  590. extern    char *re_compile_pattern();
  591. extern    int re_search();
  592. #endif
  593.  
  594. #if !defined(__STDC__) || __STDC__ <= 0
  595. #define volatile
  596. #endif
  597.  
  598. /* Figure out what '\a' really is. */
  599. #ifdef __STDC__
  600. #define BELL    '\a'        /* sure makes life easy, don't it? */
  601. #else
  602. #    if 'z' - 'a' == 25    /* ascii */
  603. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  604. #            define BELL    '\207'
  605. #        else
  606. #            define BELL    '\07'
  607. #        endif
  608. #    else
  609. #        define BELL    '\057'
  610. #    endif
  611. #endif
  612.  
  613. #ifndef SIGTYPE
  614. #define SIGTYPE    void
  615. #endif
  616.  
  617. extern char casetable[];    /* for case-independent regexp matching */
  618.