19
19
* GNU General Public License for more details.
21
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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
26
26
/* ------------------------------ Includes ------------------------------ */
30
#ifndef LIMITS_H_MISSING
31
34
#include <limits.h>
35
#endif /* HAVE_LIMITS_H */
34
37
#include <setjmp.h>
38
#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
35
41
#include <varargs.h>
38
#if !defined(errno) && !defined(MSDOS) && !defined(OS2)
46
#if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
41
#ifdef __GNU_LIBRARY__
43
50
#include <signum.h>
47
53
/* ----------------- System dependencies (with more includes) -----------*/
49
#if !defined(VMS) || (!defined(VAXC) && !defined(__DECC))
55
/* This section is the messiest one in the file, not a lot that can be done */
59
#define MALLOC_ARG_T size_t
60
#else /* not __STDC__ */
62
#define MALLOC_ARG_T unsigned
65
#endif /* not __STDC__ */
67
#if ! defined(VMS) || (! defined(VAXC) && ! defined(__DECC))
50
68
#include <sys/types.h>
51
69
#include <sys/stat.h>
52
70
#else /* VMS w/ VAXC or DECC */
55
73
#include <file.h> /* avoid <fcntl.h> in io.c */
62
#define MALLOC_ARG_T size_t
65
#define MALLOC_ARG_T unsigned
75
typedef unsigned int size_t;
75
/* DEC C implies DECC$SHR, which doesn't have the %g problem of VAXCRTL */
76
#undef GFMT_WORKAROUND
78
#endif /* VMS w/ VAXC or DECC */
83
80
#ifdef STDC_HEADERS
84
81
#include <stdlib.h>
82
#else /* not STDC_HEADERS */
84
#endif /* not STDC_HEADERS */
85
87
#include <string.h>
90
#endif /* NEED_MEMORY_H */
91
#else /* not HAVE_STRING_H */
94
#endif /* HAVE_STRINGS_H */
95
#endif /* not HAVE_STRING_H */
98
#if __GNUC__ < 2 || __GNUC_MINOR__ < 7
102
#define getopt GNU_getopt
103
#define GFMT_WORKAROUND
90
106
#if defined(atarist) || defined(VMS)
91
107
#include <unixlib.h>
92
#else /* atarist || VMS */
93
#if !defined(MSDOS) && !defined(_MSC_VER)
108
#endif /* atarist || VMS */
94
111
#include <unistd.h>
96
#endif /* atarist || VMS */
98
#else /* STDC_HEADERS */
100
#endif /* STDC_HEADERS */
102
#if defined(ultrix) && !defined(Ultrix41)
103
extern char * getenv P((char *name));
104
extern double atof P((char *s));
109
/* nasty nasty SunOS-ism */
112
extern char *alloca();
114
#else /* not sparc */
115
#if !defined(alloca) && !defined(ALLOCA_PROTO)
116
#if defined(_MSC_VER)
122
extern char *alloca();
124
#endif /* _MSC_VER */
127
#endif /* __GNUC__ */
129
#ifdef HAVE_UNDERSCORE_SETJMP
130
/* nasty nasty berkelixm */
131
#define setjmp _setjmp
132
#define longjmp _longjmp
136
* if you don't have vprintf, try this and cross your fingers.
138
#if defined(VPRINTF_MISSING)
112
#endif /* HAVE_UNISTD_H */
115
/* if you don't have vprintf, try this and cross your fingers. */
139
117
#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
118
#else /* not HAVE_DOPRNT */
121
#endif /* not HAVE_DOPRNT */
122
#endif /* HAVE_VPRINTF */
143
/* some macros to redirect to code in vms/vms_misc.c */
144
#define exit vms_exit
145
#define open vms_open
146
#define strerror vms_strerror
147
#define strdup vms_strdup
148
extern void exit P((int));
149
extern int open P((const char *,int,...));
150
extern char *strerror P((int));
151
extern char *strdup P((const char *str));
152
extern int vms_devopen P((const char *,int));
153
# ifndef NO_TTY_FWRITE
154
#define fwrite tty_fwrite
155
#define fclose tty_fclose
156
extern size_t fwrite P((const void *,size_t,size_t,FILE *));
157
extern int fclose P((FILE *));
159
extern FILE *popen P((const char *,const char *));
160
extern int pclose P((FILE *));
161
extern void vms_arg_fixup P((int *,char ***));
162
/* some things not in STDC_HEADERS */
163
extern size_t gnu_strftime P((char *,size_t,const char *,const struct tm *));
164
extern int unlink P((const char *));
165
extern int getopt P((int,char **,char *));
166
extern int isatty P((int));
168
extern int fileno P((FILE *));
170
extern int close(), dup(), dup2(), fstat(), read(), stat();
171
extern int getpgrp P((void));
125
#include "vms/redirect.h"
129
#include "atari/redirect.h"
174
132
#define GNU_REGEX
176
134
#include "regex.h"
184
142
#define RESTART(rp,s) (rp)->regs.start[0]
185
143
#define REEND(rp,s) (rp)->regs.end[0]
186
#else /* GNU_REGEX */
144
#define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
145
#define SUBPATEND(rp,s,n) (rp)->regs.end[n]
187
146
#endif /* GNU_REGEX */
190
#define read _text_read /* we do not want all these CR's to mess our input */
191
extern int _text_read (int, char *, int);
194
#endif /* __MINT__ */
198
#define DEFPATH ".:/usr/local/lib/awk:/usr/lib/awk"
205
extern double double_to_int P((double d));
207
148
/* ------------------ Constants, Structures, Typedefs ------------------ */
208
151
#define AWKNUM double
155
/* a bit hackneyed, but what the heck */
160
/* Figure out what '\a' really is. */
162
#define BELL '\a' /* sure makes life easy, don't it? */
164
# if 'z' - 'a' == 25 /* ascii */
165
# if 'a' != 97 /* machine is dumb enough to use mark parity */
175
typedef enum nodevals {
211
176
/* illegal entry == 0 */
265
230
Node_param_list, /* lnode is a variable, rnode is more list */
268
/*40*/ Node_K_if, /* lnode is conditonal, rnode is if_branches */
233
Node_K_if, /* lnode is conditonal, rnode is if_branches */
269
234
Node_K_while, /* lnode is condtional, rnode is stuff to run */
270
235
Node_K_for, /* lnode is for_struct, rnode is stuff to run */
271
236
Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
272
237
Node_K_break, /* no subs */
273
Node_K_continue, /* no stuff */
238
Node_K_continue, /* no subs */
274
239
Node_K_print, /* lnode is exp_list, rnode is redirect */
275
240
Node_K_printf, /* lnode is exp_list, rnode is redirect */
276
241
Node_K_next, /* no subs */
277
242
Node_K_exit, /* subnode is return value, or NULL */
278
/*50*/ Node_K_do, /* lnode is conditional, rnode stuff to run */
243
Node_K_do, /* lnode is conditional, rnode stuff to run */
244
Node_K_return, /* lnode is return value */
245
Node_K_delete, /* lnode is array, rnode is subscript */
246
Node_K_getline, /* lnode is opt var, rnode is redirection */
282
247
Node_K_function, /* lnode is statement list, rnode is params */
248
Node_K_nextfile, /* no subs */
284
250
/* I/O redirection for print statements */
285
251
Node_redirect_output, /* subnode is where to redirect */
394
358
unsigned short flags;
395
# define MALLOC 1 /* can be free'd */
396
# define TEMP 2 /* should be free'd */
397
# define PERM 4 /* can't be free'd */
398
# define STRING 8 /* assigned as string */
399
# define STR 16 /* string value is current */
400
# define NUM 32 /* numeric value is current */
401
# define NUMBER 64 /* assigned as number */
402
# define MAYBE_NUM 128 /* user input: if NUMERIC then
359
# define MALLOC 1 /* can be free'd */
360
# define TEMP 2 /* should be free'd */
361
# define PERM 4 /* can't be free'd */
362
# define STRING 8 /* assigned as string */
363
# define STR 16 /* string value is current */
364
# define NUM 32 /* numeric value is current */
365
# define NUMBER 64 /* assigned as number */
366
# define MAYBE_NUM 128 /* user input: if NUMERIC then
404
# define ARRAYMAXED 256 /* array is at max size */
405
char *vname; /* variable's name */
368
# define ARRAYMAXED 256 /* array is at max size */
369
# define SCALAR 512 /* used as scalar, can't be array */
370
char *vname; /* variable's name */
408
373
#define lnode sub.nodep.l.lptr
540
502
extern char *CONVFMT;
541
503
extern int CONVFMTidx;
542
504
extern int OFMTidx;
543
extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
544
extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
545
extern NODE *CONVFMT_node;
546
extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
547
extern NODE *IGNORECASE_node;
548
extern NODE *FIELDWIDTHS_node;
505
extern NODE *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
506
extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
507
extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
508
extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node;
550
509
extern NODE **stack_ptr;
551
510
extern NODE *Nnull_string;
552
511
extern NODE **fields_arr;
554
513
extern char *source;
555
514
extern NODE *expression_value;
557
517
extern NODE *_t; /* used as temporary in tree_eval */
559
extern const char *myname;
561
520
extern NODE *nextfree;
562
521
extern int field0_valid;
522
extern int do_traditional;
564
523
extern int do_posix;
565
524
extern int do_lint;
525
extern int do_lint_old;
526
extern int do_intervals;
566
527
extern int in_begin_rule;
567
528
extern int in_end_rule;
530
extern const char *myname;
533
extern char *defpath;
536
extern char casetable[]; /* for case-independent regexp matching */
569
538
/* ------------------------- Pseudo-functions ------------------------- */
571
540
#define is_identchar(c) (isalnum(c) || (c) == '_')
543
#define getnode(n) emalloc(n, NODE *, sizeof(NODE), "getnode")
545
#define freenode(n) free(n)
547
#else /* not MPROF */
575
548
#define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
576
549
else n = more_nodes()
577
#define freenode(n) ((n)->nextp = nextfree, nextfree = (n))
579
#define getnode(n) emalloc(n, NODE *, sizeof(NODE), "getnode")
580
#define freenode(n) free(n)
551
#define freenode(n) ((n)->flags &= ~SCALAR, (n)->nextp = nextfree, nextfree = (n))
553
#endif /* not MPROF */
584
#define tree_eval(t) r_tree_eval(t)
556
#define tree_eval(t) r_tree_eval(t, FALSE)
557
#define m_tree_eval(t, iscond) r_tree_eval(t, iscond)
585
558
#define get_lhs(p, a) r_get_lhs((p), (a))
588
561
#define get_lhs(p, a) ((p)->type == Node_var ? (&(p)->var_value) : \
589
562
r_get_lhs((p), (a)))
590
#define tree_eval(t) (_t = (t),_t == NULL ? Nnull_string : \
591
(_t->type == Node_param_list ? r_tree_eval(_t) : \
563
#define tree_eval(t) m_tree_eval(t, FALSE)
565
#define m_tree_eval(t, iscond) \
574
_t = _t->var_value; \
577
_t = r_tree_eval(_t, iscond);\
583
#define m_tree_eval(t, iscond) (_t = (t), _t == NULL ? Nnull_string : \
584
(_t->type == Node_param_list ? \
585
r_tree_eval(_t, iscond) : \
592
586
(_t->type == Node_val ? _t : \
593
587
(_t->type == Node_var ? _t->var_value : \
588
r_tree_eval(_t, iscond)))))
589
#endif /* __GNUC__ */
590
#endif /* not DEBUG */
597
592
#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER))
598
593
#define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUM|NUMBER))
600
#define free_temp(n) do {if ((n)->flags&TEMP) { unref(n); }} while (0)
601
#define make_string(s,l) make_str_node((s), SZTC (l),0)
595
#define free_temp(n) do { if ((n)->flags&TEMP) { unref(n); }} while (FALSE)
596
#define make_string(s, l) make_str_node((s), (size_t) (l), FALSE)
603
598
#define ALREADY_MALLOCED 2
605
600
#define cant_happen() fatal("internal error line %d, file: %s", \
606
601
__LINE__, __FILE__);
608
#if defined(__STDC__) && !defined(NO_TOKEN_PASTING)
609
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
610
(fatal("%s: %s: can't allocate memory (%s)",\
611
(str), #var, strerror(errno)),0))
612
#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\
613
(MALLOC_ARG_T)(x))) ||\
614
(fatal("%s: %s: can't allocate memory (%s)",\
615
(str), #var, strerror(errno)),0))
617
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
618
(fatal("%s: %s: can't allocate memory (%s)",\
619
(str), "var", strerror(errno)),0))
620
#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\
621
(MALLOC_ARG_T)(x))) ||\
622
(fatal("%s: %s: can't allocate memory (%s)",\
623
(str), "var", strerror(errno)),0))
624
#endif /* __STDC__ */
603
#ifdef HAVE_STRINGIZE
604
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
605
(fatal("%s: %s: can't allocate memory (%s)",\
606
(str), #var, strerror(errno)),0))
607
#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\
608
(MALLOC_ARG_T)(x))) ||\
609
(fatal("%s: %s: can't allocate memory (%s)",\
610
(str), #var, strerror(errno)),0))
611
#else /* HAVE_STRINGIZE */
612
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
613
(fatal("%s: %s: can't allocate memory (%s)",\
614
(str), "var", strerror(errno)),0))
615
#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\
616
(MALLOC_ARG_T)(x))) ||\
617
(fatal("%s: %s: can't allocate memory (%s)",\
618
(str), "var", strerror(errno)),0))
619
#endif /* HAVE_STRINGIZE */
627
622
#define force_number r_force_number
631
626
extern AWKNUM force_number();
629
#define force_number(n) ({NODE *_tn = (n);\
630
(_tn->flags & NUM) ?_tn->numbr : r_force_number(_tn);})
631
#define force_string(s) ({NODE *_ts = (s);\
632
((_ts->flags & STR) && \
633
(_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
634
_ts : r_force_string(_ts);})
634
637
extern double _msc51bug;
635
#define force_number(n) (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
638
#define force_number(n) (_msc51bug=(_t = (n),\
639
(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
636
640
#else /* not MSDOS */
637
#define force_number(n) (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
639
#define force_string(s) (_t = (s),((_t->flags & STR) && (_t->stfmt == -1 || _t->stfmt == CONVFMTidx))? _t : r_force_string(_t))
641
#define force_number(n) (_t = (n),\
642
(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
643
#endif /* not MSDOS */
644
#define force_string(s) (_t = (s),((_t->flags & STR) && \
645
(_t->stfmt == -1 || \
646
_t->stfmt == CONVFMTidx))? \
647
_t : r_force_string(_t))
648
#endif /* not __GNUC__ */
640
649
#endif /* not DEBUG */
642
651
#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
643
#define STREQN(a,b,n) ((n)&& *(a)== *(b) && strncmp((a), (b), SZTC (n)) == 0)
652
#define STREQN(a,b,n) ((n) && *(a)== *(b) && \
653
strncmp((a), (b), (size_t) (n)) == 0)
645
655
/* ------------- Function prototypes or defs (as appropriate) ------------- */
653
663
extern void do_delete P((NODE *symbol, NODE *tree));
654
664
extern void assoc_scan P((NODE *symbol, struct search *lookat));
655
665
extern void assoc_next P((struct search *lookat));
657
667
extern char *tokexpand P((void));
658
668
extern char nextc P((void));
659
669
extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
660
670
extern NODE *install P((char *name, NODE *value));
661
671
extern NODE *lookup P((const char *name));
662
extern NODE *variable P((char *name, int can_free));
672
extern NODE *variable P((char *name, int can_free, NODETYPE type));
663
673
extern int yyparse P((void));
675
extern double double_to_int P((double d));
665
676
extern NODE *do_exp P((NODE *tree));
677
extern NODE *do_fflush P((NODE *tree));
666
678
extern NODE *do_index P((NODE *tree));
667
679
extern NODE *do_int P((NODE *tree));
668
680
extern NODE *do_length P((NODE *tree));
701
714
extern void set_record P((char *buf, int cnt, int freeold));
702
715
extern void reset_record P((void));
703
716
extern void set_NF P((void));
704
extern NODE **get_field P((int num, Func_ptr *assign));
717
extern NODE **get_field P((long num, Func_ptr *assign));
705
718
extern NODE *do_split P((NODE *tree));
706
719
extern void set_FS P((void));
707
720
extern void set_FS_if_not_FIELDWIDTHS P((void));
708
721
extern void set_RS P((void));
709
722
extern void set_FIELDWIDTHS P((void));
723
extern int using_fieldwidths P((void));
725
extern char *gawk_name P((const char *filespec));
726
extern void os_arg_fixup P((int *argcp, char ***argvp));
727
extern int os_devopen P((const char *name, int flag));
728
extern int optimal_bufsize P((int fd, struct stat *sbuf));
729
extern int ispath P((const char *file));
730
extern int isdirpunct P((int c));
711
732
extern void set_FNR P((void));
712
733
extern void set_NR P((void));
764
788
extern Regexp *re_update P((NODE *t));
765
789
extern void resyntax P((int syntax));
766
790
extern void resetup P((void));
791
extern int avoid_dfa P((NODE *re, char *str, size_t len)); /* temporary */
769
extern int strcasecmp P((const char *s1, const char *s2));
770
794
extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
797
#if defined(PIPES_SIMULATED)
773
798
/* atari/tmpnam.c */
774
799
extern char *tmpnam P((char *buf));
775
800
extern char *tempnam P((const char *path, const char *base));
778
/* Figure out what '\a' really is. */
780
#define BELL '\a' /* sure makes life easy, don't it? */
782
# if 'z' - 'a' == 25 /* ascii */
783
# if 'a' != 97 /* machine is dumb enough to use mark parity */
793
extern char casetable[]; /* for case-independent regexp matching */
805
#define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1)
807
#define INVALID_HANDLE (-1)
811
#define STATIC static
815
/* The __hpux check is to avoid conflicts with bison's definition of
816
alloca() in awktab.c.*/
817
#if (defined(__STDC__) && __STDC__) || defined (__hpux)
818
extern void *alloca P((unsigned));
820
extern char *alloca P((unsigned));