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