1/* 2 * awk.h -- Definitions for gawk. 3 */ 4 5/* 6 * Copyright (C) 1986, 1988, 1989, 1991-2003 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 52#include "gettext.h" 53#define _(msgid) gettext(msgid) 54#define N_(msgid) msgid 55 56#if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0) 57#ifndef LOCALEDIR 58#define LOCALEDIR NULL 59#endif /* LOCALEDIR */ 60#endif 61 62#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ 63#include <stdarg.h> 64#else 65#include <varargs.h> 66#endif 67#include <signal.h> 68#include <time.h> 69#include <errno.h> 70#if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2) 71extern int errno; 72#endif 73#ifdef HAVE_SIGNUM_H 74#include <signum.h> 75#endif 76#if defined(HAVE_MBRLEN) && defined(HAVE_MBRTOWC) && defined(HAVE_WCHAR_H) && defined(HAVE_WCTYPE_H) 77/* We can handle multibyte strings. */ 78#define MBS_SUPPORT 79#include <wchar.h> 80#include <wctype.h> 81#endif 82 83/* ----------------- System dependencies (with more includes) -----------*/ 84 85/* This section is the messiest one in the file, not a lot that can be done */ 86 87/* First, get the ctype stuff right; from Jim Meyering */ 88#if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII)) 89#define IN_CTYPE_DOMAIN(c) 1 90#else 91#define IN_CTYPE_DOMAIN(c) isascii((unsigned char) c) 92#endif 93 94#ifdef isblank 95#define ISBLANK(c) (IN_CTYPE_DOMAIN(c) && isblank((unsigned char) c)) 96#else 97#define ISBLANK(c) ((c) == ' ' || (c) == '\t') 98#endif 99#ifdef isgraph 100#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isgraph((unsigned char) c)) 101#else 102#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isprint((unsigned char) c) && !isspace((unsigned char) c)) 103#endif 104 105#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char) c)) 106#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char) c)) 107#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char) c)) 108#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char) c)) 109#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char) c)) 110#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char) c)) 111#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (unsigned char) (c)) 112#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char) c)) 113#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char) c)) 114#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char) c)) 115 116#ifndef TOUPPER 117#define TOUPPER(c) toupper((unsigned char) c) 118#endif 119#ifndef TOLOWER 120#define TOLOWER(c) tolower((unsigned char) c) 121#endif 122 123#ifdef __STDC__ 124#define P(s) s 125#define MALLOC_ARG_T size_t 126#else /* not __STDC__ */ 127#define P(s) () 128#define MALLOC_ARG_T unsigned 129#define volatile 130#endif /* not __STDC__ */ 131 132#ifndef VMS 133#include <sys/types.h> 134#include <sys/stat.h> 135#else /* VMS */ 136#include <stddef.h> 137#include <stat.h> 138#include <file.h> /* avoid <fcntl.h> in io.c */ 139#endif /* VMS */ 140 141#if ! defined(S_ISREG) && defined(S_IFREG) 142#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 143#endif 144 145#ifdef STDC_HEADERS 146#include <stdlib.h> 147#else /* not STDC_HEADERS */ 148#include "protos.h" 149#endif /* not STDC_HEADERS */ 150 151#ifdef HAVE_STRING_H 152#include <string.h> 153#ifdef NEED_MEMORY_H 154#include <memory.h> 155#endif /* NEED_MEMORY_H */ 156#else /* not HAVE_STRING_H */ 157#ifdef HAVE_STRINGS_H 158#include <strings.h> 159#endif /* HAVE_STRINGS_H */ 160#endif /* not HAVE_STRING_H */ 161 162#ifdef NeXT 163#if __GNUC__ < 2 || __GNUC_MINOR__ < 7 164#include <libc.h> 165#endif 166#undef atof 167#define getopt GNU_getopt 168#define GFMT_WORKAROUND 169#endif /* NeXT */ 170 171#if defined(atarist) || defined(VMS) 172#include <unixlib.h> 173#endif /* atarist || VMS */ 174 175#if ! defined(MSDOS) && ! defined(OS2) && ! defined(WIN32) && ! defined(__EMX__) && ! defined(__CYGWIN__) && ! (defined(__BEOS__) || defined(__HAIKU__)) && ! defined(O_BINARY) /*duh*/ 176#define O_BINARY 0 177#endif 178 179#if defined(TANDEM) 180#define variable variabl 181#define open(name, how, mode) open(name, how) /* !!! ANSI C !!! */ 182#endif 183 184#if HAVE_UNISTD_H 185#include <unistd.h> 186#endif /* HAVE_UNISTD_H */ 187 188#ifndef HAVE_VPRINTF 189/* if you don't have vprintf, try this and cross your fingers. */ 190#ifdef HAVE_DOPRNT 191#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp)) 192#else /* not HAVE_DOPRNT */ 193you 194lose 195#endif /* not HAVE_DOPRNT */ 196#endif /* HAVE_VPRINTF */ 197 198#ifndef HAVE_SETLOCALE 199#define setlocale(locale, val) /* nothing */ 200#endif /* HAVE_SETLOCALE */ 201 202/* use this as lintwarn("...") 203 this is a hack but it gives us the right semantics */ 204#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc)) 205 206#ifdef VMS 207#include "vms/redirect.h" 208#endif /*VMS*/ 209 210#ifdef atarist 211#include "unsupported/atari/redirect.h" 212#endif 213 214#define RE_TRANSLATE_TYPE const char * 215#define GNU_REGEX 216#ifdef GNU_REGEX 217#include "regex.h" 218typedef struct Regexp { 219 struct re_pattern_buffer pat; 220 struct re_registers regs; 221} Regexp; 222#define RESTART(rp,s) (rp)->regs.start[0] 223#define REEND(rp,s) (rp)->regs.end[0] 224#define SUBPATSTART(rp,s,n) (rp)->regs.start[n] 225#define SUBPATEND(rp,s,n) (rp)->regs.end[n] 226#define NUMSUBPATS(rp,s) (rp)->regs.num_regs 227#endif /* GNU_REGEX */ 228 229/* Stuff for losing systems. */ 230#ifdef STRTOD_NOT_C89 231extern double gawk_strtod(); 232#define strtod gawk_strtod 233#endif 234 235#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) 236# define __attribute__(x) 237#endif 238 239#ifndef ATTRIBUTE_UNUSED 240#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 241#endif /* ATTRIBUTE_UNUSED */ 242 243#ifndef ATTRIBUTE_NORETURN 244#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 245#endif /* ATTRIBUTE_NORETURN */ 246 247#ifndef ATTRIBUTE_PRINTF 248#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) 249#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) 250#endif /* ATTRIBUTE_PRINTF */ 251 252/* We use __extension__ in some places to suppress -pedantic warnings 253 about GCC extensions. This feature didn't work properly before 254 gcc 2.8. */ 255#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) 256#define __extension__ 257#endif 258 259/* this is defined by Windows32 extension libraries. It must be added to 260 * every variable which is exported (including function pointers) */ 261#if defined(WIN32_EXTENSION) && !defined(ATTRIBUTE_EXPORTED) 262# define ATTRIBUTE_EXPORTED __declspec(dllimport) 263#else 264# define ATTRIBUTE_EXPORTED 265#endif 266 267 268/* ------------------ Constants, Structures, Typedefs ------------------ */ 269 270#ifndef AWKNUM 271#define AWKNUM double 272#endif 273 274#ifndef TRUE 275/* a bit hackneyed, but what the heck */ 276#define TRUE 1 277#define FALSE 0 278#endif 279 280#define LINT_INVALID 1 /* only warn about invalid */ 281#define LINT_ALL 2 /* warn about all things */ 282 283/* Figure out what '\a' really is. */ 284#ifdef __STDC__ 285#define BELL '\a' /* sure makes life easy, don't it? */ 286#else 287# if 'z' - 'a' == 25 /* ascii */ 288# if 'a' != 97 /* machine is dumb enough to use mark parity */ 289# define BELL '\207' 290# else 291# define BELL '\07' 292# endif 293# else 294# define BELL '\057' 295# endif 296#endif 297 298typedef enum nodevals { 299 /* illegal entry == 0 */ 300 Node_illegal, 301 302 /* binary operators lnode and rnode are the expressions to work on */ 303 Node_times, 304 Node_quotient, 305 Node_mod, 306 Node_plus, 307 Node_minus, 308 Node_cond_pair, /* conditional pair (see Node_line_range) */ 309 Node_subscript, 310 Node_concat, 311 Node_exp, 312 313 /* unary operators subnode is the expression to work on */ 314 Node_preincrement, 315 Node_predecrement, 316 Node_postincrement, 317 Node_postdecrement, 318 Node_unary_minus, 319 Node_field_spec, 320 321 /* assignments lnode is the var to assign to, rnode is the exp */ 322 Node_assign, 323 Node_assign_times, 324 Node_assign_quotient, 325 Node_assign_mod, 326 Node_assign_plus, 327 Node_assign_minus, 328 Node_assign_exp, 329 330 /* boolean binaries lnode and rnode are expressions */ 331 Node_and, 332 Node_or, 333 334 /* binary relationals compares lnode and rnode */ 335 Node_equal, 336 Node_notequal, 337 Node_less, 338 Node_greater, 339 Node_leq, 340 Node_geq, 341 Node_match, 342 Node_nomatch, 343 344 /* unary relationals works on subnode */ 345 Node_not, 346 347 /* program structures */ 348 Node_rule_list, /* lnode is a rule, rnode is rest of list */ 349 Node_rule_node, /* lnode is pattern, rnode is statement */ 350 Node_statement_list, /* lnode is statement, rnode is more list */ 351 Node_switch_body, /* lnode is the case list, rnode is default list */ 352 Node_case_list, /* lnode is the case, rnode is a statement list */ 353 Node_if_branches, /* lnode is to run on true, rnode on false */ 354 Node_expression_list, /* lnode is an exp, rnode is more list */ 355 Node_param_list, /* lnode is a variable, rnode is more list */ 356 357 /* keywords */ 358 Node_K_if, /* lnode is conditonal, rnode is if_branches */ 359 Node_K_switch, /* lnode is switch value, rnode is body of case statements */ 360 Node_K_case, /* lnode is case value, rnode is stuff to run */ 361 Node_K_default, /* lnode is empty, rnode is stuff to run */ 362 Node_K_while, /* lnode is condtional, rnode is stuff to run */ 363 Node_K_for, /* lnode is for_struct, rnode is stuff to run */ 364 Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */ 365 Node_K_break, /* no subs */ 366 Node_K_continue, /* no subs */ 367 Node_K_print, /* lnode is exp_list, rnode is redirect */ 368 Node_K_print_rec, /* lnode is NULL, rnode is redirect */ 369 Node_K_printf, /* lnode is exp_list, rnode is redirect */ 370 Node_K_next, /* no subs */ 371 Node_K_exit, /* subnode is return value, or NULL */ 372 Node_K_do, /* lnode is conditional, rnode stuff to run */ 373 Node_K_return, /* lnode is return value */ 374 Node_K_delete, /* lnode is array, rnode is subscript */ 375 Node_K_delete_loop, /* lnode is array, rnode is subscript */ 376 Node_K_getline, /* lnode is opt var, rnode is redirection */ 377 Node_K_function, /* lnode is statement list, rnode is params */ 378 Node_K_nextfile, /* no subs */ 379 380 /* I/O redirection for print statements */ 381 Node_redirect_output, /* subnode is where to redirect */ 382 Node_redirect_append, /* subnode is where to redirect */ 383 Node_redirect_pipe, /* subnode is where to redirect */ 384 Node_redirect_pipein, /* subnode is where to redirect */ 385 Node_redirect_input, /* subnode is where to redirect */ 386 Node_redirect_twoway, /* subnode is where to redirect */ 387 388 /* Variables */ 389 Node_var_new, /* newly created variable, may become an array */ 390 Node_var, /* scalar variable, lnode is value */ 391 Node_var_array, /* array is ptr to elements, table_size num of eles */ 392 Node_val, /* node is a value - type in flags */ 393 394 /* Builtins subnode is explist to work on, builtin is func to call */ 395 Node_builtin, 396 397 /* 398 * pattern: conditional ',' conditional ; lnode of Node_line_range 399 * is the two conditionals (Node_cond_pair), other word (rnode place) 400 * is a flag indicating whether or not this range has been entered. 401 */ 402 Node_line_range, 403 404 /* 405 * boolean test of membership in array 406 * lnode is string-valued, expression rnode is array name 407 */ 408 Node_in_array, 409 410 Node_func, /* lnode is param. list, rnode is body */ 411 Node_func_call, /* lnode is name, rnode is argument list */ 412 413 Node_cond_exp, /* lnode is conditonal, rnode is if_branches */ 414 Node_regex, /* a regexp, text, compiled, flags, etc */ 415 Node_dynregex, /* a dynamic regexp */ 416 Node_hashnode, /* an identifier in the symbol table */ 417 Node_ahash, /* an array element */ 418 Node_array_ref, /* array passed by ref as parameter */ 419 420 Node_BINMODE, /* variables recognized in the grammar */ 421 Node_CONVFMT, 422 Node_FIELDWIDTHS, 423 Node_FNR, 424 Node_FS, 425 Node_IGNORECASE, 426 Node_LINT, 427 Node_NF, 428 Node_NR, 429 Node_OFMT, 430 Node_OFS, 431 Node_ORS, 432 Node_RS, 433 Node_TEXTDOMAIN, 434 Node_final /* sentry value, not legal */ 435} NODETYPE; 436 437/* 438 * NOTE - this struct is a rather kludgey -- it is packed to minimize 439 * space usage, at the expense of cleanliness. Alter at own risk. 440 */ 441typedef struct exp_node { 442 union { 443 struct { 444 union { 445 struct exp_node *lptr; 446 char *param_name; 447 long ll; 448 } l; 449 union { 450 struct exp_node *rptr; 451 struct exp_node *(*pptr) P((struct exp_node *)); 452 Regexp *preg; 453 struct for_loop_header *hd; 454 struct exp_node **av; 455 int r_ent; /* range entered */ 456 } r; 457 union { 458 struct exp_node *extra; 459 long xl; 460 char **param_list; 461 } x; 462 char *name; 463 short number; 464 unsigned long reflags; 465# define CASE 1 466# define CONST 2 467# define FS_DFLT 4 468 } nodep; 469 struct { 470 AWKNUM fltnum; /* this is here for optimal packing of 471 * the structure on many machines 472 */ 473 char *sp; 474 size_t slen; 475 long sref; 476 int idx; 477 } val; 478 struct { 479 struct exp_node *next; 480 char *name; 481 size_t length; 482 struct exp_node *value; 483 long ref; 484 } hash; 485#define hnext sub.hash.next 486#define hname sub.hash.name 487#define hlength sub.hash.length 488#define hvalue sub.hash.value 489 490#define ahnext sub.hash.next 491#define ahname_str sub.hash.name 492#define ahname_len sub.hash.length 493#define ahvalue sub.hash.value 494#define ahname_ref sub.hash.ref 495 } sub; 496 NODETYPE type; 497 unsigned short flags; 498# define MALLOC 1 /* can be free'd */ 499# define TEMP 2 /* should be free'd */ 500# define PERM 4 /* can't be free'd */ 501# define STRING 8 /* assigned as string */ 502# define STRCUR 16 /* string value is current */ 503# define NUMCUR 32 /* numeric value is current */ 504# define NUMBER 64 /* assigned as number */ 505# define MAYBE_NUM 128 /* user input: if NUMERIC then 506 * a NUMBER */ 507# define ARRAYMAXED 256 /* array is at max size */ 508# define FUNC 512 /* this parameter is really a 509 * function name; see awkgram.y */ 510# define FIELD 1024 /* this is a field */ 511# define INTLSTR 2048 /* use localized version */ 512} NODE; 513 514#define vname sub.nodep.name 515#define exec_count sub.nodep.reflags 516 517#define lnode sub.nodep.l.lptr 518#define nextp sub.nodep.l.lptr 519#define rnode sub.nodep.r.rptr 520#define source_file sub.nodep.name 521#define source_line sub.nodep.number 522#define param_cnt sub.nodep.number 523#define param sub.nodep.l.param_name 524#define parmlist sub.nodep.x.param_list 525 526#define subnode lnode 527#define builtin sub.nodep.r.pptr 528#define callresult sub.nodep.x.extra 529#define funcbody sub.nodep.x.extra 530 531#define re_reg sub.nodep.r.preg 532#define re_flags sub.nodep.reflags 533#define re_text lnode 534#define re_exp sub.nodep.x.extra 535 536#define forloop rnode->sub.nodep.r.hd 537 538#define stptr sub.val.sp 539#define stlen sub.val.slen 540#define stref sub.val.sref 541#define stfmt sub.val.idx 542 543#define numbr sub.val.fltnum 544 545/* Node_var: */ 546#define var_value lnode 547 548/* Node_var_array: */ 549#define var_array sub.nodep.r.av 550#define array_size sub.nodep.l.ll 551#define table_size sub.nodep.x.xl 552 553/* Node_array_ref: */ 554#define orig_array sub.nodep.x.extra 555#define prev_array rnode 556 557#define printf_count sub.nodep.x.xl 558 559#define condpair lnode 560#define triggered sub.nodep.r.r_ent 561 562/* a regular for loop */ 563typedef struct for_loop_header { 564 NODE *init; 565 NODE *cond; 566 NODE *incr; 567} FOR_LOOP_HEADER; 568 569typedef struct iobuf { 570 const char *name; /* filename */ 571 int fd; /* file descriptor */ 572 struct stat sbuf; /* stat buf */ 573 char *buf; /* start data buffer */ 574 char *off; /* start of current record in buffer */ 575 char *dataend; /* first byte in buffer to hold new data, 576 NULL if not read yet */ 577 char *end; /* end of buffer */ 578 size_t readsize; /* set from fstat call */ 579 size_t size; /* buffer size */ 580 ssize_t count; /* amount read last time */ 581 size_t scanoff; /* where we were in the buffer when we had 582 to regrow/refill */ 583 int flag; 584# define IOP_IS_TTY 1 585# define IOP_IS_INTERNAL 2 586# define IOP_NO_FREE 4 587# define IOP_NOFREE_OBJ 8 588# define IOP_AT_EOF 16 589# define IOP_CLOSED 32 590} IOBUF; 591 592typedef void (*Func_ptr) P((void)); 593 594/* structure used to dynamically maintain a linked-list of open files/pipes */ 595struct redirect { 596 unsigned int flag; 597# define RED_FILE 1 598# define RED_PIPE 2 599# define RED_READ 4 600# define RED_WRITE 8 601# define RED_APPEND 16 602# define RED_NOBUF 32 603# define RED_USED 64 /* closed temporarily to reuse fd */ 604# define RED_EOF 128 605# define RED_TWOWAY 256 606# define RED_PTY 512 607# define RED_SOCKET 1024 608# define RED_TCP 2048 609 char *value; 610 FILE *fp; 611 FILE *ifp; /* input fp, needed for PIPES_SIMULATED */ 612 IOBUF *iop; 613 int pid; 614 int status; 615 struct redirect *prev; 616 struct redirect *next; 617 const char *mode; 618}; 619 620/* 621 * structure for our source, either a command line string or a source file. 622 * the same structure is used to remember variable pre-assignments. 623 */ 624struct src { 625 enum srctype { CMDLINE = 1, SOURCEFILE, 626 PRE_ASSIGN, PRE_ASSIGN_FS } stype; 627 char *val; 628}; 629 630/* for debugging purposes */ 631struct flagtab { 632 int val; 633 const char *name; 634}; 635 636/* longjmp return codes, must be nonzero */ 637/* Continue means either for loop/while continue, or next input record */ 638#define TAG_CONTINUE 1 639/* Break means either for/while break, or stop reading input */ 640#define TAG_BREAK 2 641/* Return means return from a function call; leave value in ret_node */ 642#define TAG_RETURN 3 643 644#ifndef LONG_MAX 645#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1)))) 646#endif 647#ifndef ULONG_MAX 648#define ULONG_MAX (~(unsigned long)0) 649#endif 650#ifndef LONG_MIN 651#define LONG_MIN ((long)(-LONG_MAX - 1L)) 652#endif 653#define HUGE LONG_MAX 654 655/* -------------------------- External variables -------------------------- */ 656/* gawk builtin variables */ 657extern long NF; 658extern long NR; 659extern long FNR; 660extern int BINMODE; 661extern int IGNORECASE; 662extern int RS_is_null; 663extern char *OFS; 664extern int OFSlen; 665extern char *ORS; 666extern int ORSlen; 667extern char *OFMT; 668extern char *CONVFMT; 669ATTRIBUTE_EXPORTED extern int CONVFMTidx; 670extern int OFMTidx; 671extern char *TEXTDOMAIN; 672extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node; 673extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node; 674extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node; 675extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node; 676extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node; 677ATTRIBUTE_EXPORTED extern NODE **stack_ptr; 678extern NODE *Nnull_string; 679extern NODE *Null_field; 680extern NODE **fields_arr; 681extern int sourceline; 682extern char *source; 683extern NODE *expression_value; 684 685#if __GNUC__ < 2 686# if defined(WIN32_EXTENSION) 687static 688# else 689extern 690#endif 691NODE *_t; /* used as temporary in tree_eval */ 692#endif 693 694extern NODE *nextfree; 695extern int field0_valid; 696extern int do_traditional; 697extern int do_posix; 698extern int do_intervals; 699extern int do_intl; 700extern int do_non_decimal_data; 701extern int do_dump_vars; 702extern int do_tidy_mem; 703extern int in_begin_rule; 704extern int in_end_rule; 705extern int whiny_users; 706#ifdef NO_LINT 707#define do_lint 0 708#define do_lint_old 0 709#else 710ATTRIBUTE_EXPORTED extern int do_lint; 711extern int do_lint_old; 712#endif 713#ifdef MBS_SUPPORT 714extern int gawk_mb_cur_max; 715#endif 716 717#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0 718extern GETGROUPS_T *groupset; 719extern int ngroups; 720#endif 721 722extern const char *myname; 723 724extern char quote; 725extern char *defpath; 726extern char envsep; 727 728extern const char casetable[]; /* for case-independent regexp matching */ 729 730/* ------------------------- Pseudo-functions ------------------------- */ 731 732#define is_identchar(c) (isalnum(c) || (c) == '_') 733#define isnondecimal(str) (((str)[0]) == '0' && (ISDIGIT((str)[1]) \ 734 || (str)[1] == 'x' || (str)[1] == 'X')) 735 736#define var_uninitialized(n) ((n)->var_value == Nnull_string) 737 738#ifdef MPROF 739#define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), (n)->flags = 0, (n)-exec_count = 0; 740#define freenode(n) free(n) 741#else /* not MPROF */ 742#define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\ 743 else n = more_nodes() 744#ifndef NO_PROFILING 745#define freenode(n) ((n)->flags = 0,\ 746 (n)->exec_count = 0, (n)->nextp = nextfree, nextfree = (n)) 747#else /* not PROFILING */ 748#define freenode(n) ((n)->flags = 0,\ 749 (n)->nextp = nextfree, nextfree = (n)) 750#endif /* not PROFILING */ 751#endif /* not MPROF */ 752 753#ifndef GAWKDEBUG 754#define DUPNODE_MACRO 1 755/* 756 * Speed up the path leading to r_dupnode, as well as duplicating TEMP nodes, 757 * on expense of slowing down the access to PERM nodes (by two instructions). 758 * This is right since PERM nodes are realtively rare. 759 * 760 * The code also sets MALLOC flag for PERM nodes, which should not matter. 761 */ 762#define DUPNODE_COMMON (_t->flags & (TEMP|PERM)) != 0 ? \ 763 (_t->flags &= ~TEMP, _t->flags |= MALLOC, _t) : \ 764 r_dupnode(_t) 765#if __GNUC__ >= 2 766#define dupnode(n) ({NODE * _t = (n); DUPNODE_COMMON;}) 767#else 768#define dupnode(n) (_t = (n), DUPNODE_COMMON) 769#endif 770#else /* GAWKDEBUG */ 771#define dupnode(n) r_dupnode(n) 772#endif /* GAWKDEBUG */ 773 774#define get_array(t) get_actual(t, TRUE) /* allowed to die fatally */ 775#define get_param(t) get_actual(t, FALSE) /* not allowed */ 776 777#ifdef MEMDEBUG 778#undef freenode 779#define get_lhs(p, a, r) r_get_lhs((p), (a), (r)) 780#define m_tree_eval(t, iscond) r_tree_eval(t, iscond) 781#else 782#define get_lhs(p, a, r) ((p)->type == Node_var && \ 783 ! var_uninitialized(p) ? \ 784 (&(p)->var_value) : \ 785 r_get_lhs((p), (a), (r))) 786#define TREE_EVAL_MACRO 1 787#if __GNUC__ >= 2 788#define m_tree_eval(t, iscond) __extension__ \ 789 ({NODE * _t = (t); \ 790 if (_t == NULL) \ 791 _t = Nnull_string; \ 792 else { \ 793 switch(_t->type) { \ 794 case Node_val: \ 795 if (_t->flags&INTLSTR) \ 796 _t = r_force_string(_t); \ 797 break; \ 798 case Node_var: \ 799 if (! var_uninitialized(_t)) { \ 800 _t = _t->var_value; \ 801 break; \ 802 } \ 803 /*FALLTHROUGH*/ \ 804 default: \ 805 _t = r_tree_eval(_t, iscond);\ 806 break; \ 807 } \ 808 } \ 809 _t;}) 810#else 811#define m_tree_eval(t, iscond) (_t = (t), _t == NULL ? Nnull_string : \ 812 (_t->type == Node_param_list ? \ 813 r_tree_eval(_t, iscond) : \ 814 ((_t->type == Node_val && (_t->flags&INTLSTR)) ? \ 815 r_force_string(_t) : \ 816 (_t->type == Node_val ? _t : \ 817 (_t->type == Node_var && \ 818 ! var_uninitialized(_t) ? _t->var_value : \ 819 r_tree_eval(_t, iscond)))))) 820#endif /* __GNUC__ */ 821#endif /* not MEMDEBUG */ 822#define tree_eval(t) m_tree_eval(t, FALSE) 823 824#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER)) 825#define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUMCUR|NUMBER)) 826 827#define free_temp(n) do { NODE *_n = (n); if (_n->flags&TEMP) unref(_n);} \ 828 while (FALSE) 829 830#define make_string(s, l) make_str_node((s), (size_t) (l), 0) 831#define SCAN 1 832#define ALREADY_MALLOCED 2 833 834#define cant_happen() r_fatal("internal error line %d, file: %s", \ 835 __LINE__, __FILE__) 836 837#ifdef HAVE_STRINGIZE 838#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\ 839 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\ 840 (str), #var, (long) (x), strerror(errno)),0)) 841#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\ 842 (MALLOC_ARG_T)(x))) ||\ 843 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\ 844 (str), #var, (long) (x), strerror(errno)),0)) 845#else /* HAVE_STRINGIZE */ 846#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\ 847 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\ 848 (str), "var", (long) (x), strerror(errno)),0)) 849#define erealloc(var,ty,x,str) (void)((var=(ty)realloc((char *)var,\ 850 (MALLOC_ARG_T)(x))) ||\ 851 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\ 852 (str), "var", (long) (x), strerror(errno)),0)) 853#endif /* HAVE_STRINGIZE */ 854 855#ifdef GAWKDEBUG 856#define force_number r_force_number 857#define force_string r_force_string 858#else /* not GAWKDEBUG */ 859#ifdef lint 860extern AWKNUM force_number(); 861#endif 862#if __GNUC__ >= 2 863#define force_number(n) __extension__ ({NODE *_tn = (n);\ 864 (_tn->flags & NUMCUR) ?_tn->numbr : r_force_number(_tn);}) 865#define force_string(s) __extension__ ({NODE *_ts = (s);\ 866 ((_ts->flags & INTLSTR) ? \ 867 r_force_string(_ts) : \ 868 ((_ts->flags & STRCUR) && \ 869 (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\ 870 _ts : r_force_string(_ts));}) 871#else 872#ifdef MSDOS 873extern double _msc51bug; 874#define force_number(n) (_msc51bug=(_t = (n),\ 875 (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t))) 876#else /* not MSDOS */ 877#define force_number(n) (_t = (n),\ 878 (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t)) 879#endif /* not MSDOS */ 880#define force_string(s) (_t = (s),(_t->flags & INTLSTR) ? \ 881 r_force_string(_t) :\ 882 ((_t->flags & STRCUR) && \ 883 (_t->stfmt == -1 || \ 884 _t->stfmt == CONVFMTidx))? \ 885 _t : r_force_string(_t)) 886 887#endif /* not __GNUC__ */ 888#endif /* not GAWKDEBUG */ 889 890#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0) 891#define STREQN(a,b,n) ((n) && *(a)== *(b) && \ 892 strncmp((a), (b), (size_t) (n)) == 0) 893 894#define fatal set_loc(__FILE__, __LINE__), r_fatal 895 896/* ------------- Function prototypes or defs (as appropriate) ------------- */ 897 898/* array.c */ 899extern NODE *get_actual P((NODE *symbol, int canfatal)); 900extern char *array_vname P((const NODE *symbol)); 901extern void array_init P((void)); 902extern NODE *concat_exp P((NODE *tree)); 903extern void assoc_clear P((NODE *symbol)); 904extern NODE *in_array P((NODE *symbol, NODE *subs)); 905extern NODE **assoc_lookup P((NODE *symbol, NODE *subs, int reference)); 906extern void do_delete P((NODE *symbol, NODE *tree)); 907extern void do_delete_loop P((NODE *symbol, NODE *tree)); 908extern NODE *assoc_dump P((NODE *symbol)); 909extern NODE *do_adump P((NODE *tree)); 910extern NODE *do_asort P((NODE *tree)); 911extern NODE *do_asorti P((NODE *tree)); 912extern unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize)); 913/* awkgram.c */ 914extern char *tokexpand P((void)); 915extern NODE *node P((NODE *left, NODETYPE op, NODE *right)); 916extern NODE *install P((char *name, NODE *value)); 917extern NODE *lookup P((const char *name)); 918extern NODE *variable P((char *name, int can_free, NODETYPE type)); 919extern int yyparse P((void)); 920extern void dump_funcs P((void)); 921extern void dump_vars P((const char *fname)); 922extern void release_all_vars P((void)); 923extern const char *getfname P((NODE *(*)(NODE *))); 924extern NODE *stopme P((NODE *tree)); 925extern void shadow_funcs P((void)); 926/* builtin.c */ 927extern double double_to_int P((double d)); 928extern NODE *do_exp P((NODE *tree)); 929extern NODE *do_fflush P((NODE *tree)); 930extern NODE *do_index P((NODE *tree)); 931extern NODE *do_int P((NODE *tree)); 932extern NODE *do_length P((NODE *tree)); 933extern NODE *do_log P((NODE *tree)); 934extern NODE *do_mktime P((NODE *tree)); 935extern NODE *do_sprintf P((NODE *tree)); 936extern void do_printf P((NODE *tree)); 937extern void print_simple P((NODE *tree, FILE *fp)); 938extern NODE *do_sqrt P((NODE *tree)); 939extern NODE *do_substr P((NODE *tree)); 940extern NODE *do_strftime P((NODE *tree)); 941extern NODE *do_systime P((NODE *tree)); 942extern NODE *do_system P((NODE *tree)); 943extern void do_print P((NODE *tree)); 944extern void do_print_rec P((NODE *tree)); 945extern NODE *do_tolower P((NODE *tree)); 946extern NODE *do_toupper P((NODE *tree)); 947extern NODE *do_atan2 P((NODE *tree)); 948extern NODE *do_sin P((NODE *tree)); 949extern NODE *do_cos P((NODE *tree)); 950extern NODE *do_rand P((NODE *tree)); 951extern NODE *do_srand P((NODE *tree)); 952extern NODE *do_match P((NODE *tree)); 953extern NODE *do_gsub P((NODE *tree)); 954extern NODE *do_sub P((NODE *tree)); 955extern NODE *do_gensub P((NODE *tree)); 956extern NODE *format_tree P((const char *, size_t, NODE *, long)); 957extern NODE *do_lshift P((NODE *tree)); 958extern NODE *do_rshift P((NODE *tree)); 959extern NODE *do_and P((NODE *tree)); 960extern NODE *do_or P((NODE *tree)); 961extern NODE *do_xor P((NODE *tree)); 962extern NODE *do_compl P((NODE *tree)); 963extern NODE *do_strtonum P((NODE *tree)); 964extern AWKNUM nondec2awknum P((char *str, size_t len)); 965extern NODE *do_dcgettext P((NODE *tree)); 966extern NODE *do_dcngettext P((NODE *tree)); 967extern NODE *do_bindtextdomain P((NODE *tree)); 968#ifdef MBS_SUPPORT 969extern int strncasecmpmbs P((const char *, mbstate_t, const char *, 970 mbstate_t, size_t)); 971#endif 972/* eval.c */ 973extern int interpret P((NODE *volatile tree)); 974extern NODE *r_tree_eval P((NODE *tree, int iscond)); 975extern int cmp_nodes P((NODE *t1, NODE *t2)); 976extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign, int reference)); 977extern void set_IGNORECASE P((void)); 978extern void set_OFS P((void)); 979extern void set_ORS P((void)); 980extern void set_OFMT P((void)); 981extern void set_CONVFMT P((void)); 982extern void set_BINMODE P((void)); 983extern void set_LINT P((void)); 984extern void set_TEXTDOMAIN P((void)); 985extern void update_ERRNO P((void)); 986extern const char *redflags2str P((int)); 987extern const char *flags2str P((int)); 988extern const char *genflags2str P((int flagval, const struct flagtab *tab)); 989extern const char *nodetype2str P((NODETYPE type)); 990extern NODE *assign_val P((NODE **lhs_p, NODE *rhs)); 991#ifdef PROFILING 992extern void dump_fcall_stack P((FILE *fp)); 993#endif 994/* ext.c */ 995NODE *do_ext P((NODE *)); 996#ifdef DYNAMIC 997void make_builtin P((char *, NODE *(*)(NODE *), int)); 998NODE *get_argument P((NODE *, int)); 999void set_value P((NODE *)); 1000#endif 1001/* field.c */ 1002extern void init_fields P((void)); 1003extern void set_record P((const char *buf, int cnt)); 1004extern void reset_record P((void)); 1005extern void set_NF P((void)); 1006extern NODE **get_field P((long num, Func_ptr *assign)); 1007extern NODE *do_split P((NODE *tree)); 1008extern void set_FS P((void)); 1009extern void set_RS P((void)); 1010extern void set_FIELDWIDTHS P((void)); 1011extern int using_fieldwidths P((void)); 1012/* gawkmisc.c */ 1013extern char *gawk_name P((const char *filespec)); 1014extern void os_arg_fixup P((int *argcp, char ***argvp)); 1015extern int os_devopen P((const char *name, int flag)); 1016extern void os_close_on_exec P((int fd, const char *name, const char *what, 1017 const char *dir)); 1018extern int os_isdir P((int fd)); 1019extern int os_is_setuid P((void)); 1020extern int os_setbinmode P((int fd, int mode)); 1021extern void os_restore_mode P((int fd)); 1022extern size_t optimal_bufsize P((int fd, struct stat *sbuf)); 1023extern int ispath P((const char *file)); 1024extern int isdirpunct P((int c)); 1025#if defined(_MSC_VER) && !defined(_WIN32) 1026extern char *memcpy_ulong P((char *dest, const char *src, unsigned long l)); 1027extern void *memset_ulong P((void *dest, int val, unsigned long l)); 1028#define memcpy memcpy_ulong 1029#define memset memset_ulong 1030#endif 1031/* io.c */ 1032extern void set_FNR P((void)); 1033extern void set_NR P((void)); 1034extern void do_input P((void)); 1035extern struct redirect *redirect P((NODE *tree, int *errflg)); 1036extern NODE *do_close P((NODE *tree)); 1037extern int flush_io P((void)); 1038extern int close_io P((void)); 1039extern int devopen P((const char *name, const char *mode)); 1040extern int pathopen P((const char *file)); 1041extern NODE *do_getline P((NODE *tree)); 1042extern void do_nextfile P((void)) ATTRIBUTE_NORETURN; 1043extern struct redirect *getredirect P((const char *str, int len)); 1044/* main.c */ 1045extern int main P((int argc, char **argv)); 1046extern NODE *load_environ P((void)); 1047extern NODE *load_procinfo P((void)); 1048extern int arg_assign P((char *arg, int initing)); 1049/* msg.c */ 1050extern void err P((const char *s, const char *emsg, va_list argp)) ATTRIBUTE_PRINTF(2, 0); 1051#if _MSC_VER == 510 1052extern void msg P((va_list va_alist, ...)); 1053extern void error P((va_list va_alist, ...)); 1054extern void warning P((va_list va_alist, ...)); 1055extern void set_loc P((const char *file, int line)); 1056extern void r_fatal P((va_list va_alist, ...)); 1057extern void (*lintfunc) P((va_list va_alist, ...)); 1058#else 1059#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ 1060extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1; 1061extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1; 1062extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1; 1063extern void set_loc (const char *file, int line); 1064extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; 1065ATTRIBUTE_EXPORTED 1066#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2) 1067extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1; 1068#else 1069extern void (*lintfunc) (const char *mesg, ...); 1070#endif 1071#else 1072extern void msg (); 1073extern void error (); 1074extern void warning (); 1075extern void set_loc (); 1076extern void r_fatal (); 1077extern void (*lintfunc) (); 1078#endif 1079#endif 1080/* profile.c */ 1081extern void init_profiling P((int *flag, const char *def_file)); 1082extern void init_profiling_signals P((void)); 1083extern void set_prof_file P((const char *filename)); 1084extern void dump_prog P((NODE *begin, NODE *prog, NODE *end)); 1085extern void pp_func P((const char *name, size_t namelen, NODE *f)); 1086extern void pp_string_fp P((FILE *fp, const char *str, size_t namelen, 1087 int delim, int breaklines)); 1088/* node.c */ 1089extern AWKNUM r_force_number P((NODE *n)); 1090extern NODE *format_val P((const char *format, int index, NODE *s)); 1091extern NODE *r_force_string P((NODE *s)); 1092extern NODE *r_dupnode P((NODE *n)); 1093extern NODE *copynode P((NODE *n)); 1094extern NODE *mk_number P((AWKNUM x, unsigned int flags)); 1095extern NODE *make_str_node P((char *s, unsigned long len, int scan )); 1096extern NODE *tmp_string P((char *s, size_t len )); 1097extern NODE *more_nodes P((void)); 1098#ifdef MEMDEBUG 1099extern void freenode P((NODE *it)); 1100#endif 1101extern void unref P((NODE *tmp)); 1102extern int parse_escape P((const char **string_ptr)); 1103/* re.c */ 1104extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase)); 1105extern int research P((Regexp *rp, const char *str, int start, 1106 size_t len, int need_start)); 1107extern void refree P((Regexp *rp)); 1108extern void reg_error P((const char *s)); 1109extern Regexp *re_update P((NODE *t)); 1110extern void resyntax P((int syntax)); 1111extern void resetup P((void)); 1112extern int reisstring P((const char *text, size_t len, Regexp *re, const char *buf)); 1113extern int remaybelong P((const char *text, size_t len)); 1114 1115/* strncasecmp.c */ 1116#ifndef BROKEN_STRNCASECMP 1117extern int strcasecmp P((const char *s1, const char *s2)); 1118extern int strncasecmp P((const char *s1, const char *s2, register size_t n)); 1119#endif 1120 1121#if defined(atarist) 1122#if defined(PIPES_SIMULATED) 1123/* unsupported/atari/tmpnam.c */ 1124extern char *tmpnam P((char *buf)); 1125extern char *tempnam P((const char *path, const char *base)); 1126#else 1127#include <wait.h> 1128#endif 1129#include <fcntl.h> 1130#define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1) 1131#else 1132#define INVALID_HANDLE (-1) 1133#endif /* atarist */ 1134 1135#ifdef HAVE_SYS_WAIT_H 1136#include <sys/wait.h> 1137#endif 1138#ifndef WEXITSTATUS 1139#define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF) 1140#endif 1141 1142#ifndef STATIC 1143#define STATIC static 1144#endif 1145