diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 2001-11-02 21:06:09 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 2001-11-02 21:06:09 +0000 |
commit | d3d782709b16c614378bb4a7e7d39a68f34decba (patch) | |
tree | d547401eaf1e8d58bb3bcd6e38bab2dbbc0bfa5a | |
parent | ce83bef85e2e23eb8d5b30b9f4987d323094c3f4 (diff) |
Notes
-rw-r--r-- | contrib/awk/ACKNOWLEDGMENT | 34 | ||||
-rw-r--r-- | contrib/awk/FREEBSD-upgrade | 60 | ||||
-rw-r--r-- | contrib/awk/PORTS | 29 | ||||
-rw-r--r-- | contrib/awk/aclocal.m4 | 129 | ||||
-rw-r--r-- | contrib/awk/alloca.c | 496 | ||||
-rw-r--r-- | contrib/awk/awk.y | 2479 | ||||
-rw-r--r-- | contrib/awk/awklib/eg/lib/mktime.awk | 105 | ||||
-rw-r--r-- | contrib/awk/awklib/eg/misc/findpat.sh | 10 | ||||
-rw-r--r-- | contrib/awk/awktab.c | 3983 | ||||
-rw-r--r-- | contrib/awk/config.h | 207 | ||||
-rw-r--r-- | contrib/awk/doc/awk.1 | 2627 | ||||
-rw-r--r-- | contrib/awk/missing.c | 59 | ||||
-rw-r--r-- | contrib/awk/patchlevel.h | 1 | ||||
-rw-r--r-- | contrib/awk/test/Makefile | 451 | ||||
-rwxr-xr-x | contrib/awk/test/poundbang | 3 | ||||
-rw-r--r-- | contrib/awk/test/reg/exp.awk | 1 | ||||
-rw-r--r-- | contrib/awk/test/reg/exp.good | 2 | ||||
-rw-r--r-- | contrib/awk/test/reg/exp.in | 0 | ||||
-rw-r--r-- | contrib/awk/test/reg/log.awk | 1 | ||||
-rw-r--r-- | contrib/awk/test/reg/log.good | 4 | ||||
-rw-r--r-- | contrib/awk/test/reg/log.in | 0 | ||||
-rwxr-xr-x | contrib/awk/test/regtest | 18 |
22 files changed, 0 insertions, 10699 deletions
diff --git a/contrib/awk/ACKNOWLEDGMENT b/contrib/awk/ACKNOWLEDGMENT deleted file mode 100644 index 0851ecf9706b..000000000000 --- a/contrib/awk/ACKNOWLEDGMENT +++ /dev/null @@ -1,34 +0,0 @@ -The current developers of Gawk would like to thank and acknowledge the -many people who have contributed to the development through bug reports -and fixes and suggestions. Unfortunately, we have not been organized -enough to keep track of all the names -- for that we apologize. - -The following people were involved in porting gawk to different platforms. - - Mike Lijewski <mjlx@eagle.cnsf.cornell.edu> (IBM RS6000) - Kent Williams (MSDOS 2.11) - Conrad Kwok (MSDOS earlier versions) - Scott Garfinkle (MSDOS earlier versions) - Hal Peterson <hrp@pecan.cray.com> (Cray) - -This group of people comprise the "GAWK crack portability team", who -test the pre-releases and ensure portability of gawk. - - Pat Rankin <gawk.rankin@EQL.Caltech.Edu> (VMS) - Michal Jaegermann <michal@gortel.phys.UAlberta.CA> - (Atari, NeXT, DEC 3100) - Scott Deifik <scottd@amgen.com> (MSDOS 2.14, 2.15, 3.0) - Kai Uwe Rommel <rommel@ars.de> (OS/2) - Darrel Hankerson <hankedr@mail.auburn.edu> (DOS and formerly OS/2) - Mark Moraes <Mark-Moraes@deshaw.com> (Code Center, Purify) - Kaveh Ghazi <ghazi@noc.rutgers.edu> (Lots of Unix variants) - -Michal, Scott and Darrel go out of their way to make sure that gawk -works on non-32 bit systems, and keep me on track where portability is -concerned. Indeed, all of these folks are incredibly helpful; gawk would -not be the fine program it is now without them. - -Last, but far from least, we would like to thank Brian Kernighan who -has helped to clear up many dark corners of the language and provided a -restraining touch when we have been overly tempted by "feeping -creaturism". diff --git a/contrib/awk/FREEBSD-upgrade b/contrib/awk/FREEBSD-upgrade deleted file mode 100644 index d2add40f4737..000000000000 --- a/contrib/awk/FREEBSD-upgrade +++ /dev/null @@ -1,60 +0,0 @@ - -Import of GNU awk 3.0.3 - -Original source available as ftp://prep.ai.mit.edu/pub/gnu/gawk-3.0.3.tar.gz - -The following files and directories were removed for this import: - -Makefile.in -README_d/README.VMS -README_d/README.atari -README_d/README.irix -README_d/README.linux -README_d/README.pc -README_d/README.sco -README_d/README.sgi -README_d/README.solaris -README_d/README.sony -README_d/README.sunos4 -README_d/README.ultrix -README_d/README.yacc -aclocal.m4 -alloca.c -atari/ -awklib/ -awktab.c -configh.in -configure -configure.in -doc/Makefile.in -doc/README.card -doc/ad.block -doc/awkcard.in -doc/awkforai.txt -doc/cardfonts -doc/colors -doc/igawk.1 -doc/macros -doc/no.colors -doc/setter.outline -doc/texinfo.tex -install-sh -missing/ -mkinstalldirs -pc/ -protos.h -regex.c -stamp-h.in -vms/ - -In addition, doc/gawk.1 and doc/gawk.texi were renamed to awk.1 and awk.texi. - -The test sub-directory has been left in, as, although not necessary to build -awk on FreeBSD, it will be useful to anyone changing the code. To use it, -do something like - -cd /usr/src/contrib/awk -ln -s /path/to/new/awk gawk -cd test && make - -jraynard@freebsd.org 26 Sept 1997 diff --git a/contrib/awk/PORTS b/contrib/awk/PORTS deleted file mode 100644 index 8fe8802d970b..000000000000 --- a/contrib/awk/PORTS +++ /dev/null @@ -1,29 +0,0 @@ -Gawk 3.0.5 has been successfully compiled and run "make test" -on the following: - - Linux 2.2.14 gcc 2.95.2 - Linux 2.2.13-SMP egcs-2.91.66 make test -j5 - IRIX64 6.5 gcc 2.8.1 - IRIX 5.3 gcc 2.7.2.2 - SunOS 5.3 gcc 2.5.8 - Linux 2.0.33 gcc 2.7.2.1 - IRIX64 6.5 gcc 2.95.1 - - Apple Macintosh PPC G3 Rhapsody 5.5 - DEC Alpha OSF/1 4.0F - DEC Alpha Linux - HP 9000/735 HP-UX 10.01 - HP PA 1.1 HP-UX 11.00 - IBM PowerPC AIX 4.2 - Intel Pentium III GNU/Linux 2.2.12-20smp (Redhat 6.1) - NeXT Turbostation Mach 3.3 - SGI MIPS IRIX 6.3 - SGI Origin 200 IRIX 6.5 - Sun SPARC GNU/Linux 2.2.12-42smp (Redhat 6.1) - Sun SPARC Solaris 2.6 - Sun SPARC Solaris 2.7 - - DEC Alpha OpenVMS - DEC Vax VMS DEC C - - OS/2 EMX GCC diff --git a/contrib/awk/aclocal.m4 b/contrib/awk/aclocal.m4 deleted file mode 100644 index 7ba39c39cdd6..000000000000 --- a/contrib/awk/aclocal.m4 +++ /dev/null @@ -1,129 +0,0 @@ -dnl -dnl aclocal.m4 --- autoconf input file for gawk -dnl -dnl Copyright (C) 1995, 1996, 1998, 1999, 2000 the Free Software Foundation, Inc. -dnl -dnl This file is part of GAWK, the GNU implementation of the -dnl AWK Progamming Language. -dnl -dnl GAWK is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl GAWK is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -dnl - -dnl gawk-specific macros for autoconf. one day hopefully part of autoconf - -AC_DEFUN(GAWK_AC_C_STRINGIZE, [ -AC_REQUIRE([AC_PROG_CPP]) -AC_MSG_CHECKING([for ANSI stringizing capability]) -AC_CACHE_VAL(gawk_cv_c_stringize, -AC_EGREP_CPP([#teststring],[ -#define x(y) #y - -char *s = x(teststring); -], gawk_cv_c_stringize=no, gawk_cv_c_stringize=yes)) -if test "${gawk_cv_c_stringize}" = yes -then - AC_DEFINE(HAVE_STRINGIZE) -fi -AC_MSG_RESULT([${gawk_cv_c_stringize}]) -])dnl - - -dnl By default, many hosts won't let programs access large files; -dnl one must use special compiler options to get large-file access to work. -dnl For more details about this brain damage please see: -dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html - -dnl Written by Paul Eggert <eggert@twinsun.com>. - -dnl Internal subroutine of GAWK_AC_SYS_LARGEFILE. -dnl GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES -AC_DEFUN(GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES, - [[#include <sys/types.h> - int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1]; - ]]) - -dnl Internal subroutine of GAWK_AC_SYS_LARGEFILE. -dnl GAWK_AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY) -AC_DEFUN(GAWK_AC_SYS_LARGEFILE_MACRO_VALUE, - [AC_CACHE_CHECK([for $1 value needed for large files], $3, - [$3=no - AC_TRY_COMPILE(GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES -$5 - , - [$6], - , - [AC_TRY_COMPILE([#define $1 $2] -GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES -$5 - , - [$6], - [$3=$2])])]) - if test "[$]$3" != no; then - AC_DEFINE_UNQUOTED([$1], [$]$3, [$4]) - fi]) - -AC_DEFUN(GAWK_AC_SYS_LARGEFILE, - [AC_ARG_ENABLE(largefile, - [ --disable-largefile omit support for large files]) - if test "$enable_largefile" != no; then - - AC_CACHE_CHECK([for special C compiler options needed for large files], - gawk_cv_sys_largefile_CC, - [gawk_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - AC_TRY_COMPILE(GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES, , , - [ac_save_CC="$CC" - CC="$CC -n32" - AC_TRY_COMPILE(GAWK_AC_SYS_LARGEFILE_TEST_INCLUDES, , - gawk_cv_sys_largefile_CC=' -n32') - CC="$ac_save_CC"]) - fi]) - if test "$gawk_cv_sys_largefile_CC" != no; then - CC="$CC$gawk_cv_sys_largefile_CC" - fi - - GAWK_AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64, - gawk_cv_sys_file_offset_bits, - [Number of bits in a file offset, on hosts where this is settable.]) - GAWK_AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1, - gawk_cv_sys_largefile_source, - [Define to make ftello visible on some hosts (e.g. HP-UX 10.20).], - [#include <stdio.h>], [return !ftello;]) - GAWK_AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1, - gawk_cv_sys_large_files, - [Define for large files, on AIX-style hosts.]) - GAWK_AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500, - gawk_cv_sys_xopen_source, - [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).], - [#include <stdio.h>], [return !ftello;]) - fi - ]) - -dnl Check for AIX and add _XOPEN_SOURCE_EXTENDED -AC_DEFUN(GAWK_AC_AIX_TWEAK, [ -AC_MSG_CHECKING([for AIX compilation hacks]) -AC_CACHE_VAL(gawk_cv_aix_hack, [ -if test -d /lpp/bos -then - CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=1" - gawk_cv_aix_hack=yes -else - gawk_cv_aix_hack=no -fi -])dnl -AC_MSG_RESULT([${gawk_cv_aix_hack}]) -])dnl diff --git a/contrib/awk/alloca.c b/contrib/awk/alloca.c deleted file mode 100644 index 6bbd9839ba8b..000000000000 --- a/contrib/awk/alloca.c +++ /dev/null @@ -1,496 +0,0 @@ -/* alloca.c -- allocate automatically reclaimed memory - (Mostly) portable public-domain implementation -- D A Gwyn - - This implementation of the PWB library alloca function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - J.Otto Tennant <jot@cray.com> contributed the Cray support. - - There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef emacs -#include "blockinput.h" -#endif - -/* If compiling with GCC 2, this file's not needed. */ -#if !defined (__GNUC__) || __GNUC__ < 2 - -/* If someone has defined alloca as a macro, - there must be some other way alloca is supposed to work. */ -#ifndef alloca - -#ifdef emacs -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ - -/* If your stack is a linked list of frames, you have to - provide an "address metric" ADDRESS_FUNCTION macro. */ - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc (); -#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -#else -#define ADDRESS_FUNCTION(arg) &(arg) -#endif - -#if __STDC__ -typedef void *pointer; -#else -typedef char *pointer; -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef malloc -/* Different portions of Emacs need to call different versions of - malloc. The Emacs executable needs alloca to call xmalloc, because - ordinary malloc isn't protected from input signals. On the other - hand, the utilities in lib-src need alloca to call malloc; some of - them are very simple, and don't have an xmalloc routine. - - Non-Emacs programs expect this to call xmalloc. - - Callers below should use malloc. */ - -#ifndef emacs -#define malloc xmalloc -#endif -extern pointer malloc (); -#endif /* malloc */ - -/* Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* Direction unknown. */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ - -#else /* STACK_DIRECTION == 0; need run-time code. */ - -static int stack_dir; /* 1 or -1 once known. */ -#define STACK_DIR stack_dir - -static void -find_stack_direction () -{ - static char *addr = NULL; /* Address of first `dummy', once known. */ - auto char dummy; /* To get stack address. */ - - if (addr == NULL) - { /* Initial entry. */ - addr = ADDRESS_FUNCTION (dummy); - - find_stack_direction (); /* Recurse once. */ - } - else - { - /* Second entry. */ - if (ADDRESS_FUNCTION (dummy) > addr) - stack_dir = 1; /* Stack grew upward. */ - else - stack_dir = -1; /* Stack grew downward. */ - } -} - -#endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: - (a) chain together all alloca'ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc - alignment chunk size. The following default should work okay. */ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* To force sizeof(header). */ - struct - { - union hdr *next; /* For chaining headers. */ - char *deep; /* For stack depth measure. */ - } h; -} header; - -static header *last_alloca_header = NULL; /* -> last alloca header. */ - -/* Return a pointer to at least SIZE bytes of storage, - which will be automatically reclaimed upon exit from - the procedure that called alloca. Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. */ - -pointer -alloca (size) - unsigned size; -{ - auto char probe; /* Probes stack depth: */ - register char *depth = ADDRESS_FUNCTION (probe); - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* Unknown growth direction. */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca'd storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* Traverses linked list. */ - -#ifdef emacs - BLOCK_INPUT; -#endif - - for (hp = last_alloca_header; hp != NULL;) - if ((STACK_DIR > 0 && hp->h.deep > depth) - || (STACK_DIR < 0 && hp->h.deep < depth)) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* Collect garbage. */ - - hp = np; /* -> next header. */ - } - else - break; /* Rest are not deeper. */ - - last_alloca_header = hp; /* -> last valid storage. */ - -#ifdef emacs - UNBLOCK_INPUT; -#endif - } - - if (size == 0) - return NULL; /* No allocation required. */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = malloc (sizeof (header) + size); - /* Address of header. */ - - ((header *) new)->h.next = last_alloca_header; - ((header *) new)->h.deep = depth; - - last_alloca_header = (header *) new; - - /* User storage begins just after header. */ - - return (pointer) ((char *) new + sizeof (header)); - } -} - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) - -#ifdef DEBUG_I00AFUNC -#include <stdio.h> -#endif - -#ifndef CRAY_STACK -#define CRAY_STACK -#ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header - { - long shgrow:32; /* Number of times stack has grown. */ - long shaseg:32; /* Size of increments to stack. */ - long shhwm:32; /* High water mark of stack. */ - long shsize:32; /* Current size of stack (all segments). */ - }; - -/* The stack segment linkage control information occurs at - the high-address end of a stack segment. (The stack - grows from low addresses to high addresses.) The initial - part of the stack segment linkage control information is - 0200 (octal) words. This provides for register storage - for the routine which overflows the stack. */ - -struct stack_segment_linkage - { - long ss[0200]; /* 0200 overflow words. */ - long sssize:32; /* Number of words in this segment. */ - long ssbase:32; /* Offset to stack base. */ - long:32; - long sspseg:32; /* Offset to linkage control of previous - segment of stack. */ - long:32; - long sstcpt:32; /* Pointer to task common address block. */ - long sscsnm; /* Private control structure number for - microtasking. */ - long ssusr1; /* Reserved for user. */ - long ssusr2; /* Reserved for user. */ - long sstpid; /* Process ID for pid based multi-tasking. */ - long ssgvup; /* Pointer to multitasking thread giveup. */ - long sscray[7]; /* Reserved for Cray Research. */ - long ssa0; - long ssa1; - long ssa2; - long ssa3; - long ssa4; - long ssa5; - long ssa6; - long ssa7; - long sss0; - long sss1; - long sss2; - long sss3; - long sss4; - long sss5; - long sss6; - long sss7; - }; - -#else /* CRAY2 */ -/* The following structure defines the vector of words - returned by the STKSTAT library routine. */ -struct stk_stat - { - long now; /* Current total stack size. */ - long maxc; /* Amount of contiguous space which would - be required to satisfy the maximum - stack demand to date. */ - long high_water; /* Stack high-water mark. */ - long overflows; /* Number of stack overflow ($STKOFEN) calls. */ - long hits; /* Number of internal buffer hits. */ - long extends; /* Number of block extensions. */ - long stko_mallocs; /* Block allocations by $STKOFEN. */ - long underflows; /* Number of stack underflow calls ($STKRETN). */ - long stko_free; /* Number of deallocations by $STKRETN. */ - long stkm_free; /* Number of deallocations by $STKMRET. */ - long segments; /* Current number of stack segments. */ - long maxs; /* Maximum number of stack segments so far. */ - long pad_size; /* Stack pad size. */ - long current_address; /* Current stack segment address. */ - long current_size; /* Current stack segment size. This - number is actually corrupted by STKSTAT to - include the fifteen word trailer area. */ - long initial_address; /* Address of initial segment. */ - long initial_size; /* Size of initial segment. */ - }; - -/* The following structure describes the data structure which trails - any stack segment. I think that the description in 'asdef' is - out of date. I only describe the parts that I am sure about. */ - -struct stk_trailer - { - long this_address; /* Address of this block. */ - long this_size; /* Size of this block (does not include - this trailer). */ - long unknown2; - long unknown3; - long link; /* Address of trailer block of previous - segment. */ - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - long unknown10; - long unknown11; - long unknown12; - long unknown13; - long unknown14; - }; - -#endif /* CRAY2 */ -#endif /* not CRAY_STACK */ - -#ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. - I doubt that "lint" will like this much. */ - -static long -i00afunc (long *address) -{ - struct stk_stat status; - struct stk_trailer *trailer; - long *block, size; - long result = 0; - - /* We want to iterate through all of the segments. The first - step is to get the stack status structure. We could do this - more quickly and more directly, perhaps, by referencing the - $LM00 common block, but I know that this works. */ - - STKSTAT (&status); - - /* Set up the iteration. */ - - trailer = (struct stk_trailer *) (status.current_address - + status.current_size - - 15); - - /* There must be at least one stack segment. Therefore it is - a fatal error if "trailer" is null. */ - - if (trailer == 0) - abort (); - - /* Discard segments that do not contain our argument address. */ - - while (trailer != 0) - { - block = (long *) trailer->this_address; - size = trailer->this_size; - if (block == 0 || size == 0) - abort (); - trailer = (struct stk_trailer *) trailer->link; - if ((block <= address) && (address < (block + size))) - break; - } - - /* Set the result to the offset in this segment and add the sizes - of all predecessor segments. */ - - result = address - block; - - if (trailer == 0) - { - return result; - } - - do - { - if (trailer->this_size <= 0) - abort (); - result += trailer->this_size; - trailer = (struct stk_trailer *) trailer->link; - } - while (trailer != 0); - - /* We are done. Note that if you present a bogus address (one - not in any segment), you will get a different number back, formed - from subtracting the address of the first block. This is probably - not what you want. */ - - return (result); -} - -#else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. - Determine the number of the cell within the stack, - given the address of the cell. The purpose of this - routine is to linearize, in some sense, stack addresses - for alloca. */ - -static long -i00afunc (long address) -{ - long stkl = 0; - - long size, pseg, this_segment, stack; - long result = 0; - - struct stack_segment_linkage *ssptr; - - /* Register B67 contains the address of the end of the - current stack segment. If you (as a subprogram) store - your registers on the stack and find that you are past - the contents of B67, you have overflowed the segment. - - B67 also points to the stack segment linkage control - area, which is what we are really interested in. */ - - stkl = CRAY_STACKSEG_END (); - ssptr = (struct stack_segment_linkage *) stkl; - - /* If one subtracts 'size' from the end of the segment, - one has the address of the first word of the segment. - - If this is not the first segment, 'pseg' will be - nonzero. */ - - pseg = ssptr->sspseg; - size = ssptr->sssize; - - this_segment = stkl - size; - - /* It is possible that calling this routine itself caused - a stack overflow. Discard stack segments which do not - contain the target address. */ - - while (!(this_segment <= address && address <= stkl)) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); -#endif - if (pseg == 0) - break; - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - this_segment = stkl - size; - } - - result = address - this_segment; - - /* If you subtract pseg from the current end of the stack, - you get the address of the previous stack segment's end. - This seems a little convoluted to me, but I'll bet you save - a cycle somewhere. */ - - while (pseg != 0) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o\n", pseg, size); -#endif - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - result += size; - } - return (result); -} - -#endif /* not CRAY2 */ -#endif /* CRAY */ - -#endif /* no alloca */ -#endif /* not GCC version 2 */ diff --git a/contrib/awk/awk.y b/contrib/awk/awk.y deleted file mode 100644 index f6fdfcc5f222..000000000000 --- a/contrib/awk/awk.y +++ /dev/null @@ -1,2479 +0,0 @@ -/* - * awk.y --- yacc/bison parser - */ - -/* - * Copyright (C) 1986, 1988, 1989, 1991-2000 the Free Software Foundation, Inc. - * - * This file is part of GAWK, the GNU implementation of the - * AWK Programming Language. - * - * GAWK is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GAWK is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -%{ -#ifdef DEBUG -#define YYDEBUG 12 -#endif - -#include "awk.h" - -#define CAN_FREE TRUE -#define DONT_FREE FALSE - -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ -static void yyerror(const char *m, ...) ; -#else -static void yyerror(); /* va_alist */ -#endif -static char *get_src_buf P((void)); -static int yylex P((void)); -static NODE *node_common P((NODETYPE op)); -static NODE *snode P((NODE *subn, NODETYPE op, int sindex)); -static NODE *mkrangenode P((NODE *cpair)); -static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr)); -static NODE *append_right P((NODE *list, NODE *new)); -static void func_install P((NODE *params, NODE *def)); -static void pop_var P((NODE *np, int freeit)); -static void pop_params P((NODE *params)); -static NODE *make_param P((char *name)); -static NODE *mk_rexp P((NODE *exp)); -static int dup_parms P((NODE *func)); -static void param_sanity P((NODE *arglist)); -static int isnoeffect P((NODETYPE t)); -static int isassignable P((NODE *n)); - -enum defref { FUNC_DEFINE, FUNC_USE }; -static void func_use P((char *name, enum defref how)); -static void check_funcs P((void)); - -static int want_assign; /* lexical scanning kludge */ -static int want_regexp; /* lexical scanning kludge */ -static int can_return; /* lexical scanning kludge */ -static int io_allowed = TRUE; /* lexical scanning kludge */ -static char *lexptr; /* pointer to next char during parsing */ -static char *lexend; -static char *lexptr_begin; /* keep track of where we were for error msgs */ -static char *lexeme; /* beginning of lexeme for debugging */ -static char *thisline = NULL; -#define YYDEBUG_LEXER_TEXT (lexeme) -static int param_counter; -static char *tokstart = NULL; -static char *tok = NULL; -static char *tokend; - -#define HASHSIZE 1021 /* this constant only used here */ -NODE *variables[HASHSIZE]; - -extern char *source; -extern int sourceline; -extern struct src *srcfiles; -extern int numfiles; -extern int errcount; -extern NODE *begin_block; -extern NODE *end_block; -%} - -%union { - long lval; - AWKNUM fval; - NODE *nodeval; - NODETYPE nodetypeval; - char *sval; - NODE *(*ptrval)(); -} - -%type <nodeval> function_prologue function_body -%type <nodeval> rexp exp start program rule simp_exp -%type <nodeval> non_post_simp_exp -%type <nodeval> pattern -%type <nodeval> action variable param_list -%type <nodeval> rexpression_list opt_rexpression_list -%type <nodeval> expression_list opt_expression_list -%type <nodeval> statements statement if_statement opt_param_list -%type <nodeval> opt_exp opt_variable regexp -%type <nodeval> input_redir output_redir -%type <nodetypeval> print -%type <sval> func_name -%type <lval> lex_builtin - -%token <sval> FUNC_CALL NAME REGEXP -%token <lval> ERROR -%token <nodeval> YNUMBER YSTRING -%token <nodetypeval> RELOP APPEND_OP -%token <nodetypeval> ASSIGNOP MATCHOP NEWLINE CONCAT_OP -%token <nodetypeval> LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE -%token <nodetypeval> LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE -%token <nodetypeval> LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION -%token <nodetypeval> LEX_GETLINE LEX_NEXTFILE -%token <nodetypeval> LEX_IN -%token <lval> LEX_AND LEX_OR INCREMENT DECREMENT -%token <lval> LEX_BUILTIN LEX_LENGTH - -/* these are just yylval numbers */ - -/* Lowest to highest */ -%right ASSIGNOP -%right '?' ':' -%left LEX_OR -%left LEX_AND -%left LEX_GETLINE -%nonassoc LEX_IN -%left FUNC_CALL LEX_BUILTIN LEX_LENGTH -%nonassoc ',' -%nonassoc MATCHOP -%nonassoc RELOP '<' '>' '|' APPEND_OP -%left CONCAT_OP -%left YSTRING YNUMBER -%left '+' '-' -%left '*' '/' '%' -%right '!' UNARY -%right '^' -%left INCREMENT DECREMENT -%left '$' -%left '(' ')' -%% - -start - : opt_nls program opt_nls - { - expression_value = $2; - check_funcs(); - } - ; - -program - : rule - { - if ($1 != NULL) - $$ = $1; - else - $$ = NULL; - yyerrok; - } - | program rule - /* add the rule to the tail of list */ - { - if ($2 == NULL) - $$ = $1; - else if ($1 == NULL) - $$ = $2; - else { - if ($1->type != Node_rule_list) - $1 = node($1, Node_rule_list, - (NODE*) NULL); - $$ = append_right($1, - node($2, Node_rule_list, (NODE *) NULL)); - } - yyerrok; - } - | error { $$ = NULL; } - | program error { $$ = NULL; } - | /* empty */ { $$ = NULL; } - ; - -rule - : LEX_BEGIN { io_allowed = FALSE; } - action - { - if (begin_block != NULL) { - if (begin_block->type != Node_rule_list) - begin_block = node(begin_block, Node_rule_list, - (NODE *) NULL); - (void) append_right(begin_block, node( - node((NODE *) NULL, Node_rule_node, $3), - Node_rule_list, (NODE *) NULL) ); - } else - begin_block = node((NODE *) NULL, Node_rule_node, $3); - $$ = NULL; - io_allowed = TRUE; - yyerrok; - } - | LEX_END { io_allowed = FALSE; } - action - { - if (end_block != NULL) { - if (end_block->type != Node_rule_list) - end_block = node(end_block, Node_rule_list, - (NODE *) NULL); - (void) append_right (end_block, node( - node((NODE *) NULL, Node_rule_node, $3), - Node_rule_list, (NODE *) NULL)); - } else - end_block = node((NODE *) NULL, Node_rule_node, $3); - $$ = NULL; - io_allowed = TRUE; - yyerrok; - } - | LEX_BEGIN statement_term - { - warning("BEGIN blocks must have an action part"); - errcount++; - yyerrok; - } - | LEX_END statement_term - { - warning("END blocks must have an action part"); - errcount++; - yyerrok; - } - | pattern action - { $$ = node($1, Node_rule_node, $2); yyerrok; } - | action - { $$ = node((NODE *) NULL, Node_rule_node, $1); yyerrok; } - | pattern statement_term - { - $$ = node($1, - Node_rule_node, - node(node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL), - Node_K_print, - (NODE *) NULL)); - yyerrok; - } - | function_prologue function_body - { - func_install($1, $2); - $$ = NULL; - yyerrok; - } - ; - -func_name - : NAME - { $$ = $1; } - | FUNC_CALL - { $$ = $1; } - | lex_builtin - { - yyerror("%s() is a built-in function, it cannot be redefined", - tokstart); - errcount++; - /* yyerrok; */ - } - ; - -lex_builtin - : LEX_BUILTIN - | LEX_LENGTH - ; - -function_prologue - : LEX_FUNCTION - { - param_counter = 0; - } - func_name '(' opt_param_list r_paren opt_nls - { - NODE *t; - - t = make_param($3); - t->flags |= FUNC; - $$ = append_right(t, $5); - can_return = TRUE; - /* check for duplicate parameter names */ - if (dup_parms($$)) - errcount++; - } - ; - -function_body - : l_brace statements r_brace opt_semi - { - $$ = $2; - can_return = FALSE; - } - | l_brace r_brace opt_semi opt_nls - { - $$ = node((NODE *) NULL, Node_K_return, (NODE *) NULL); - can_return = FALSE; - } - ; - - -pattern - : exp - { $$ = $1; } - | exp ',' exp - { $$ = mkrangenode(node($1, Node_cond_pair, $3)); } - ; - -regexp - /* - * In this rule, want_regexp tells yylex that the next thing - * is a regexp so it should read up to the closing slash. - */ - : '/' - { ++want_regexp; } - REGEXP '/' - { - NODE *n; - size_t len; - - getnode(n); - n->type = Node_regex; - len = strlen($3); - n->re_exp = make_string($3, len); - n->re_reg = make_regexp($3, len, FALSE, TRUE); - n->re_text = NULL; - n->re_flags = CONST; - n->re_cnt = 1; - $$ = n; - } - ; - -action - : l_brace statements r_brace opt_semi opt_nls - { $$ = $2; } - | l_brace r_brace opt_semi opt_nls - { $$ = NULL; } - ; - -statements - : statement - { - $$ = $1; - if (do_lint && isnoeffect($$->type)) - warning("statement may have no effect"); - } - | statements statement - { - if ($1 == NULL || $1->type != Node_statement_list) - $1 = node($1, Node_statement_list, (NODE *) NULL); - $$ = append_right($1, - node($2, Node_statement_list, (NODE *) NULL)); - yyerrok; - } - | error - { $$ = NULL; } - | statements error - { $$ = NULL; } - ; - -statement_term - : nls - | semi opt_nls - ; - -statement - : semi opt_nls - { $$ = NULL; } - | l_brace r_brace - { $$ = NULL; } - | l_brace statements r_brace - { $$ = $2; } - | if_statement - { $$ = $1; } - | LEX_WHILE '(' exp r_paren opt_nls statement - { $$ = node($3, Node_K_while, $6); } - | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls - { $$ = node($6, Node_K_do, $3); } - | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement - { - /* - * Efficiency hack. Recognize the special case of - * - * for (iggy in foo) - * delete foo[iggy] - * - * and treat it as if it were - * - * delete foo - * - * Check that the body is a `delete a[i]' statement, - * and that both the loop var and array names match. - */ - if ($8->type == Node_K_delete - && $8->rnode != NULL - && strcmp($3, $8->rnode->var_value->vname) == 0 - && strcmp($5, $8->lnode->vname) == 0) { - $8->type = Node_K_delete_loop; - $$ = $8; - } else { - $$ = node($8, Node_K_arrayfor, - make_for_loop(variable($3, CAN_FREE, Node_var), - (NODE *) NULL, variable($5, CAN_FREE, Node_var_array))); - } - } - | LEX_FOR '(' opt_exp semi exp semi opt_exp r_paren opt_nls statement - { - $$ = node($10, Node_K_for, (NODE *) make_for_loop($3, $5, $7)); - } - | LEX_FOR '(' opt_exp semi semi opt_exp r_paren opt_nls statement - { - $$ = node($9, Node_K_for, - (NODE *) make_for_loop($3, (NODE *) NULL, $6)); - } - | LEX_BREAK statement_term - /* for break, maybe we'll have to remember where to break to */ - { $$ = node((NODE *) NULL, Node_K_break, (NODE *) NULL); } - | LEX_CONTINUE statement_term - /* similarly */ - { $$ = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); } - | print '(' expression_list r_paren output_redir statement_term - { $$ = node($3, $1, $5); } - | print opt_rexpression_list output_redir statement_term - { - if ($1 == Node_K_print && $2 == NULL) { - static int warned = FALSE; - - $2 = node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL); - - if (do_lint && ! io_allowed && ! warned) { - warned = TRUE; - warning( - "plain `print' in BEGIN or END rule should probably be `print \"\"'"); - } - } - - $$ = node($2, $1, $3); - } - | LEX_NEXT opt_exp statement_term - { NODETYPE type; - - if ($2) { - if ($2 == lookup("file")) { - static int warned = FALSE; - - if (! warned) { - warned = TRUE; - warning("`next file' is obsolete; use `nextfile'"); - } - if (do_lint) - warning("`next file' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`next file' is a gawk extension"); - } - if (! io_allowed) { - /* same thing */ - errcount++; - error("`next file' used in BEGIN or END action"); - } - type = Node_K_nextfile; - } else { - errcount++; - error("illegal expression after `next'"); - type = Node_K_next; /* sanity */ - } - } else { - if (! io_allowed) - yyerror("`next' used in BEGIN or END action"); - type = Node_K_next; - } - $$ = node((NODE *) NULL, type, (NODE *) NULL); - } - | LEX_NEXTFILE statement_term - { - if (do_lint) - warning("`nextfile' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`nextfile' is a gawk extension"); - } - if (! io_allowed) { - /* same thing */ - errcount++; - error("`nextfile' used in BEGIN or END action"); - } - $$ = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL); - } - | LEX_EXIT opt_exp statement_term - { $$ = node($2, Node_K_exit, (NODE *) NULL); } - | LEX_RETURN - { - if (! can_return) - yyerror("`return' used outside function context"); - } - opt_exp statement_term - { $$ = node($3, Node_K_return, (NODE *) NULL); } - | LEX_DELETE NAME '[' expression_list ']' statement_term - { $$ = node(variable($2, CAN_FREE, Node_var_array), Node_K_delete, $4); } - | LEX_DELETE NAME statement_term - { - if (do_lint) - warning("`delete array' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`delete array' is a gawk extension"); - } - $$ = node(variable($2, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL); - } - | exp statement_term - { $$ = $1; } - ; - -print - : LEX_PRINT - { $$ = $1; } - | LEX_PRINTF - { $$ = $1; } - ; - -if_statement - : LEX_IF '(' exp r_paren opt_nls statement - { - $$ = node($3, Node_K_if, - node($6, Node_if_branches, (NODE *) NULL)); - } - | LEX_IF '(' exp r_paren opt_nls statement - LEX_ELSE opt_nls statement - { $$ = node($3, Node_K_if, - node($6, Node_if_branches, $9)); } - ; - -nls - : NEWLINE - { want_assign = FALSE; } - | nls NEWLINE - ; - -opt_nls - : /* empty */ - | nls - ; - -input_redir - : /* empty */ - { $$ = NULL; } - | '<' simp_exp - { $$ = node($2, Node_redirect_input, (NODE *) NULL); } - ; - -output_redir - : /* empty */ - { $$ = NULL; } - | '>' exp - { $$ = node($2, Node_redirect_output, (NODE *) NULL); } - | APPEND_OP exp - { $$ = node($2, Node_redirect_append, (NODE *) NULL); } - | '|' exp - { $$ = node($2, Node_redirect_pipe, (NODE *) NULL); } - ; - -opt_param_list - : /* empty */ - { $$ = NULL; } - | param_list - { $$ = $1; } - ; - -param_list - : NAME - { $$ = make_param($1); } - | param_list comma NAME - { $$ = append_right($1, make_param($3)); yyerrok; } - | error - { $$ = NULL; } - | param_list error - { $$ = NULL; } - | param_list comma error - { $$ = NULL; } - ; - -/* optional expression, as in for loop */ -opt_exp - : /* empty */ - { $$ = NULL; } - | exp - { $$ = $1; } - ; - -opt_rexpression_list - : /* empty */ - { $$ = NULL; } - | rexpression_list - { $$ = $1; } - ; - -rexpression_list - : rexp - { $$ = node($1, Node_expression_list, (NODE *) NULL); } - | rexpression_list comma rexp - { - $$ = append_right($1, - node($3, Node_expression_list, (NODE *) NULL)); - yyerrok; - } - | error - { $$ = NULL; } - | rexpression_list error - { $$ = NULL; } - | rexpression_list error rexp - { $$ = NULL; } - | rexpression_list comma error - { $$ = NULL; } - ; - -opt_expression_list - : /* empty */ - { $$ = NULL; } - | expression_list - { $$ = $1; } - ; - -expression_list - : exp - { $$ = node($1, Node_expression_list, (NODE *) NULL); } - | expression_list comma exp - { - $$ = append_right($1, - node($3, Node_expression_list, (NODE *) NULL)); - yyerrok; - } - | error - { $$ = NULL; } - | expression_list error - { $$ = NULL; } - | expression_list error exp - { $$ = NULL; } - | expression_list comma error - { $$ = NULL; } - ; - -/* Expressions, not including the comma operator. */ -exp : variable ASSIGNOP - { want_assign = FALSE; } - exp - { - if (do_lint && $4->type == Node_regex) - warning("Regular expression on left of assignment."); - $$ = node($1, $2, $4); - } - | '(' expression_list r_paren LEX_IN NAME - { $$ = node(variable($5, CAN_FREE, Node_var_array), Node_in_array, $2); } - | exp '|' LEX_GETLINE opt_variable - { - $$ = node($4, Node_K_getline, - node($1, Node_redirect_pipein, (NODE *) NULL)); - } - | LEX_GETLINE opt_variable input_redir - { - if (do_lint && ! io_allowed && $3 == NULL) - warning("non-redirected getline undefined inside BEGIN or END action"); - $$ = node($2, Node_K_getline, $3); - } - | exp LEX_AND exp - { $$ = node($1, Node_and, $3); } - | exp LEX_OR exp - { $$ = node($1, Node_or, $3); } - | exp MATCHOP exp - { - if ($1->type == Node_regex) - warning("Regular expression on left of MATCH operator."); - $$ = node($1, $2, mk_rexp($3)); - } - | regexp - { - $$ = $1; - if (do_lint && tokstart[0] == '*') { - /* possible C comment */ - int n = strlen(tokstart) - 1; - if (tokstart[n] == '*') - warning("regexp looks like a C comment, but is not"); - } - } - | '!' regexp %prec UNARY - { - $$ = node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_nomatch, - $2); - } - | exp LEX_IN NAME - { $$ = node(variable($3, CAN_FREE, Node_var_array), Node_in_array, $1); } - | exp RELOP exp - { - if (do_lint && $3->type == Node_regex) - warning("Regular expression on left of comparison."); - $$ = node($1, $2, $3); - } - | exp '<' exp - { $$ = node($1, Node_less, $3); } - | exp '>' exp - { $$ = node($1, Node_greater, $3); } - | exp '?' exp ':' exp - { $$ = node($1, Node_cond_exp, node($3, Node_if_branches, $5));} - | simp_exp - { $$ = $1; } - | exp simp_exp %prec CONCAT_OP - { $$ = node($1, Node_concat, $2); } - ; - -rexp - : variable ASSIGNOP - { want_assign = FALSE; } - rexp - { $$ = node($1, $2, $4); } - | rexp LEX_AND rexp - { $$ = node($1, Node_and, $3); } - | rexp LEX_OR rexp - { $$ = node($1, Node_or, $3); } - | LEX_GETLINE opt_variable input_redir - { - if (do_lint && ! io_allowed && $3 == NULL) - warning("non-redirected getline undefined inside BEGIN or END action"); - $$ = node($2, Node_K_getline, $3); - } - | regexp - { $$ = $1; } - | '!' regexp %prec UNARY - { $$ = node((NODE *) NULL, Node_nomatch, $2); } - | rexp MATCHOP rexp - { $$ = node($1, $2, mk_rexp($3)); } - | rexp LEX_IN NAME - { $$ = node(variable($3, CAN_FREE, Node_var_array), Node_in_array, $1); } - | rexp RELOP rexp - { $$ = node($1, $2, $3); } - | rexp '?' rexp ':' rexp - { $$ = node($1, Node_cond_exp, node($3, Node_if_branches, $5));} - | simp_exp - { $$ = $1; } - | rexp simp_exp %prec CONCAT_OP - { $$ = node($1, Node_concat, $2); } - ; - -simp_exp - : non_post_simp_exp - /* Binary operators in order of decreasing precedence. */ - | simp_exp '^' simp_exp - { $$ = node($1, Node_exp, $3); } - | simp_exp '*' simp_exp - { $$ = node($1, Node_times, $3); } - | simp_exp '/' simp_exp - { $$ = node($1, Node_quotient, $3); } - | simp_exp '%' simp_exp - { $$ = node($1, Node_mod, $3); } - | simp_exp '+' simp_exp - { $$ = node($1, Node_plus, $3); } - | simp_exp '-' simp_exp - { $$ = node($1, Node_minus, $3); } - | variable INCREMENT - { $$ = node($1, Node_postincrement, (NODE *) NULL); } - | variable DECREMENT - { $$ = node($1, Node_postdecrement, (NODE *) NULL); } - ; - -non_post_simp_exp - : '!' simp_exp %prec UNARY - { $$ = node($2, Node_not, (NODE *) NULL); } - | '(' exp r_paren - { $$ = $2; } - | LEX_BUILTIN - '(' opt_expression_list r_paren - { $$ = snode($3, Node_builtin, (int) $1); } - | LEX_LENGTH '(' opt_expression_list r_paren - { $$ = snode($3, Node_builtin, (int) $1); } - | LEX_LENGTH - { - if (do_lint) - warning("call of `length' without parentheses is not portable"); - $$ = snode((NODE *) NULL, Node_builtin, (int) $1); - if (do_posix) - warning("call of `length' without parentheses is deprecated by POSIX"); - } - | FUNC_CALL '(' opt_expression_list r_paren - { - $$ = node($3, Node_func_call, make_string($1, strlen($1))); - func_use($1, FUNC_USE); - param_sanity($3); - free($1); - } - | variable - | INCREMENT variable - { $$ = node($2, Node_preincrement, (NODE *) NULL); } - | DECREMENT variable - { $$ = node($2, Node_predecrement, (NODE *) NULL); } - | YNUMBER - { $$ = $1; } - | YSTRING - { $$ = $1; } - - | '-' simp_exp %prec UNARY - { - if ($2->type == Node_val) { - $2->numbr = -(force_number($2)); - $$ = $2; - } else - $$ = node($2, Node_unary_minus, (NODE *) NULL); - } - | '+' simp_exp %prec UNARY - { - /* - * was: $$ = $2 - * POSIX semantics: force a conversion to numeric type - */ - $$ = node (make_number(0.0), Node_plus, $2); - } - ; - -opt_variable - : /* empty */ - { $$ = NULL; } - | variable - { $$ = $1; } - ; - -variable - : NAME - { $$ = variable($1, CAN_FREE, Node_var); } - | NAME '[' expression_list ']' - { - if ($3 == NULL) { - fatal("invalid subscript expression"); - } else if ($3->rnode == NULL) { - $$ = node(variable($1, CAN_FREE, Node_var_array), Node_subscript, $3->lnode); - freenode($3); - } else - $$ = node(variable($1, CAN_FREE, Node_var_array), Node_subscript, $3); - } - | '$' non_post_simp_exp - { $$ = node($2, Node_field_spec, (NODE *) NULL); } - ; - -l_brace - : '{' opt_nls - ; - -r_brace - : '}' opt_nls { yyerrok; } - ; - -r_paren - : ')' { yyerrok; } - ; - -opt_semi - : /* empty */ - | semi - ; - -semi - : ';' { yyerrok; want_assign = FALSE; } - ; - -comma : ',' opt_nls { yyerrok; } - ; - -%% - -struct token { - const char *operator; /* text to match */ - NODETYPE value; /* node type */ - int class; /* lexical class */ - unsigned flags; /* # of args. allowed and compatability */ -# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */ -# define A(n) (1<<(n)) -# define VERSION 0xFF00 /* old awk is zero */ -# define NOT_OLD 0x0100 /* feature not in old awk */ -# define NOT_POSIX 0x0200 /* feature not in POSIX */ -# define GAWKX 0x0400 /* gawk extension */ -# define RESX 0x0800 /* Bell Labs Research extension */ - NODE *(*ptr)(); /* function that implements this keyword */ -}; - - -/* Tokentab is sorted ascii ascending order, so it can be binary searched. */ -/* Function pointers come from declarations in awk.h. */ - -static struct token tokentab[] = { -{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0}, -{"END", Node_illegal, LEX_END, 0, 0}, -#ifdef ARRAYDEBUG -{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump}, -#endif -#ifdef BITOPS -{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and}, -#endif /* BITOPS */ -{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2}, -{"break", Node_K_break, LEX_BREAK, 0, 0}, -{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_close}, -#ifdef BITOPS -{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl}, -#endif /* BITOPS */ -{"continue", Node_K_continue, LEX_CONTINUE, 0, 0}, -{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos}, -{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0}, -{"do", Node_K_do, LEX_DO, NOT_OLD, 0}, -{"else", Node_illegal, LEX_ELSE, 0, 0}, -{"exit", Node_K_exit, LEX_EXIT, 0, 0}, -{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp}, -{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush}, -{"for", Node_K_for, LEX_FOR, 0, 0}, -{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, -{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0}, -{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, -{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0}, -{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, -{"if", Node_K_if, LEX_IF, 0, 0}, -{"in", Node_illegal, LEX_IN, 0, 0}, -{"index", Node_builtin, LEX_BUILTIN, A(2), do_index}, -{"int", Node_builtin, LEX_BUILTIN, A(1), do_int}, -{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length}, -{"log", Node_builtin, LEX_BUILTIN, A(1), do_log}, -#ifdef BITOPS -{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift}, -#endif /* BITOPS */ -{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_match}, -{"next", Node_K_next, LEX_NEXT, 0, 0}, -{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0}, -#ifdef BITOPS -{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or}, -#endif /* BITOPS */ -{"print", Node_K_print, LEX_PRINT, 0, 0}, -{"printf", Node_K_printf, LEX_PRINTF, 0, 0}, -{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand}, -{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0}, -#ifdef BITOPS -{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift}, -#endif /* BITOPS */ -{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin}, -{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split}, -{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf}, -{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt}, -{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand}, -#ifdef ARRAYDEBUG -{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme}, -#endif -{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime}, -#ifdef BITOPS -{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, -#endif /* BITOPS */ -{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, -{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, -{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, -{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime}, -{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower}, -{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper}, -{"while", Node_K_while, LEX_WHILE, 0, 0}, -#ifdef BITOPS -{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor}, -#endif /* BITOPS */ -}; - -/* yyerror --- print a syntax error message, show where */ - -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ -static void -yyerror(const char *m, ...) -#else -/* VARARGS0 */ -static void -yyerror(va_alist) -va_dcl -#endif -{ - va_list args; - const char *mesg = NULL; - register char *bp, *cp; - char *scan; - char buf[120]; - static char end_of_file_line[] = "(END OF FILE)"; - - errcount++; - /* Find the current line in the input file */ - if (lexptr && lexeme) { - if (thisline == NULL) { - cp = lexeme; - if (*cp == '\n') { - cp--; - mesg = "unexpected newline"; - } - for (; cp != lexptr_begin && *cp != '\n'; --cp) - continue; - if (*cp == '\n') - cp++; - thisline = cp; - } - /* NL isn't guaranteed */ - bp = lexeme; - while (bp < lexend && *bp && *bp != '\n') - bp++; - } else { - thisline = end_of_file_line; - bp = thisline + strlen(thisline); - } - msg("%.*s", (int) (bp - thisline), thisline); - bp = buf; - cp = buf + sizeof(buf) - 24; /* 24 more than longest msg. input */ - if (lexptr != NULL) { - scan = thisline; - while (bp < cp && scan < lexeme) - if (*scan++ == '\t') - *bp++ = '\t'; - else - *bp++ = ' '; - *bp++ = '^'; - *bp++ = ' '; - } -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ - va_start(args, m); - if (mesg == NULL) - mesg = m; -#else - va_start(args); - if (mesg == NULL) - mesg = va_arg(args, char *); -#endif - strcpy(bp, mesg); - err("", buf, args); - va_end(args); -} - -/* get_src_buf --- read the next buffer of source program */ - -static char * -get_src_buf() -{ - static int samefile = FALSE; - static int nextfile = 0; - static char *buf = NULL; - static int fd; - int n; - register char *scan; - static int len = 0; - static int did_newline = FALSE; - int newfile; - struct stat sbuf; - -# define SLOP 128 /* enough space to hold most source lines */ - -again: - newfile = FALSE; - if (nextfile > numfiles) - return NULL; - - if (srcfiles[nextfile].stype == CMDLINE) { - if (len == 0) { - len = strlen(srcfiles[nextfile].val); - if (len == 0) { - /* - * Yet Another Special case: - * gawk '' /path/name - * Sigh. - */ - static int warned = FALSE; - - if (do_lint && ! warned) { - warned = TRUE; - warning("empty program text on command line"); - } - ++nextfile; - goto again; - } - sourceline = 1; - lexptr = lexptr_begin = srcfiles[nextfile].val; - lexend = lexptr + len; - } else if (! did_newline && *(lexptr-1) != '\n') { - /* - * The following goop is to ensure that the source - * ends with a newline and that the entire current - * line is available for error messages. - */ - int offset; - - did_newline = TRUE; - offset = lexptr - lexeme; - for (scan = lexeme; scan > lexptr_begin; scan--) - if (*scan == '\n') { - scan++; - break; - } - len = lexptr - scan; - emalloc(buf, char *, len+1, "get_src_buf"); - memcpy(buf, scan, len); - thisline = buf; - lexptr = buf + len; - *lexptr = '\n'; - lexeme = lexptr - offset; - lexptr_begin = buf; - lexend = lexptr + 1; - } else { - len = 0; - lexeme = lexptr = lexptr_begin = NULL; - } - if (lexptr == NULL && ++nextfile <= numfiles) - goto again; - return lexptr; - } - if (! samefile) { - source = srcfiles[nextfile].val; - if (source == NULL) { - if (buf != NULL) { - free(buf); - buf = NULL; - } - len = 0; - return lexeme = lexptr = lexptr_begin = NULL; - } - fd = pathopen(source); - if (fd <= INVALID_HANDLE) { - char *in; - - /* suppress file name and line no. in error mesg */ - in = source; - source = NULL; - fatal("can't open source file \"%s\" for reading (%s)", - in, strerror(errno)); - } - len = optimal_bufsize(fd, & sbuf); - newfile = TRUE; - if (buf != NULL) - free(buf); - emalloc(buf, char *, len + SLOP, "get_src_buf"); - lexptr_begin = buf + SLOP; - samefile = TRUE; - sourceline = 1; - } else { - /* - * Here, we retain the current source line (up to length SLOP) - * in the beginning of the buffer that was overallocated above - */ - int offset; - int linelen; - - offset = lexptr - lexeme; - for (scan = lexeme; scan > lexptr_begin; scan--) - if (*scan == '\n') { - scan++; - break; - } - linelen = lexptr - scan; - if (linelen > SLOP) - linelen = SLOP; - thisline = buf + SLOP - linelen; - memcpy(thisline, scan, linelen); - lexeme = buf + SLOP - offset; - lexptr_begin = thisline; - } - n = read(fd, buf + SLOP, len); - if (n == -1) - fatal("can't read sourcefile \"%s\" (%s)", - source, strerror(errno)); - if (n == 0) { - if (newfile) { - static int warned = FALSE; - - if (do_lint && ! warned) { - warned = TRUE; - warning("source file `%s' is empty", source); - } - } - if (fileno(stdin) != fd) /* safety */ - close(fd); - samefile = FALSE; - nextfile++; - if (lexeme) - *lexeme = '\0'; - len = 0; - goto again; - } - lexptr = buf + SLOP; - lexend = lexptr + n; - return buf; -} - -/* tokadd --- add a character to the token buffer */ - -#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok) - -/* tokexpand --- grow the token buffer */ - -char * -tokexpand() -{ - static int toksize = 60; - int tokoffset; - - tokoffset = tok - tokstart; - toksize *= 2; - if (tokstart != NULL) - erealloc(tokstart, char *, toksize, "tokexpand"); - else - emalloc(tokstart, char *, toksize, "tokexpand"); - tokend = tokstart + toksize; - tok = tokstart + tokoffset; - return tok; -} - -/* nextc --- get the next input character */ - -#if DEBUG -int -nextc() -{ - int c; - - if (lexptr && lexptr < lexend) - c = (int) (unsigned char) *lexptr++; - else if (get_src_buf()) - c = (int) (unsigned char) *lexptr++; - else - c = EOF; - - return c; -} -#else -#define nextc() ((lexptr && lexptr < lexend) ? \ - ((int) (unsigned char) *lexptr++) : \ - (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \ - ) -#endif - -/* pushback --- push a character back on the input */ - -#define pushback() (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr) - -/* allow_newline --- allow newline after &&, ||, ? and : */ - -static void -allow_newline() -{ - int c; - - for (;;) { - c = nextc(); - if (c == EOF) - break; - if (c == '#') { - while ((c = nextc()) != '\n' && c != EOF) - continue; - if (c == EOF) - break; - } - if (c == '\n') - sourceline++; - if (! isspace(c)) { - pushback(); - break; - } - } -} - -/* yylex --- Read the input and turn it into tokens. */ - -static int -yylex() -{ - register int c, c1; - int seen_e = FALSE; /* These are for numbers */ - int seen_point = FALSE; - int esc_seen; /* for literal strings */ - int low, mid, high; - static int did_newline = FALSE; - char *tokkey; - static int lasttok = 0, eof_warned = FALSE; - int inhex = FALSE; - - if (nextc() == EOF) { - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - } - pushback(); -#ifdef OS2 - /* - * added for OS/2's extproc feature of cmd.exe - * (like #! in BSD sh) - */ - if (strncasecmp(lexptr, "extproc ", 8) == 0) { - while (*lexptr && *lexptr != '\n') - lexptr++; - } -#endif - lexeme = lexptr; - thisline = NULL; - if (want_regexp) { - int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ - /* - * Counting brackets is non-trivial. [[] is ok, - * and so is [\]], with a point being that /[/]/ as a regexp - * constant has to work. - * - * Do not count [ or ] if either one is preceded by a \. - * A `[' should be counted if - * a) it is the first one so far (in_brack == 0) - * b) it is the `[' in `[:' - * A ']' should be counted if not preceded by a \, since - * it is either closing `:]' or just a plain list. - * According to POSIX, []] is how you put a ] into a set. - * Try to handle that too. - * - * The code for \ handles \[ and \]. - */ - - want_regexp = FALSE; - tok = tokstart; - for (;;) { - c = nextc(); - switch (c) { - case '[': - /* one day check for `.' and `=' too */ - if ((c1 = nextc()) == ':' || in_brack == 0) - in_brack++; - pushback(); - break; - case ']': - if (tokstart[0] == '[' - && (tok == tokstart + 1 - || (tok == tokstart + 2 - && tokstart[1] == '^'))) - /* do nothing */; - else - in_brack--; - break; - case '\\': - if ((c = nextc()) == EOF) { - yyerror("unterminated regexp ends with \\ at end of file"); - return lasttok = REGEXP; /* kludge */ - } else if (c == '\n') { - sourceline++; - continue; - } else { - tokadd('\\'); - tokadd(c); - continue; - } - break; - case '/': /* end of the regexp */ - if (in_brack > 0) - break; - - pushback(); - tokadd('\0'); - yylval.sval = tokstart; - return lasttok = REGEXP; - case '\n': - pushback(); - yyerror("unterminated regexp"); - return lasttok = REGEXP; /* kludge */ - case EOF: - yyerror("unterminated regexp at end of file"); - return lasttok = REGEXP; /* kludge */ - } - tokadd(c); - } - } -retry: - while ((c = nextc()) == ' ' || c == '\t') - continue; - - lexeme = lexptr ? lexptr - 1 : lexptr; - thisline = NULL; - tok = tokstart; - yylval.nodetypeval = Node_illegal; - - switch (c) { - case EOF: - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - - case '\n': - sourceline++; - return lasttok = NEWLINE; - - case '#': /* it's a comment */ - while ((c = nextc()) != '\n') { - if (c == EOF) { - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning( - "source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - } - } - sourceline++; - return lasttok = NEWLINE; - - case '\\': -#ifdef RELAXED_CONTINUATION - /* - * This code puports to allow comments and/or whitespace - * after the `\' at the end of a line used for continuation. - * Use it at your own risk. We think it's a bad idea, which - * is why it's not on by default. - */ - if (! do_traditional) { - /* strip trailing white-space and/or comment */ - while ((c = nextc()) == ' ' || c == '\t') - continue; - if (c == '#') { - if (do_lint) - warning( - "use of `\\ #...' line continuation is not portable"); - while ((c = nextc()) != '\n') - if (c == EOF) - break; - } - pushback(); - } -#endif /* RELAXED_CONTINUATION */ - if (nextc() == '\n') { - sourceline++; - goto retry; - } else { - yyerror("backslash not last character on line"); - exit(1); - } - break; - - case '$': - want_assign = TRUE; - return lasttok = '$'; - - case ':': - case '?': - allow_newline(); - return lasttok = c; - - case ')': - case '(': - case ';': - case '{': - case ',': - want_assign = FALSE; - /* fall through */ - case '[': - case ']': - return lasttok = c; - - case '*': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_times; - return lasttok = ASSIGNOP; - } else if (do_posix) { - pushback(); - return lasttok = '*'; - } else if (c == '*') { - /* make ** and **= aliases for ^ and ^= */ - static int did_warn_op = FALSE, did_warn_assgn = FALSE; - - if (nextc() == '=') { - if (do_lint && ! did_warn_assgn) { - did_warn_assgn = TRUE; - warning("**= is not allowed by POSIX"); - warning("operator `**=' is not supported in old awk"); - } - yylval.nodetypeval = Node_assign_exp; - return ASSIGNOP; - } else { - pushback(); - if (do_lint && ! did_warn_op) { - did_warn_op = TRUE; - warning("** is not allowed by POSIX"); - warning("operator `**' is not supported in old awk"); - } - return lasttok = '^'; - } - } - pushback(); - return lasttok = '*'; - - case '/': - if (want_assign) { - if (nextc() == '=') { - yylval.nodetypeval = Node_assign_quotient; - return lasttok = ASSIGNOP; - } - pushback(); - } - return lasttok = '/'; - - case '%': - if (nextc() == '=') { - yylval.nodetypeval = Node_assign_mod; - return lasttok = ASSIGNOP; - } - pushback(); - return lasttok = '%'; - - case '^': - { - static int did_warn_op = FALSE, did_warn_assgn = FALSE; - - if (nextc() == '=') { - if (do_lint && ! did_warn_assgn) { - did_warn_assgn = TRUE; - warning("operator `^=' is not supported in old awk"); - } - yylval.nodetypeval = Node_assign_exp; - return lasttok = ASSIGNOP; - } - pushback(); - if (do_lint && ! did_warn_op) { - did_warn_op = TRUE; - warning("operator `^' is not supported in old awk"); - } - return lasttok = '^'; - } - - case '+': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_plus; - return lasttok = ASSIGNOP; - } - if (c == '+') - return lasttok = INCREMENT; - pushback(); - return lasttok = '+'; - - case '!': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_notequal; - return lasttok = RELOP; - } - if (c == '~') { - yylval.nodetypeval = Node_nomatch; - want_assign = FALSE; - return lasttok = MATCHOP; - } - pushback(); - return lasttok = '!'; - - case '<': - if (nextc() == '=') { - yylval.nodetypeval = Node_leq; - return lasttok = RELOP; - } - yylval.nodetypeval = Node_less; - pushback(); - return lasttok = '<'; - - case '=': - if (nextc() == '=') { - yylval.nodetypeval = Node_equal; - return lasttok = RELOP; - } - yylval.nodetypeval = Node_assign; - pushback(); - return lasttok = ASSIGNOP; - - case '>': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_geq; - return lasttok = RELOP; - } else if (c == '>') { - yylval.nodetypeval = Node_redirect_append; - return lasttok = APPEND_OP; - } - yylval.nodetypeval = Node_greater; - pushback(); - return lasttok = '>'; - - case '~': - yylval.nodetypeval = Node_match; - want_assign = FALSE; - return lasttok = MATCHOP; - - case '}': - /* - * Added did newline stuff. Easier than - * hacking the grammar. - */ - if (did_newline) { - did_newline = FALSE; - return lasttok = c; - } - did_newline++; - --lexptr; /* pick up } next time */ - return lasttok = NEWLINE; - - case '"': - esc_seen = FALSE; - while ((c = nextc()) != '"') { - if (c == '\n') { - pushback(); - yyerror("unterminated string"); - exit(1); - } - if (c == '\\') { - c = nextc(); - if (c == '\n') { - sourceline++; - continue; - } - esc_seen = TRUE; - tokadd('\\'); - } - if (c == EOF) { - pushback(); - yyerror("unterminated string"); - exit(1); - } - tokadd(c); - } - yylval.nodeval = make_str_node(tokstart, - tok - tokstart, esc_seen ? SCAN : 0); - yylval.nodeval->flags |= PERM; - return lasttok = YSTRING; - - case '-': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_minus; - return lasttok = ASSIGNOP; - } - if (c == '-') - return lasttok = DECREMENT; - pushback(); - return lasttok = '-'; - - case '.': - c = nextc(); - pushback(); - if (! isdigit(c)) - return lasttok = '.'; - else - c = '.'; - /* FALL THROUGH */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* It's a number */ - for (;;) { - int gotnumber = FALSE; - - tokadd(c); - switch (c) { -#ifdef BITOPS - case 'x': - case 'X': - if (do_traditional) - goto done; - if (tok == tokstart + 2) - inhex = TRUE; - break; -#endif /* BITOTS */ - case '.': - if (seen_point) { - gotnumber = TRUE; - break; - } - seen_point = TRUE; - break; - case 'e': - case 'E': - if (inhex) - break; - if (seen_e) { - gotnumber = TRUE; - break; - } - seen_e = TRUE; - if ((c = nextc()) == '-' || c == '+') - tokadd(c); - else - pushback(); - break; -#ifdef BITOPS - case 'a': - case 'A': - case 'b': - case 'B': - case 'c': - case 'C': - case 'D': - case 'd': - case 'f': - case 'F': - if (do_traditional || ! inhex) - goto done; - /* fall through */ -#endif - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - default: - done: - gotnumber = TRUE; - } - if (gotnumber) - break; - c = nextc(); - } - if (c != EOF) - pushback(); - else if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - tokadd('\0'); -#ifdef BITOPS - if (! do_traditional && isnondecimal(tokstart)) - yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart))); - else -#endif /* BITOPS */ - yylval.nodeval = make_number(atof(tokstart)); - yylval.nodeval->flags |= PERM; - return lasttok = YNUMBER; - - case '&': - if ((c = nextc()) == '&') { - yylval.nodetypeval = Node_and; - allow_newline(); - want_assign = FALSE; - return lasttok = LEX_AND; - } - pushback(); - return lasttok = '&'; - - case '|': - if ((c = nextc()) == '|') { - yylval.nodetypeval = Node_or; - allow_newline(); - want_assign = FALSE; - return lasttok = LEX_OR; - } - pushback(); - return lasttok = '|'; - } - - if (c != '_' && ! isalpha(c)) { - yyerror("Invalid char '%c' in expression\n", c); - exit(1); - } - - /* it's some type of name-type-thing. Find its length. */ - tok = tokstart; - while (is_identchar(c)) { - tokadd(c); - c = nextc(); - } - tokadd('\0'); - emalloc(tokkey, char *, tok - tokstart, "yylex"); - memcpy(tokkey, tokstart, tok - tokstart); - if (c != EOF) - pushback(); - else if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - - /* See if it is a special token. */ - low = 0; - high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1; - while (low <= high) { - int i; - - mid = (low + high) / 2; - c = *tokstart - tokentab[mid].operator[0]; - i = c ? c : strcmp(tokstart, tokentab[mid].operator); - - if (i < 0) /* token < mid */ - high = mid - 1; - else if (i > 0) /* token > mid */ - low = mid + 1; - else { - if (do_lint) { - if (tokentab[mid].flags & GAWKX) - warning("%s() is a gawk extension", - tokentab[mid].operator); - if (tokentab[mid].flags & RESX) - warning("%s() is a Bell Labs extension", - tokentab[mid].operator); - if (tokentab[mid].flags & NOT_POSIX) - warning("POSIX does not allow %s", - tokentab[mid].operator); - } - if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) - warning("%s is not supported in old awk", - tokentab[mid].operator); - if ((do_traditional && (tokentab[mid].flags & GAWKX)) - || (do_posix && (tokentab[mid].flags & NOT_POSIX))) - break; - if (tokentab[mid].class == LEX_BUILTIN - || tokentab[mid].class == LEX_LENGTH - ) - yylval.lval = mid; - else - yylval.nodetypeval = tokentab[mid].value; - - free(tokkey); - return lasttok = tokentab[mid].class; - } - } - - yylval.sval = tokkey; - if (*lexptr == '(') - return lasttok = FUNC_CALL; - else { - want_assign = TRUE; - return lasttok = NAME; - } -} - -/* node_common --- common code for allocating a new node */ - -static NODE * -node_common(op) -NODETYPE op; -{ - register NODE *r; - - getnode(r); - r->type = op; - r->flags = MALLOC; - /* if lookahead is NL, lineno is 1 too high */ - if (lexeme && *lexeme == '\n') - r->source_line = sourceline - 1; - else - r->source_line = sourceline; - r->source_file = source; - return r; -} - -/* node --- allocates a node with defined lnode and rnode. */ - -NODE * -node(left, op, right) -NODE *left, *right; -NODETYPE op; -{ - register NODE *r; - - r = node_common(op); - r->lnode = left; - r->rnode = right; - return r; -} - -/* snode --- allocate a node with defined subnode and proc for builtin - functions. Checks for arg. count and supplies defaults where - possible. */ - -static NODE * -snode(subn, op, idx) -NODETYPE op; -int idx; -NODE *subn; -{ - register NODE *r; - register NODE *n; - int nexp = 0; - int args_allowed; - - r = node_common(op); - - /* traverse expression list to see how many args. given */ - for (n = subn; n != NULL; n = n->rnode) { - nexp++; - if (nexp > 3) - break; - } - - /* check against how many args. are allowed for this builtin */ - args_allowed = tokentab[idx].flags & ARGS; - if (args_allowed && (args_allowed & A(nexp)) == 0) - fatal("%s() cannot have %d argument%c", - tokentab[idx].operator, nexp, nexp == 1 ? ' ' : 's'); - - r->proc = tokentab[idx].ptr; - - /* special case processing for a few builtins */ - /* - * FIXME: go through these to make sure that everything done - * here is really right. Move anything that's not into - * the corresponding routine. - */ - if (nexp == 0 && r->proc == do_length) { - subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), - Node_expression_list, - (NODE *) NULL); - } else if (r->proc == do_match) { - if (subn->rnode->lnode->type != Node_regex) - subn->rnode->lnode = mk_rexp(subn->rnode->lnode); - } else if (r->proc == do_sub || r->proc == do_gsub) { - if (subn->lnode->type != Node_regex) - subn->lnode = mk_rexp(subn->lnode); - if (nexp == 2) - append_right(subn, node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL)); - else if (subn->rnode->rnode->lnode->type == Node_val) { - if (do_lint) - warning("string literal as last arg of substitute"); - } else if (! isassignable(subn->rnode->rnode->lnode)) - yyerror("%s third parameter is not a changeable object", - r->proc == do_sub ? "sub" : "gsub"); - } else if (r->proc == do_gensub) { - if (subn->lnode->type != Node_regex) - subn->lnode = mk_rexp(subn->lnode); - if (nexp == 3) - append_right(subn, node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL)); - } else if (r->proc == do_split) { - if (nexp == 2) - append_right(subn, - node(FS_node, Node_expression_list, (NODE *) NULL)); - n = subn->rnode->rnode->lnode; - if (n->type != Node_regex) - subn->rnode->rnode->lnode = mk_rexp(n); - if (nexp == 2) - subn->rnode->rnode->lnode->re_flags |= FS_DFLT; - } - - r->subnode = subn; - return r; -} - -/* - * mkrangenode: - * This allocates a Node_line_range node with defined condpair and - * zeroes the trigger word to avoid the temptation of assuming that calling - * 'node( foo, Node_line_range, 0)' will properly initialize 'triggered'. - * Otherwise like node(). - */ - -static NODE * -mkrangenode(cpair) -NODE *cpair; -{ - register NODE *r; - - getnode(r); - r->type = Node_line_range; - r->condpair = cpair; - r->triggered = FALSE; - return r; -} - -/* make_for_loop --- build a for loop */ - -static NODE * -make_for_loop(init, cond, incr) -NODE *init, *cond, *incr; -{ - register FOR_LOOP_HEADER *r; - NODE *n; - - emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop"); - getnode(n); - n->type = Node_illegal; - r->init = init; - r->cond = cond; - r->incr = incr; - n->sub.nodep.r.hd = r; - return n; -} - -/* dup_parms --- return TRUE if there are duplicate parameters */ - -static int -dup_parms(func) -NODE *func; -{ - register NODE *np; - char *fname, **names; - int count, i, j, dups; - NODE *params; - - if (func == NULL) /* error earlier */ - return TRUE; - - fname = func->param; - count = func->param_cnt; - params = func->rnode; - - if (count == 0) /* no args, no problem */ - return FALSE; - - if (params == NULL) /* error earlier */ - return TRUE; - - emalloc(names, char **, count * sizeof(char *), "dup_parms"); - - i = 0; - for (np = params; np != NULL; np = np->rnode) { - if (np->param == NULL) { /* error earlier, give up, go home */ - free(names); - return TRUE; - } - names[i++] = np->param; - } - - dups = 0; - for (i = 1; i < count; i++) { - for (j = 0; j < i; j++) { - if (strcmp(names[i], names[j]) == 0) { - dups++; - error( - "function `%s': parameter #%d, `%s', duplicates parameter #%d", - fname, i+1, names[j], j+1); - } - } - } - - free(names); - return (dups > 0 ? TRUE : FALSE); -} - -/* - * install: - * Install a name in the symbol table, even if it is already there. - * Caller must check against redefinition if that is desired. - */ - -NODE * -install(name, value) -char *name; -NODE *value; -{ - register NODE *hp; - register size_t len; - register int bucket; - - len = strlen(name); - bucket = hash(name, len, (unsigned long) HASHSIZE); - getnode(hp); - hp->type = Node_hashnode; - hp->hnext = variables[bucket]; - variables[bucket] = hp; - hp->hlength = len; - hp->hvalue = value; - hp->hname = name; - hp->hvalue->vname = name; - return hp->hvalue; -} - -/* lookup --- find the most recent hash node for name installed by install */ - -NODE * -lookup(name) -const char *name; -{ - register NODE *bucket; - register size_t len; - - len = strlen(name); - for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)]; - bucket != NULL; bucket = bucket->hnext) - if (bucket->hlength == len && STREQN(bucket->hname, name, len)) - return bucket->hvalue; - - return NULL; -} - -/* - * append_right: - * Add new to the rightmost branch of LIST. This uses n^2 time, so we make - * a simple attempt at optimizing it. - */ - -static NODE * -append_right(list, new) -NODE *list, *new; -{ - register NODE *oldlist; - static NODE *savefront = NULL, *savetail = NULL; - - if (list == NULL || new == NULL) - return list; - - oldlist = list; - if (savefront == oldlist) { - savetail = savetail->rnode = new; - return oldlist; - } else - savefront = oldlist; - while (list->rnode != NULL) - list = list->rnode; - savetail = list->rnode = new; - return oldlist; -} - -/* - * func_install: - * check if name is already installed; if so, it had better have Null value, - * in which case def is added as the value. Otherwise, install name with def - * as value. - */ - -static void -func_install(params, def) -NODE *params; -NODE *def; -{ - NODE *r; - NODE *n; - - /* check for function foo(foo) { ... }. bleh. */ - for (n = params->rnode; n != NULL; n = n->rnode) { - if (strcmp(n->param, params->param) == 0) - fatal("function `%s': can't use function name as parameter name", - params->param); - } - - pop_params(params->rnode); - pop_var(params, FALSE); - r = lookup(params->param); - if (r != NULL) { - fatal("function name `%s' previously defined", params->param); - } else - (void) install(params->param, node(params, Node_func, def)); - - func_use(params->param, FUNC_DEFINE); -} - -/* pop_var --- remove a variable from the symbol table */ - -static void -pop_var(np, freeit) -NODE *np; -int freeit; -{ - register NODE *bucket, **save; - register size_t len; - char *name; - - name = np->param; - len = strlen(name); - save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]); - for (bucket = *save; bucket != NULL; bucket = bucket->hnext) { - if (len == bucket->hlength && STREQN(bucket->hname, name, len)) { - *save = bucket->hnext; - freenode(bucket); - if (freeit) - free(np->param); - return; - } - save = &(bucket->hnext); - } -} - -/* pop_params --- remove list of function parameters from symbol table */ - -/* - * pop parameters out of the symbol table. do this in reverse order to - * avoid reading freed memory if there were duplicated parameters. - */ -static void -pop_params(params) -NODE *params; -{ - if (params == NULL) - return; - pop_params(params->rnode); - pop_var(params, TRUE); -} - -/* make_param --- make NAME into a function parameter */ - -static NODE * -make_param(name) -char *name; -{ - NODE *r; - - getnode(r); - r->type = Node_param_list; - r->rnode = NULL; - r->param = name; - r->param_cnt = param_counter++; - return (install(name, r)); -} - -static struct fdesc { - char *name; - short used; - short defined; - struct fdesc *next; -} *ftable[HASHSIZE]; - -/* func_use --- track uses and definitions of functions */ - -static void -func_use(name, how) -char *name; -enum defref how; -{ - struct fdesc *fp; - int len; - int ind; - - len = strlen(name); - ind = hash(name, len, HASHSIZE); - - for (fp = ftable[ind]; fp != NULL; fp = fp->next) { - if (strcmp(fp->name, name) == 0) { - if (how == FUNC_DEFINE) - fp->defined++; - else - fp->used++; - return; - } - } - - /* not in the table, fall through to allocate a new one */ - - emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use"); - memset(fp, '\0', sizeof(struct fdesc)); - emalloc(fp->name, char *, len + 1, "func_use"); - strcpy(fp->name, name); - if (how == FUNC_DEFINE) - fp->defined++; - else - fp->used++; - fp->next = ftable[ind]; - ftable[ind] = fp; -} - -/* check_funcs --- verify functions that are called but not defined */ - -static void -check_funcs() -{ - struct fdesc *fp, *next; - int i; - - for (i = 0; i < HASHSIZE; i++) { - for (fp = ftable[i]; fp != NULL; fp = fp->next) { -#ifdef REALLYMEAN - /* making this the default breaks old code. sigh. */ - if (fp->defined == 0) { - error( - "function `%s' called but never defined", fp->name); - errcount++; - } -#else - if (do_lint && fp->defined == 0) - warning( - "function `%s' called but never defined", fp->name); -#endif - if (do_lint && fp->used == 0) { - warning("function `%s' defined but never called", - fp->name); - } - } - } - - /* now let's free all the memory */ - for (i = 0; i < HASHSIZE; i++) { - for (fp = ftable[i]; fp != NULL; fp = next) { - next = fp->next; - free(fp->name); - free(fp); - } - } -} - -/* param_sanity --- look for parameters that are regexp constants */ - -static void -param_sanity(arglist) -NODE *arglist; -{ - NODE *argp, *arg; - int i; - - for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) { - arg = argp->lnode; - if (arg->type == Node_regex) - warning("regexp constant for parameter #%d yields boolean value", i); - } -} - -/* variable --- make sure NAME is in the symbol table */ - -NODE * -variable(name, can_free, type) -char *name; -int can_free; -NODETYPE type; -{ - register NODE *r; - static int env_loaded = FALSE; - - if (! env_loaded && STREQ(name, "ENVIRON")) { - load_environ(); - env_loaded = TRUE; - } - if ((r = lookup(name)) == NULL) - r = install(name, node(Nnull_string, type, (NODE *) NULL)); - else if (can_free) - free(name); - return r; -} - -/* mk_rexp --- make a regular expression constant */ - -static NODE * -mk_rexp(exp) -NODE *exp; -{ - NODE *n; - - if (exp->type == Node_regex) - return exp; - - getnode(n); - n->type = Node_regex; - n->re_exp = exp; - n->re_text = NULL; - n->re_reg = NULL; - n->re_flags = 0; - n->re_cnt = 1; - return n; -} - -/* isnoeffect --- when used as a statement, has no side effects */ - -/* - * To be completely general, we should recursively walk the parse - * tree, to make sure that all the subexpressions also have no effect. - * Instead, we just weaken the actual warning that's printed, up above - * in the grammar. - */ - -static int -isnoeffect(type) -NODETYPE type; -{ - switch (type) { - case Node_times: - case Node_quotient: - case Node_mod: - case Node_plus: - case Node_minus: - case Node_subscript: - case Node_concat: - case Node_exp: - case Node_unary_minus: - case Node_field_spec: - case Node_and: - case Node_or: - case Node_equal: - case Node_notequal: - case Node_less: - case Node_greater: - case Node_leq: - case Node_geq: - case Node_match: - case Node_nomatch: - case Node_not: - case Node_val: - case Node_in_array: - case Node_NF: - case Node_NR: - case Node_FNR: - case Node_FS: - case Node_RS: - case Node_FIELDWIDTHS: - case Node_IGNORECASE: - case Node_OFS: - case Node_ORS: - case Node_OFMT: - case Node_CONVFMT: - return TRUE; - default: - break; /* keeps gcc -Wall happy */ - } - - return FALSE; -} - -/* isassignable --- can this node be assigned to? */ - -static int -isassignable(n) -register NODE *n; -{ - switch (n->type) { - case Node_var: - case Node_FIELDWIDTHS: - case Node_RS: - case Node_FS: - case Node_FNR: - case Node_NR: - case Node_NF: - case Node_IGNORECASE: - case Node_OFMT: - case Node_CONVFMT: - case Node_ORS: - case Node_OFS: - case Node_field_spec: - case Node_subscript: - return TRUE; - case Node_param_list: - return ((n->flags & FUNC) == 0); /* ok if not func name */ - default: - break; /* keeps gcc -Wall happy */ - } - return FALSE; -} - -/* for debugging */ -NODE * -stopme(tree) -NODE *tree; -{ - return tmp_number((AWKNUM) 0.0); -} diff --git a/contrib/awk/awklib/eg/lib/mktime.awk b/contrib/awk/awklib/eg/lib/mktime.awk deleted file mode 100644 index 57ff20e53aed..000000000000 --- a/contrib/awk/awklib/eg/lib/mktime.awk +++ /dev/null @@ -1,105 +0,0 @@ -# mktime.awk --- convert a canonical date representation -# into a timestamp -# Arnold Robbins, arnold@gnu.org, Public Domain -# May 1993 - -BEGIN \ -{ - # Initialize table of month lengths - _tm_months[0,1] = _tm_months[1,1] = 31 - _tm_months[0,2] = 28; _tm_months[1,2] = 29 - _tm_months[0,3] = _tm_months[1,3] = 31 - _tm_months[0,4] = _tm_months[1,4] = 30 - _tm_months[0,5] = _tm_months[1,5] = 31 - _tm_months[0,6] = _tm_months[1,6] = 30 - _tm_months[0,7] = _tm_months[1,7] = 31 - _tm_months[0,8] = _tm_months[1,8] = 31 - _tm_months[0,9] = _tm_months[1,9] = 30 - _tm_months[0,10] = _tm_months[1,10] = 31 - _tm_months[0,11] = _tm_months[1,11] = 30 - _tm_months[0,12] = _tm_months[1,12] = 31 -} -# decide if a year is a leap year -function _tm_isleap(year, ret) -{ - ret = (year % 4 == 0 && year % 100 != 0) || - (year % 400 == 0) - - return ret -} -# convert a date into seconds -function _tm_addup(a, total, yearsecs, daysecs, - hoursecs, i, j) -{ - hoursecs = 60 * 60 - daysecs = 24 * hoursecs - yearsecs = 365 * daysecs - - total = (a[1] - 1970) * yearsecs - - # extra day for leap years - for (i = 1970; i < a[1]; i++) - if (_tm_isleap(i)) - total += daysecs - - j = _tm_isleap(a[1]) - for (i = 1; i < a[2]; i++) - total += _tm_months[j, i] * daysecs - - total += (a[3] - 1) * daysecs - total += a[4] * hoursecs - total += a[5] * 60 - total += a[6] - - return total -} -# mktime --- convert a date into seconds, -# compensate for time zone - -function mktime(str, res1, res2, a, b, i, j, t, diff) -{ - i = split(str, a, " ") # don't rely on FS - - if (i != 6) - return -1 - - # force numeric - for (j in a) - a[j] += 0 - - # validate - if (a[1] < 1970 || - a[2] < 1 || a[2] > 12 || - a[3] < 1 || a[3] > 31 || - a[4] < 0 || a[4] > 23 || - a[5] < 0 || a[5] > 59 || - a[6] < 0 || a[6] > 60 ) - return -1 - - res1 = _tm_addup(a) - t = strftime("%Y %m %d %H %M %S", res1) - - if (_tm_debug) - printf("(%s) -> (%s)\n", str, t) > "/dev/stderr" - - split(t, b, " ") - res2 = _tm_addup(b) - - diff = res1 - res2 - - if (_tm_debug) - printf("diff = %d seconds\n", diff) > "/dev/stderr" - - res1 += diff - - return res1 -} -BEGIN { - if (_tm_test) { - printf "Enter date as yyyy mm dd hh mm ss: " - getline _tm_test_date - t = mktime(_tm_test_date) - r = strftime("%Y %m %d %H %M %S", t) - printf "Got back (%s)\n", r - } -} diff --git a/contrib/awk/awklib/eg/misc/findpat.sh b/contrib/awk/awklib/eg/misc/findpat.sh deleted file mode 100644 index 397103247a1e..000000000000 --- a/contrib/awk/awklib/eg/misc/findpat.sh +++ /dev/null @@ -1,10 +0,0 @@ -awk '{ - if ($1 == "FIND") - regex = $2 - else { - where = match($0, regex) - if (where != 0) - print "Match of", regex, "found at", \ - where, "in", $0 - } -}' diff --git a/contrib/awk/awktab.c b/contrib/awk/awktab.c deleted file mode 100644 index 23aa4fb381e9..000000000000 --- a/contrib/awk/awktab.c +++ /dev/null @@ -1,3983 +0,0 @@ - -/* A Bison parser, made from ./awk.y - by GNU Bison version 1.25 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define FUNC_CALL 258 -#define NAME 259 -#define REGEXP 260 -#define ERROR 261 -#define YNUMBER 262 -#define YSTRING 263 -#define RELOP 264 -#define APPEND_OP 265 -#define ASSIGNOP 266 -#define MATCHOP 267 -#define NEWLINE 268 -#define CONCAT_OP 269 -#define LEX_BEGIN 270 -#define LEX_END 271 -#define LEX_IF 272 -#define LEX_ELSE 273 -#define LEX_RETURN 274 -#define LEX_DELETE 275 -#define LEX_WHILE 276 -#define LEX_DO 277 -#define LEX_FOR 278 -#define LEX_BREAK 279 -#define LEX_CONTINUE 280 -#define LEX_PRINT 281 -#define LEX_PRINTF 282 -#define LEX_NEXT 283 -#define LEX_EXIT 284 -#define LEX_FUNCTION 285 -#define LEX_GETLINE 286 -#define LEX_NEXTFILE 287 -#define LEX_IN 288 -#define LEX_AND 289 -#define LEX_OR 290 -#define INCREMENT 291 -#define DECREMENT 292 -#define LEX_BUILTIN 293 -#define LEX_LENGTH 294 -#define UNARY 295 - -#line 26 "./awk.y" - -#ifdef DEBUG -#define YYDEBUG 12 -#endif - -#include "awk.h" - -#define CAN_FREE TRUE -#define DONT_FREE FALSE - -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ -static void yyerror(const char *m, ...) ; -#else -static void yyerror(); /* va_alist */ -#endif -static char *get_src_buf P((void)); -static int yylex P((void)); -static NODE *node_common P((NODETYPE op)); -static NODE *snode P((NODE *subn, NODETYPE op, int sindex)); -static NODE *mkrangenode P((NODE *cpair)); -static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr)); -static NODE *append_right P((NODE *list, NODE *new)); -static void func_install P((NODE *params, NODE *def)); -static void pop_var P((NODE *np, int freeit)); -static void pop_params P((NODE *params)); -static NODE *make_param P((char *name)); -static NODE *mk_rexp P((NODE *exp)); -static int dup_parms P((NODE *func)); -static void param_sanity P((NODE *arglist)); -static int isnoeffect P((NODETYPE t)); -static int isassignable P((NODE *n)); - -enum defref { FUNC_DEFINE, FUNC_USE }; -static void func_use P((char *name, enum defref how)); -static void check_funcs P((void)); - -static int want_assign; /* lexical scanning kludge */ -static int want_regexp; /* lexical scanning kludge */ -static int can_return; /* lexical scanning kludge */ -static int io_allowed = TRUE; /* lexical scanning kludge */ -static char *lexptr; /* pointer to next char during parsing */ -static char *lexend; -static char *lexptr_begin; /* keep track of where we were for error msgs */ -static char *lexeme; /* beginning of lexeme for debugging */ -static char *thisline = NULL; -#define YYDEBUG_LEXER_TEXT (lexeme) -static int param_counter; -static char *tokstart = NULL; -static char *tok = NULL; -static char *tokend; - -#define HASHSIZE 1021 /* this constant only used here */ -NODE *variables[HASHSIZE]; - -extern char *source; -extern int sourceline; -extern struct src *srcfiles; -extern int numfiles; -extern int errcount; -extern NODE *begin_block; -extern NODE *end_block; - -#line 89 "./awk.y" -typedef union { - long lval; - AWKNUM fval; - NODE *nodeval; - NODETYPE nodetypeval; - char *sval; - NODE *(*ptrval)(); -} YYSTYPE; -#include <stdio.h> - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 312 -#define YYFLAG -32768 -#define YYNTBASE 62 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 295 ? yytranslate[x] : 107) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 51, 2, 2, 54, 50, 2, 2, 55, - 56, 48, 46, 42, 47, 2, 49, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 41, 61, 43, - 2, 44, 40, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 57, 2, 58, 53, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 59, 45, 60, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 52 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 4, 6, 9, 11, 14, 15, 16, 20, 21, - 25, 28, 31, 34, 36, 39, 42, 44, 46, 48, - 50, 52, 53, 61, 66, 71, 73, 77, 78, 83, - 89, 94, 96, 99, 101, 104, 106, 109, 112, 115, - 119, 121, 128, 137, 146, 157, 167, 170, 173, 180, - 185, 189, 192, 196, 197, 202, 209, 213, 216, 218, - 220, 227, 237, 239, 242, 243, 245, 246, 249, 250, - 253, 256, 259, 260, 262, 264, 268, 270, 273, 277, - 278, 280, 281, 283, 285, 289, 291, 294, 298, 302, - 303, 305, 307, 311, 313, 316, 320, 324, 325, 330, - 336, 341, 345, 349, 353, 357, 359, 362, 366, 370, - 374, 378, 384, 386, 389, 390, 395, 399, 403, 407, - 409, 412, 416, 420, 424, 430, 432, 435, 437, 441, - 445, 449, 453, 457, 461, 464, 467, 470, 474, 479, - 484, 486, 491, 493, 496, 499, 501, 503, 506, 509, - 510, 512, 514, 519, 522, 525, 528, 530, 531, 533, - 535 -}; - -static const short yyrhs[] = { 83, - 63, 83, 0, 64, 0, 63, 64, 0, 1, 0, - 63, 1, 0, 0, 0, 15, 65, 75, 0, 0, - 16, 66, 75, 0, 15, 77, 0, 16, 77, 0, - 72, 75, 0, 75, 0, 72, 77, 0, 69, 71, - 0, 4, 0, 3, 0, 68, 0, 38, 0, 39, - 0, 0, 30, 70, 67, 55, 86, 103, 83, 0, - 101, 76, 102, 104, 0, 101, 102, 104, 83, 0, - 93, 0, 93, 42, 93, 0, 0, 49, 74, 5, - 49, 0, 101, 76, 102, 104, 83, 0, 101, 102, - 104, 83, 0, 78, 0, 76, 78, 0, 1, 0, - 76, 1, 0, 82, 0, 105, 83, 0, 105, 83, - 0, 101, 102, 0, 101, 76, 102, 0, 81, 0, - 21, 55, 93, 103, 83, 78, 0, 22, 83, 78, - 21, 55, 93, 103, 83, 0, 23, 55, 4, 33, - 4, 103, 83, 78, 0, 23, 55, 88, 105, 93, - 105, 88, 103, 83, 78, 0, 23, 55, 88, 105, - 105, 88, 103, 83, 78, 0, 24, 77, 0, 25, - 77, 0, 80, 55, 92, 103, 85, 77, 0, 80, - 89, 85, 77, 0, 28, 88, 77, 0, 32, 77, - 0, 29, 88, 77, 0, 0, 19, 79, 88, 77, - 0, 20, 4, 57, 92, 58, 77, 0, 20, 4, - 77, 0, 93, 77, 0, 26, 0, 27, 0, 17, - 55, 93, 103, 83, 78, 0, 17, 55, 93, 103, - 83, 78, 18, 83, 78, 0, 13, 0, 82, 13, - 0, 0, 82, 0, 0, 43, 97, 0, 0, 44, - 93, 0, 10, 93, 0, 45, 93, 0, 0, 87, - 0, 4, 0, 87, 106, 4, 0, 1, 0, 87, - 1, 0, 87, 106, 1, 0, 0, 93, 0, 0, - 90, 0, 95, 0, 90, 106, 95, 0, 1, 0, - 90, 1, 0, 90, 1, 95, 0, 90, 106, 1, - 0, 0, 92, 0, 93, 0, 92, 106, 93, 0, - 1, 0, 92, 1, 0, 92, 1, 93, 0, 92, - 106, 1, 0, 0, 100, 11, 94, 93, 0, 55, - 92, 103, 33, 4, 0, 93, 45, 31, 99, 0, - 31, 99, 84, 0, 93, 34, 93, 0, 93, 35, - 93, 0, 93, 12, 93, 0, 73, 0, 51, 73, - 0, 93, 33, 4, 0, 93, 9, 93, 0, 93, - 43, 93, 0, 93, 44, 93, 0, 93, 40, 93, - 41, 93, 0, 97, 0, 93, 97, 0, 0, 100, - 11, 96, 95, 0, 95, 34, 95, 0, 95, 35, - 95, 0, 31, 99, 84, 0, 73, 0, 51, 73, - 0, 95, 12, 95, 0, 95, 33, 4, 0, 95, - 9, 95, 0, 95, 40, 95, 41, 95, 0, 97, - 0, 95, 97, 0, 98, 0, 97, 53, 97, 0, - 97, 48, 97, 0, 97, 49, 97, 0, 97, 50, - 97, 0, 97, 46, 97, 0, 97, 47, 97, 0, - 100, 36, 0, 100, 37, 0, 51, 97, 0, 55, - 93, 103, 0, 38, 55, 91, 103, 0, 39, 55, - 91, 103, 0, 39, 0, 3, 55, 91, 103, 0, - 100, 0, 36, 100, 0, 37, 100, 0, 7, 0, - 8, 0, 47, 97, 0, 46, 97, 0, 0, 100, - 0, 4, 0, 4, 57, 92, 58, 0, 54, 98, - 0, 59, 83, 0, 60, 83, 0, 56, 0, 0, - 105, 0, 61, 0, 42, 83, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 150, 158, 166, 182, 183, 184, 188, 190, 204, 206, - 220, 226, 232, 234, 236, 249, 258, 260, 262, 272, - 273, 277, 281, 296, 301, 310, 312, 321, 323, 341, - 343, 348, 354, 362, 364, 369, 370, 374, 376, 378, - 380, 382, 384, 386, 413, 417, 422, 425, 428, 430, - 450, 489, 508, 510, 515, 517, 519, 533, 538, 540, - 545, 550, 557, 559, 563, 564, 568, 570, 575, 577, - 579, 581, 586, 588, 593, 595, 597, 599, 601, 607, - 609, 614, 616, 621, 623, 629, 631, 633, 635, 640, - 642, 647, 649, 655, 657, 659, 661, 666, 669, 674, - 676, 681, 687, 689, 691, 697, 707, 715, 717, 723, - 725, 727, 729, 731, 736, 739, 740, 742, 744, 750, - 752, 754, 756, 758, 760, 762, 764, 769, 771, 773, - 775, 777, 779, 781, 783, 785, 790, 792, 794, 797, - 799, 807, 814, 815, 817, 819, 821, 824, 832, 843, - 845, 850, 852, 862, 867, 871, 875, 879, 880, 884, - 887 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","FUNC_CALL", -"NAME","REGEXP","ERROR","YNUMBER","YSTRING","RELOP","APPEND_OP","ASSIGNOP","MATCHOP", -"NEWLINE","CONCAT_OP","LEX_BEGIN","LEX_END","LEX_IF","LEX_ELSE","LEX_RETURN", -"LEX_DELETE","LEX_WHILE","LEX_DO","LEX_FOR","LEX_BREAK","LEX_CONTINUE","LEX_PRINT", -"LEX_PRINTF","LEX_NEXT","LEX_EXIT","LEX_FUNCTION","LEX_GETLINE","LEX_NEXTFILE", -"LEX_IN","LEX_AND","LEX_OR","INCREMENT","DECREMENT","LEX_BUILTIN","LEX_LENGTH", -"'?'","':'","','","'<'","'>'","'|'","'+'","'-'","'*'","'/'","'%'","'!'","UNARY", -"'^'","'$'","'('","')'","'['","']'","'{'","'}'","';'","start","program","rule", -"@1","@2","func_name","lex_builtin","function_prologue","@3","function_body", -"pattern","regexp","@4","action","statements","statement_term","statement","@5", -"print","if_statement","nls","opt_nls","input_redir","output_redir","opt_param_list", -"param_list","opt_exp","opt_rexpression_list","rexpression_list","opt_expression_list", -"expression_list","exp","@6","rexp","@7","simp_exp","non_post_simp_exp","opt_variable", -"variable","l_brace","r_brace","r_paren","opt_semi","semi","comma", NULL -}; -#endif - -static const short yyr1[] = { 0, - 62, 63, 63, 63, 63, 63, 65, 64, 66, 64, - 64, 64, 64, 64, 64, 64, 67, 67, 67, 68, - 68, 70, 69, 71, 71, 72, 72, 74, 73, 75, - 75, 76, 76, 76, 76, 77, 77, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 79, 78, 78, 78, 78, 80, 80, - 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, - 85, 85, 86, 86, 87, 87, 87, 87, 87, 88, - 88, 89, 89, 90, 90, 90, 90, 90, 90, 91, - 91, 92, 92, 92, 92, 92, 92, 94, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 96, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, - 99, 100, 100, 100, 101, 102, 103, 104, 104, 105, - 106 -}; - -static const short yyr2[] = { 0, - 3, 1, 2, 1, 2, 0, 0, 3, 0, 3, - 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, - 1, 0, 7, 4, 4, 1, 3, 0, 4, 5, - 4, 1, 2, 1, 2, 1, 2, 2, 2, 3, - 1, 6, 8, 8, 10, 9, 2, 2, 6, 4, - 3, 2, 3, 0, 4, 6, 3, 2, 1, 1, - 6, 9, 1, 2, 0, 1, 0, 2, 0, 2, - 2, 2, 0, 1, 1, 3, 1, 2, 3, 0, - 1, 0, 1, 1, 3, 1, 2, 3, 3, 0, - 1, 1, 3, 1, 2, 3, 3, 0, 4, 5, - 4, 3, 3, 3, 3, 1, 2, 3, 3, 3, - 3, 5, 1, 2, 0, 4, 3, 3, 3, 1, - 2, 3, 3, 3, 5, 1, 2, 1, 3, 3, - 3, 3, 3, 3, 2, 2, 2, 3, 4, 4, - 1, 4, 1, 2, 2, 1, 1, 2, 2, 0, - 1, 1, 4, 2, 2, 2, 1, 0, 1, 1, - 2 -}; - -static const short yydefact[] = { 65, - 63, 66, 0, 64, 4, 0, 152, 146, 147, 7, - 9, 22, 150, 0, 0, 0, 141, 0, 0, 28, - 0, 0, 0, 65, 0, 2, 0, 0, 106, 14, - 26, 113, 128, 143, 0, 0, 0, 160, 0, 11, - 36, 65, 0, 12, 0, 67, 151, 144, 145, 0, - 0, 0, 0, 149, 143, 148, 0, 107, 137, 154, - 143, 94, 0, 92, 155, 5, 3, 1, 16, 0, - 13, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 114, 0, 0, 0, 0, 0, 0, 98, - 135, 136, 34, 0, 54, 0, 0, 65, 0, 0, - 0, 59, 60, 80, 80, 0, 65, 0, 32, 0, - 41, 0, 0, 158, 65, 0, 0, 92, 0, 8, - 37, 10, 18, 17, 20, 21, 0, 19, 0, 102, - 0, 0, 0, 0, 95, 65, 157, 0, 0, 138, - 0, 158, 109, 105, 108, 103, 104, 0, 27, 110, - 111, 150, 133, 134, 130, 131, 132, 129, 0, 0, - 80, 0, 0, 0, 80, 47, 48, 0, 81, 0, - 52, 156, 35, 33, 158, 86, 150, 0, 0, 120, - 69, 0, 84, 126, 143, 58, 0, 39, 65, 159, - 38, 142, 153, 0, 68, 139, 140, 29, 96, 161, - 0, 97, 93, 158, 65, 0, 101, 99, 0, 0, - 0, 57, 0, 0, 152, 0, 51, 53, 65, 67, - 121, 0, 0, 0, 0, 0, 87, 0, 0, 0, - 0, 0, 0, 0, 127, 115, 40, 31, 77, 75, - 0, 0, 100, 24, 25, 112, 65, 55, 0, 65, - 0, 0, 0, 30, 119, 69, 71, 70, 72, 50, - 88, 89, 85, 124, 122, 123, 117, 118, 0, 0, - 65, 78, 0, 0, 0, 0, 0, 0, 0, 80, - 0, 0, 116, 23, 79, 76, 61, 56, 42, 0, - 65, 80, 0, 49, 125, 65, 65, 0, 0, 65, - 0, 43, 44, 65, 0, 62, 0, 46, 45, 0, - 0, 0 -}; - -static const short yydefgoto[] = { 310, - 25, 26, 39, 43, 127, 128, 27, 45, 69, 28, - 29, 57, 30, 108, 40, 109, 161, 110, 111, 2, - 3, 130, 226, 241, 242, 168, 181, 182, 116, 117, - 112, 159, 183, 270, 32, 33, 46, 34, 113, 114, - 140, 189, 42, 139 -}; - -static const short yypact[] = { -6, --32768, 0, 875,-32768,-32768, -40, -38,-32768,-32768, -7, - -7,-32768, 10, 10, 10, -31, -26, 1735, 1735,-32768, - 1715, 1735, 1131, -6, 932,-32768, -24, 72,-32768,-32768, - 1304, 205,-32768, 5, 709, 1110, 1131,-32768, -24,-32768, - 0, -6, -24,-32768, 85, 3,-32768,-32768,-32768, 1110, - 1110, 1735, 1620, 8, 106, 8, 81,-32768, 8,-32768, --32768,-32768, 37, 1250,-32768,-32768,-32768,-32768,-32768, 709, --32768,-32768, 1620, 1620, 90, 1620, 1620, 1620, 1620, 1620, - 1620, 65, 205, 1735, 1735, 1735, 1735, 1735, 1735,-32768, --32768,-32768,-32768, 50,-32768, 111, 70, -6, 93, -7, - -7,-32768,-32768, 1620, 1620, -7, -6, 758,-32768, 819, --32768, 1040, 709, 100, -6, 99, 55, 1402, 9,-32768, --32768,-32768,-32768,-32768,-32768,-32768, 109,-32768, 1735,-32768, - 99, 99, 1250, 119, 1620, -6,-32768, 133, 1180,-32768, - 758, 100, 1327, 794,-32768, 1515, 1451, 1353, 1402, 1327, - 1327, 10, 125, 125, 8, 8, 8, 8, 1620, 1620, - 1620, 42, 1620, 981, 1657,-32768,-32768, -7, 1402, -7, --32768,-32768,-32768,-32768, 100,-32768, 10, 1715, 1131,-32768, - 96, 39, 1538, 205, 117,-32768, 758,-32768, -6,-32768, --32768,-32768,-32768, 7, 205,-32768,-32768,-32768, 1402,-32768, - 166,-32768, 1402, 100, -6, 1620,-32768, 1402, 1250, -7, - 1131,-32768, 1250, 151, -12, 100,-32768,-32768, -6, 3, --32768, 37, 1620, 1620, 1620, -7, 1678, 1201, 1678, 1678, - 181, 1678, 1678, 1678, 205,-32768,-32768,-32768,-32768,-32768, - 99, 56,-32768,-32768,-32768, 1402, -6,-32768, 11, -6, - 131, 183, 1061,-32768,-32768, 96, 1402, 1402, 1402,-32768, - 1538,-32768, 1538, 635, 83,-32768, 1599, 1579, 1474, 1678, - -6,-32768, 103, 981, -7, 981, 1620, 99, 623, 1620, - -7, 1678, 1538,-32768,-32768,-32768, 170,-32768,-32768, 1250, - -6, 1620, 99,-32768, 1538, -6, -6, 981, 99, -6, - 981,-32768,-32768, -6, 981,-32768, 981,-32768,-32768, 190, - 191,-32768 -}; - -static const short yypgoto[] = {-32768, --32768, 167,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 211,-32768, 107, -53, 315, -105,-32768,-32768,-32768, 199, - 97, -22, -62,-32768,-32768, -103,-32768,-32768, 94, -14, - -3,-32768, -202,-32768, 318, 177, -134, 95, 124, -69, - 407, -138, 420, -177 -}; - - -#define YYLAST 1790 - - -static const short yytable[] = { 31, - 142, 170, 174, 205, 228, 1, 1, 239, 63, 135, - 240, 135, 4, 7, 36, 90, 141, 207, 37, 64, - 252, 31, 119, 50, 261, 263, 264, 265, 51, 267, - 268, 269, 118, 118, 24, 174, 219, 135, 175, 227, - 91, 92, 220, 188, 37, 129, 118, 118, -83, 133, - 136, -83, 136, 38, 1, 135, 272, 210, 214, 187, - 89, 216, -73, 22, 273, 244, 193, 283, 275, 143, - 144, 204, 146, 147, 148, 149, 150, 151, 136, 295, - 136, 174, -83, -83, 1, 134, 7, 123, 124, 8, - 9, 229, 137, 145,-32768, 152, 136, 136, 211, -83, - 169, 169, 38, 285, 160, 223, 286, 47, 48, 49, - -91, -74, 55, 55, 162, 55, 61, 237, 14, 15, - 65, 68, 125, 126, 163, 55, 35, 236, 18, 19, - 24, 199, 38, 52, 71, 203, 22, 53, 121, 224, - 225, 91, 92, 131, 132, 120, 55, 165, 35, 122, - 70, 35, 91, 92, 137, 208, 209, 169, 55, 213, - 38, 169, 35, 194, 222, 201, 35, 198, 287, 243, - 289, 251, 86, 87, 88, 64, 293, 89, 55, 55, - 55, 55, 55, 55, 266, 277, 278, 296, 299, 311, - 312, 67, 303, 281, 164, 306, 249, 255, 60, 308, - 0, 309, 246, 172, 185, 0, 55, 118, 41, 41, - 0, 191, 55, 0, 0, 0, 0, 0, 0, 257, - 258, 259, 0, 55, 0, 0, 41, 55, 0, 0, - 0, 58, 200, 0, 0, 0, 0, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 47, 0, 0, 279, - 84, 85, 86, 87, 88, 0, 0, 89, 0, 0, - 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, - 0, 47, 55, 290, 0, 0, 169, 55, 0, 0, - 0, 0, 0, 0, 0, 238, 0, 0, 169, 0, - 0, 0, 0, 55, 0, 0, 0, 55, 41, 41, - 0, 245, 55, 55, 41, 0, 0, 55, 0, 0, - 41, 0, 0, 0, 0, 254, 0, 0, 0, 0, - 180, 185, 185, 185, 185, 44, 185, 185, 185, 0, - 0, 0, 0, 0, 0, 54, 56, 0, 59, 0, - 55, 0, 72, 274, 0, 0, 276, 0, 83, 0, - 0, 55, 55, 55, 0, 55, 0, 55, 55, 55, - 41, 55, 55, 55, 185, 0, 41, 284, 41, 59, - 0, 0, 0, 55, 0, 0, 185, 55, 0, 0, - 0, 83, 0, 0, 55, 0, 0, 298, 221, 55, - 0, 0, 301, 302, 0, 0, 305, 0, 0, 0, - 307, 153, 154, 155, 156, 157, 158, 0, 41, 0, - 0, 0, 0, 0, 166, 167, 0, 0, 0, 0, - 171, 0, 0, 0, 41, 0, 186, 184, 0, 83, - 0, 0, 0, 0, 0, 83, 0, 180, 180, 180, - 180, 0, 180, 180, 180, 0, 195, 0, 0, 0, - 83, 0, 0, 0, 115, 0, 0, 0, 0, 0, - 83, 83, 0, 83, 83, 83, 83, 83, 83, 138, - 0, 0, 0, 41, 0, 0, 212, 0, 0, 41, - 180, 0, 217, 0, 218, 0, 83, 0, 0, 115, - 0, 0, 180, 0, 0, 59, 0, 0, 0, 0, - 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, - 83, 0, 192, 0, 248, 83, 83, 115, 0, 0, - 83, 0, 115, 190, 0, 0, 0, 196, 197, 0, - 260, 0, 0, 0, 184, 184, 184, 184, 0, 184, - 184, 184, 0, 0, 0, 0, 0, 0, 0, 0, - 115, 190, 0, 83, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 83, 83, 83, 0, 235, 0, - 235, 235, 235, 115, 235, 235, 235, 184, 0, 288, - 0, 0, 0, 0, 190, 294, 83, 0, 0, 184, - 235, 0, 0, 0, 0, 0, 115, 83, 0, 0, - 0, 0, 235, 0, 0, 247, 0, 0, 0, 250, - 0, 0, 0, 190, 0, 6, 7, 0, 256, 8, - 9, 73, 0, 0, 74, 253, 0, 0, 7, 0, - 0, 8, 9,-32768, 0, 0, 0, 271, 0, 0, - 0, 0, 0, 0, 0, 75, 76, 77, 14, 15, - 16, 17, 78, 0, 0, 80, 81, 82, 18, 19, - 14, 15, 280, 52, 0, 0, 22, 53, 0, 0, - 18, 19, 0, 38, 291, 52, 0, 0, 22, 53, - 0, 0, 0, 115, 0, 115, 297, 0, 292, 300, - 0, 0, 0, 0, 0, 304, 0, 0, 0, 93, - 0, 6, 7, 0, 0, 8, 9, 115, 0, 0, - 115, 0, 0, 0, 115, 94, 115, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 0, 13, - 106, 0, 0, 0, 14, 15, 16, 17, 0, 0, - 0, 0, 0, 0, 18, 19, 0, 20, 173, 21, - 6, 7, 22, 23, 8, 9, 0, 24, 107, 38, - 0, 0, 0, 0, 94, 0, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 0, 13, 106, - 0, 0, 0, 14, 15, 16, 17, 7, 0, 0, - 8, 9, 73, 18, 19,-32768, 20, 0, 21, 0, - 0, 22, 23, 0, 0, 0, 24, 107, 38, 176, - 0, 6, 7, 0, 0, 8, 9, 0, -82, 14, - 15, -82, 0, 0, 0, 0, 80, 81, 82, 18, - 19, 0, 0, 0, 52, 0, 0, 22, 53, 177, - 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, - 0, 0, -82, -82, 18, 19, 0, 20, 0, 178, - 0, 0, 22, 179, -6, 5, 0, 6, 7, -82, - 0, 8, 9, 0, 0, 0, 0, -6, 0, 10, - 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, - 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, - 18, 19, 0, 20, 0, 21, 0, 0, 22, 23, - 0, -65, 66, 24, 6, 7, 0, 0, 8, 9, - 0, 0, 0, 0, 1, 0, 10, 11, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 13, 0, 0, 0, 0, 14, 15, 16, - 17, 0, 0, 0, 0, 0, 0, 18, 19, 0, - 20, 0, 21, 6, 7, 22, 23, 8, 9, 0, - 24, 0, 0, 0, 0, 0, 0, 94, 0, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 0, 13, 106, 0, 0, 0, 14, 15, 16, 17, - 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, - 0, 21, 0, 0, 22, 23, 0, 0, 0, 24, - 0, 38, 6, 7, 0, 0, 8, 9, 73, 0, - 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 7, 0, 0, 8, 9, 0, - 0, 0, 75, 76, 77, 14, 15, 16, 17, 78, - 0, 0, 80, 81, 82, 18, 19, 0, 0, 0, - 52, 13, 0, 22, 53, 0, 14, 15, 16, 17, - 38, 0, 0, 0, 0, 0, 18, 19, 0, 20, - 62, 21, 6, 7, 22, 23, 8, 9, 0, 0, - 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 0, 6, 7, 0, 0, 8, 9, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, - 0, 0, 0, 0, 0, 18, 19, 0, 20, 0, - 21, 13, 0, 22, 23, -90, 14, 15, 16, 17, - 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, - 202, 21, 6, 7, 22, 23, 8, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 262, 0, 6, 7, 0, 0, 8, 9, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, - 0, 0, 0, 0, 0, 18, 19, 0, 20, 0, - 21, 177, 0, 22, 23, 0, 14, 15, 16, 17, - 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, - 0, 178, 6, 7, 22, 53, 8, 9, 73, 0, - 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 76, 77, 14, 15, 16, 17, 78, - 0, 0, 80, 81, 82, 18, 19, 0, 0, 0, - 52, 0, 0, 22, 53, 137, 6, 7, 0, 0, - 8, 9, 73, 0, 0, 74, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 8, 9,-32768, 75, 76, 77, 14, - 15, 16, 17, 78, 0, 79, 80, 81, 82, 18, - 19, 0, 0, 0, 52, 6, 7, 22, 53, 8, - 9, 73, 14, 15, 74, 0, 0, 0, 0,-32768, --32768,-32768, 18, 19, 0, 0, 0, 52, 0, 0, - 22, 53, 0, 0, 0, 75, 76, 77, 14, 15, - 16, 17, 78, 206, 0, 80, 81, 82, 18, 19, - 0, 0, 0, 52, 6, 7, 22, 53, 8, 9, - 73, 0, 0, 74, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 75, 76, 77, 14, 15, 16, - 17, 78, 0, 0, 80, 81, 82, 18, 19, 0, - 0, 0, 52, 6, 7, 22, 53, 8, 9, 73, - 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, - 8, 9, 229, 75, 76, 230, 14, 15, 16, 17, - 0, 0, 0, 80, 81, 82, 18, 19, 0, 0, - 0, 52, 0, 0, 22, 53, 231, 232, 233, 14, - 15, 16, 17, 234, 282, 0, 0, 6, 7, 18, - 19, 8, 9, 73, 52, 0, 74, 22, 53, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 7, 0, 0, 8, 9, 229, 75, 0, 230, - 14, 15, 16, 17, 0, 0, 0, 80, 81, 82, - 18, 19, 0, 0, 0, 52, 0, 0, 22, 53, - 231, 232, 233, 14, 15, 16, 17, 234, 0, 0, - 0, 6, 7, 18, 19, 8, 9, 229, 52, 0, - 230, 22, 53, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 7, 0, 0, 8, 9, 229, 0, 0, - 230, 231, 232, 0, 14, 15, 16, 17, 0, 0, - 0, 0, 6, 7, 18, 19, 8, 9, 0, 52, - 0, 231, 22, 53, 14, 15, 16, 17, 0, 0, - 0, 0, 0, 0, 18, 19, 0, 0, 0, 52, - 13, 0, 22, 53, 0, 14, 15, 16, 17, 6, - 215, 0, 0, 8, 9, 18, 19, 0, 20, 0, - 21, 0, 0, 22, 23, 0, 0, 0, 0, 0, - 6, 7, 0, 0, 8, 9, 0, 13, 0, 0, - 0, 0, 14, 15, 16, 17, 0, 0, 0, 0, - 0, 0, 18, 19, 0, 20, 0, 21, 177, 0, - 22, 23, 0, 14, 15, 16, 17, 6, 7, 0, - 0, 8, 9, 18, 19, 0, 20, 0, 178, 0, - 0, 22, 53, 0, 0, 0, 0, 6, 7, 0, - 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, - 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, - 18, 19, 0, 20, 0, 52, 0, 0, 22, 53, - 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, - 18, 19, 0, 0, 0, 52, 0, 0, 22, 53 -}; - -static const short yycheck[] = { 3, - 70, 105, 108, 142, 182, 13, 13, 1, 23, 1, - 4, 1, 13, 4, 55, 11, 70, 152, 57, 23, - 33, 25, 37, 55, 227, 228, 229, 230, 55, 232, - 233, 234, 36, 37, 59, 141, 175, 1, 108, 1, - 36, 37, 177, 113, 57, 43, 50, 51, 10, 53, - 42, 13, 42, 61, 13, 1, 1, 161, 164, 113, - 53, 165, 56, 54, 242, 204, 58, 270, 58, 73, - 74, 141, 76, 77, 78, 79, 80, 81, 42, 282, - 42, 187, 44, 45, 13, 5, 4, 3, 4, 7, - 8, 9, 56, 4, 12, 31, 42, 42, 57, 61, - 104, 105, 61, 1, 55, 10, 4, 13, 14, 15, - 56, 56, 18, 19, 4, 21, 22, 187, 36, 37, - 24, 25, 38, 39, 55, 31, 3, 11, 46, 47, - 59, 135, 61, 51, 28, 139, 54, 55, 42, 44, - 45, 36, 37, 50, 51, 39, 52, 55, 25, 43, - 27, 28, 36, 37, 56, 159, 160, 161, 64, 163, - 61, 165, 39, 55, 179, 33, 43, 49, 274, 4, - 276, 21, 48, 49, 50, 179, 280, 53, 84, 85, - 86, 87, 88, 89, 4, 55, 4, 18, 292, 0, - 0, 25, 298, 256, 98, 301, 211, 220, 22, 305, - -1, 307, 206, 107, 110, -1, 112, 211, 10, 11, - -1, 115, 118, -1, -1, -1, -1, -1, -1, 223, - 224, 225, -1, 129, -1, -1, 28, 133, -1, -1, - -1, 21, 136, -1, -1, -1, -1, 143, 144, -1, - 146, 147, 148, 149, 150, 151, 152, -1, -1, 253, - 46, 47, 48, 49, 50, -1, -1, 53, -1, -1, - -1, -1, -1, 169, -1, -1, -1, -1, -1, -1, - -1, 177, 178, 277, -1, -1, 280, 183, -1, -1, - -1, -1, -1, -1, -1, 189, -1, -1, 292, -1, - -1, -1, -1, 199, -1, -1, -1, 203, 100, 101, - -1, 205, 208, 209, 106, -1, -1, 213, -1, -1, - 112, -1, -1, -1, -1, 219, -1, -1, -1, -1, - 110, 227, 228, 229, 230, 11, 232, 233, 234, -1, - -1, -1, -1, -1, -1, 18, 19, -1, 21, -1, - 246, -1, 28, 247, -1, -1, 250, -1, 31, -1, - -1, 257, 258, 259, -1, 261, -1, 263, 264, 265, - 162, 267, 268, 269, 270, -1, 168, 271, 170, 52, - -1, -1, -1, 279, -1, -1, 282, 283, -1, -1, - -1, 64, -1, -1, 290, -1, -1, 291, 178, 295, - -1, -1, 296, 297, -1, -1, 300, -1, -1, -1, - 304, 84, 85, 86, 87, 88, 89, -1, 210, -1, - -1, -1, -1, -1, 100, 101, -1, -1, -1, -1, - 106, -1, -1, -1, 226, -1, 112, 110, -1, 112, - -1, -1, -1, -1, -1, 118, -1, 227, 228, 229, - 230, -1, 232, 233, 234, -1, 129, -1, -1, -1, - 133, -1, -1, -1, 35, -1, -1, -1, -1, -1, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 63, - -1, -1, -1, 275, -1, -1, 162, -1, -1, 281, - 270, -1, 168, -1, 170, -1, 169, -1, -1, 70, - -1, -1, 282, -1, -1, 178, -1, -1, -1, -1, - 183, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 199, -1, -1, -1, - 203, -1, 116, -1, 210, 208, 209, 108, -1, -1, - 213, -1, 113, 114, -1, -1, -1, 131, 132, -1, - 226, -1, -1, -1, 227, 228, 229, 230, -1, 232, - 233, 234, -1, -1, -1, -1, -1, -1, -1, -1, - 141, 142, -1, 246, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 257, 258, 259, -1, 261, -1, - 263, 264, 265, 164, 267, 268, 269, 270, -1, 275, - -1, -1, -1, -1, 175, 281, 279, -1, -1, 282, - 283, -1, -1, -1, -1, -1, 187, 290, -1, -1, - -1, -1, 295, -1, -1, 209, -1, -1, -1, 213, - -1, -1, -1, 204, -1, 3, 4, -1, 222, 7, - 8, 9, -1, -1, 12, 216, -1, -1, 4, -1, - -1, 7, 8, 9, -1, -1, -1, 241, -1, -1, - -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, - 38, 39, 40, -1, -1, 43, 44, 45, 46, 47, - 36, 37, 253, 51, -1, -1, 54, 55, -1, -1, - 46, 47, -1, 61, 278, 51, -1, -1, 54, 55, - -1, -1, -1, 274, -1, 276, 290, -1, 279, 293, - -1, -1, -1, -1, -1, 299, -1, -1, -1, 1, - -1, 3, 4, -1, -1, 7, 8, 298, -1, -1, - 301, -1, -1, -1, 305, 17, 307, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, -1, 31, - 32, -1, -1, -1, 36, 37, 38, 39, -1, -1, - -1, -1, -1, -1, 46, 47, -1, 49, 1, 51, - 3, 4, 54, 55, 7, 8, -1, 59, 60, 61, - -1, -1, -1, -1, 17, -1, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, -1, 31, 32, - -1, -1, -1, 36, 37, 38, 39, 4, -1, -1, - 7, 8, 9, 46, 47, 12, 49, -1, 51, -1, - -1, 54, 55, -1, -1, -1, 59, 60, 61, 1, - -1, 3, 4, -1, -1, 7, 8, -1, 10, 36, - 37, 13, -1, -1, -1, -1, 43, 44, 45, 46, - 47, -1, -1, -1, 51, -1, -1, 54, 55, 31, - -1, -1, -1, -1, 36, 37, 38, 39, -1, -1, - -1, -1, 44, 45, 46, 47, -1, 49, -1, 51, - -1, -1, 54, 55, 0, 1, -1, 3, 4, 61, - -1, 7, 8, -1, -1, -1, -1, 13, -1, 15, - 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 30, 31, -1, -1, -1, -1, - 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, - 46, 47, -1, 49, -1, 51, -1, -1, 54, 55, - -1, 0, 1, 59, 3, 4, -1, -1, 7, 8, - -1, -1, -1, -1, 13, -1, 15, 16, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 30, 31, -1, -1, -1, -1, 36, 37, 38, - 39, -1, -1, -1, -1, -1, -1, 46, 47, -1, - 49, -1, 51, 3, 4, 54, 55, 7, 8, -1, - 59, -1, -1, -1, -1, -1, -1, 17, -1, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - -1, 31, 32, -1, -1, -1, 36, 37, 38, 39, - -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, - -1, 51, -1, -1, 54, 55, -1, -1, -1, 59, - -1, 61, 3, 4, -1, -1, 7, 8, 9, -1, - -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3, 4, -1, -1, 7, 8, -1, - -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, - -1, -1, 43, 44, 45, 46, 47, -1, -1, -1, - 51, 31, -1, 54, 55, -1, 36, 37, 38, 39, - 61, -1, -1, -1, -1, -1, 46, 47, -1, 49, - 1, 51, 3, 4, 54, 55, 7, 8, -1, -1, - -1, 61, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1, -1, 3, 4, -1, -1, 7, 8, -1, - 31, -1, -1, -1, -1, 36, 37, 38, 39, -1, - -1, -1, -1, -1, -1, 46, 47, -1, 49, -1, - 51, 31, -1, 54, 55, 56, 36, 37, 38, 39, - -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, - 1, 51, 3, 4, 54, 55, 7, 8, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1, -1, 3, 4, -1, -1, 7, 8, -1, - 31, -1, -1, -1, -1, 36, 37, 38, 39, -1, - -1, -1, -1, -1, -1, 46, 47, -1, 49, -1, - 51, 31, -1, 54, 55, -1, 36, 37, 38, 39, - -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, - -1, 51, 3, 4, 54, 55, 7, 8, 9, -1, - -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, - -1, -1, 43, 44, 45, 46, 47, -1, -1, -1, - 51, -1, -1, 54, 55, 56, 3, 4, -1, -1, - 7, 8, 9, -1, -1, 12, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4, -1, -1, 7, 8, 9, 33, 34, 35, 36, - 37, 38, 39, 40, -1, 42, 43, 44, 45, 46, - 47, -1, -1, -1, 51, 3, 4, 54, 55, 7, - 8, 9, 36, 37, 12, -1, -1, -1, -1, 43, - 44, 45, 46, 47, -1, -1, -1, 51, -1, -1, - 54, 55, -1, -1, -1, 33, 34, 35, 36, 37, - 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, - -1, -1, -1, 51, 3, 4, 54, 55, 7, 8, - 9, -1, -1, 12, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, - 39, 40, -1, -1, 43, 44, 45, 46, 47, -1, - -1, -1, 51, 3, 4, 54, 55, 7, 8, 9, - -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3, 4, -1, -1, - 7, 8, 9, 33, 34, 12, 36, 37, 38, 39, - -1, -1, -1, 43, 44, 45, 46, 47, -1, -1, - -1, 51, -1, -1, 54, 55, 33, 34, 35, 36, - 37, 38, 39, 40, 41, -1, -1, 3, 4, 46, - 47, 7, 8, 9, 51, -1, 12, 54, 55, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3, 4, -1, -1, 7, 8, 9, 33, -1, 12, - 36, 37, 38, 39, -1, -1, -1, 43, 44, 45, - 46, 47, -1, -1, -1, 51, -1, -1, 54, 55, - 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, - -1, 3, 4, 46, 47, 7, 8, 9, 51, -1, - 12, 54, 55, -1, -1, -1, -1, -1, -1, -1, - -1, 3, 4, -1, -1, 7, 8, 9, -1, -1, - 12, 33, 34, -1, 36, 37, 38, 39, -1, -1, - -1, -1, 3, 4, 46, 47, 7, 8, -1, 51, - -1, 33, 54, 55, 36, 37, 38, 39, -1, -1, - -1, -1, -1, -1, 46, 47, -1, -1, -1, 51, - 31, -1, 54, 55, -1, 36, 37, 38, 39, 3, - 4, -1, -1, 7, 8, 46, 47, -1, 49, -1, - 51, -1, -1, 54, 55, -1, -1, -1, -1, -1, - 3, 4, -1, -1, 7, 8, -1, 31, -1, -1, - -1, -1, 36, 37, 38, 39, -1, -1, -1, -1, - -1, -1, 46, 47, -1, 49, -1, 51, 31, -1, - 54, 55, -1, 36, 37, 38, 39, 3, 4, -1, - -1, 7, 8, 46, 47, -1, 49, -1, 51, -1, - -1, 54, 55, -1, -1, -1, -1, 3, 4, -1, - -1, 7, 8, -1, -1, -1, -1, -1, -1, -1, - 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, - 46, 47, -1, 49, -1, 51, -1, -1, 54, 55, - 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, - 46, 47, -1, -1, -1, 51, -1, -1, 54, 55 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) -#include <alloca.h> -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#include <malloc.h> -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -#include <malloc.h> - #pragma alloca -#else /* not MSDOS, __TURBOC__, or _AIX */ -#ifdef __hpux -#ifdef __cplusplus -extern "C" { -void *alloca (unsigned int); -}; -#else /* not __cplusplus */ -void *alloca (); -#endif /* not __cplusplus */ -#endif /* __hpux */ -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -#ifndef YYPARSE_RETURN_TYPE -#define YYPARSE_RETURN_TYPE int -#endif - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -YYPARSE_RETURN_TYPE yyparse (void); -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 196 "/usr/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -YYPARSE_RETURN_TYPE -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 151 "./awk.y" -{ - expression_value = yyvsp[-1].nodeval; - check_funcs(); - ; - break;} -case 2: -#line 159 "./awk.y" -{ - if (yyvsp[0].nodeval != NULL) - yyval.nodeval = yyvsp[0].nodeval; - else - yyval.nodeval = NULL; - yyerrok; - ; - break;} -case 3: -#line 168 "./awk.y" -{ - if (yyvsp[0].nodeval == NULL) - yyval.nodeval = yyvsp[-1].nodeval; - else if (yyvsp[-1].nodeval == NULL) - yyval.nodeval = yyvsp[0].nodeval; - else { - if (yyvsp[-1].nodeval->type != Node_rule_list) - yyvsp[-1].nodeval = node(yyvsp[-1].nodeval, Node_rule_list, - (NODE*) NULL); - yyval.nodeval = append_right(yyvsp[-1].nodeval, - node(yyvsp[0].nodeval, Node_rule_list, (NODE *) NULL)); - } - yyerrok; - ; - break;} -case 4: -#line 182 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 5: -#line 183 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 6: -#line 184 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 7: -#line 188 "./awk.y" -{ io_allowed = FALSE; ; - break;} -case 8: -#line 190 "./awk.y" -{ - if (begin_block != NULL) { - if (begin_block->type != Node_rule_list) - begin_block = node(begin_block, Node_rule_list, - (NODE *) NULL); - (void) append_right(begin_block, node( - node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval), - Node_rule_list, (NODE *) NULL) ); - } else - begin_block = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); - yyval.nodeval = NULL; - io_allowed = TRUE; - yyerrok; - ; - break;} -case 9: -#line 204 "./awk.y" -{ io_allowed = FALSE; ; - break;} -case 10: -#line 206 "./awk.y" -{ - if (end_block != NULL) { - if (end_block->type != Node_rule_list) - end_block = node(end_block, Node_rule_list, - (NODE *) NULL); - (void) append_right (end_block, node( - node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval), - Node_rule_list, (NODE *) NULL)); - } else - end_block = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); - yyval.nodeval = NULL; - io_allowed = TRUE; - yyerrok; - ; - break;} -case 11: -#line 221 "./awk.y" -{ - warning("BEGIN blocks must have an action part"); - errcount++; - yyerrok; - ; - break;} -case 12: -#line 227 "./awk.y" -{ - warning("END blocks must have an action part"); - errcount++; - yyerrok; - ; - break;} -case 13: -#line 233 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_rule_node, yyvsp[0].nodeval); yyerrok; ; - break;} -case 14: -#line 235 "./awk.y" -{ yyval.nodeval = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); yyerrok; ; - break;} -case 15: -#line 237 "./awk.y" -{ - yyval.nodeval = node(yyvsp[-1].nodeval, - Node_rule_node, - node(node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL), - Node_K_print, - (NODE *) NULL)); - yyerrok; - ; - break;} -case 16: -#line 250 "./awk.y" -{ - func_install(yyvsp[-1].nodeval, yyvsp[0].nodeval); - yyval.nodeval = NULL; - yyerrok; - ; - break;} -case 17: -#line 259 "./awk.y" -{ yyval.sval = yyvsp[0].sval; ; - break;} -case 18: -#line 261 "./awk.y" -{ yyval.sval = yyvsp[0].sval; ; - break;} -case 19: -#line 263 "./awk.y" -{ - yyerror("%s() is a built-in function, it cannot be redefined", - tokstart); - errcount++; - /* yyerrok; */ - ; - break;} -case 22: -#line 278 "./awk.y" -{ - param_counter = 0; - ; - break;} -case 23: -#line 282 "./awk.y" -{ - NODE *t; - - t = make_param(yyvsp[-4].sval); - t->flags |= FUNC; - yyval.nodeval = append_right(t, yyvsp[-2].nodeval); - can_return = TRUE; - /* check for duplicate parameter names */ - if (dup_parms(yyval.nodeval)) - errcount++; - ; - break;} -case 24: -#line 297 "./awk.y" -{ - yyval.nodeval = yyvsp[-2].nodeval; - can_return = FALSE; - ; - break;} -case 25: -#line 302 "./awk.y" -{ - yyval.nodeval = node((NODE *) NULL, Node_K_return, (NODE *) NULL); - can_return = FALSE; - ; - break;} -case 26: -#line 311 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 27: -#line 313 "./awk.y" -{ yyval.nodeval = mkrangenode(node(yyvsp[-2].nodeval, Node_cond_pair, yyvsp[0].nodeval)); ; - break;} -case 28: -#line 322 "./awk.y" -{ ++want_regexp; ; - break;} -case 29: -#line 324 "./awk.y" -{ - NODE *n; - size_t len; - - getnode(n); - n->type = Node_regex; - len = strlen(yyvsp[-1].sval); - n->re_exp = make_string(yyvsp[-1].sval, len); - n->re_reg = make_regexp(yyvsp[-1].sval, len, FALSE, TRUE); - n->re_text = NULL; - n->re_flags = CONST; - n->re_cnt = 1; - yyval.nodeval = n; - ; - break;} -case 30: -#line 342 "./awk.y" -{ yyval.nodeval = yyvsp[-3].nodeval; ; - break;} -case 31: -#line 344 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 32: -#line 349 "./awk.y" -{ - yyval.nodeval = yyvsp[0].nodeval; - if (do_lint && isnoeffect(yyval.nodeval->type)) - warning("statement may have no effect"); - ; - break;} -case 33: -#line 355 "./awk.y" -{ - if (yyvsp[-1].nodeval == NULL || yyvsp[-1].nodeval->type != Node_statement_list) - yyvsp[-1].nodeval = node(yyvsp[-1].nodeval, Node_statement_list, (NODE *) NULL); - yyval.nodeval = append_right(yyvsp[-1].nodeval, - node(yyvsp[0].nodeval, Node_statement_list, (NODE *) NULL)); - yyerrok; - ; - break;} -case 34: -#line 363 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 35: -#line 365 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 38: -#line 375 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 39: -#line 377 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 40: -#line 379 "./awk.y" -{ yyval.nodeval = yyvsp[-1].nodeval; ; - break;} -case 41: -#line 381 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 42: -#line 383 "./awk.y" -{ yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_while, yyvsp[0].nodeval); ; - break;} -case 43: -#line 385 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_do, yyvsp[-5].nodeval); ; - break;} -case 44: -#line 387 "./awk.y" -{ - /* - * Efficiency hack. Recognize the special case of - * - * for (iggy in foo) - * delete foo[iggy] - * - * and treat it as if it were - * - * delete foo - * - * Check that the body is a `delete a[i]' statement, - * and that both the loop var and array names match. - */ - if (yyvsp[0].nodeval->type == Node_K_delete - && yyvsp[0].nodeval->rnode != NULL - && strcmp(yyvsp[-5].sval, yyvsp[0].nodeval->rnode->var_value->vname) == 0 - && strcmp(yyvsp[-3].sval, yyvsp[0].nodeval->lnode->vname) == 0) { - yyvsp[0].nodeval->type = Node_K_delete_loop; - yyval.nodeval = yyvsp[0].nodeval; - } else { - yyval.nodeval = node(yyvsp[0].nodeval, Node_K_arrayfor, - make_for_loop(variable(yyvsp[-5].sval, CAN_FREE, Node_var), - (NODE *) NULL, variable(yyvsp[-3].sval, CAN_FREE, Node_var_array))); - } - ; - break;} -case 45: -#line 414 "./awk.y" -{ - yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, (NODE *) make_for_loop(yyvsp[-7].nodeval, yyvsp[-5].nodeval, yyvsp[-3].nodeval)); - ; - break;} -case 46: -#line 418 "./awk.y" -{ - yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, - (NODE *) make_for_loop(yyvsp[-6].nodeval, (NODE *) NULL, yyvsp[-3].nodeval)); - ; - break;} -case 47: -#line 424 "./awk.y" -{ yyval.nodeval = node((NODE *) NULL, Node_K_break, (NODE *) NULL); ; - break;} -case 48: -#line 427 "./awk.y" -{ yyval.nodeval = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); ; - break;} -case 49: -#line 429 "./awk.y" -{ yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-5].nodetypeval, yyvsp[-1].nodeval); ; - break;} -case 50: -#line 431 "./awk.y" -{ - if (yyvsp[-3].nodetypeval == Node_K_print && yyvsp[-2].nodeval == NULL) { - static int warned = FALSE; - - yyvsp[-2].nodeval = node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL); - - if (do_lint && ! io_allowed && ! warned) { - warned = TRUE; - warning( - "plain `print' in BEGIN or END rule should probably be `print \"\"'"); - } - } - - yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-3].nodetypeval, yyvsp[-1].nodeval); - ; - break;} -case 51: -#line 451 "./awk.y" -{ NODETYPE type; - - if (yyvsp[-1].nodeval) { - if (yyvsp[-1].nodeval == lookup("file")) { - static int warned = FALSE; - - if (! warned) { - warned = TRUE; - warning("`next file' is obsolete; use `nextfile'"); - } - if (do_lint) - warning("`next file' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`next file' is a gawk extension"); - } - if (! io_allowed) { - /* same thing */ - errcount++; - error("`next file' used in BEGIN or END action"); - } - type = Node_K_nextfile; - } else { - errcount++; - error("illegal expression after `next'"); - type = Node_K_next; /* sanity */ - } - } else { - if (! io_allowed) - yyerror("`next' used in BEGIN or END action"); - type = Node_K_next; - } - yyval.nodeval = node((NODE *) NULL, type, (NODE *) NULL); - ; - break;} -case 52: -#line 490 "./awk.y" -{ - if (do_lint) - warning("`nextfile' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`nextfile' is a gawk extension"); - } - if (! io_allowed) { - /* same thing */ - errcount++; - error("`nextfile' used in BEGIN or END action"); - } - yyval.nodeval = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL); - ; - break;} -case 53: -#line 509 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_exit, (NODE *) NULL); ; - break;} -case 54: -#line 511 "./awk.y" -{ - if (! can_return) - yyerror("`return' used outside function context"); - ; - break;} -case 55: -#line 516 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_return, (NODE *) NULL); ; - break;} -case 56: -#line 518 "./awk.y" -{ yyval.nodeval = node(variable(yyvsp[-4].sval, CAN_FREE, Node_var_array), Node_K_delete, yyvsp[-2].nodeval); ; - break;} -case 57: -#line 520 "./awk.y" -{ - if (do_lint) - warning("`delete array' is a gawk extension"); - if (do_traditional) { - /* - * can't use yyerror, since may have overshot - * the source line - */ - errcount++; - error("`delete array' is a gawk extension"); - } - yyval.nodeval = node(variable(yyvsp[-1].sval, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL); - ; - break;} -case 58: -#line 534 "./awk.y" -{ yyval.nodeval = yyvsp[-1].nodeval; ; - break;} -case 59: -#line 539 "./awk.y" -{ yyval.nodetypeval = yyvsp[0].nodetypeval; ; - break;} -case 60: -#line 541 "./awk.y" -{ yyval.nodetypeval = yyvsp[0].nodetypeval; ; - break;} -case 61: -#line 546 "./awk.y" -{ - yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_if, - node(yyvsp[0].nodeval, Node_if_branches, (NODE *) NULL)); - ; - break;} -case 62: -#line 552 "./awk.y" -{ yyval.nodeval = node(yyvsp[-6].nodeval, Node_K_if, - node(yyvsp[-3].nodeval, Node_if_branches, yyvsp[0].nodeval)); ; - break;} -case 63: -#line 558 "./awk.y" -{ want_assign = FALSE; ; - break;} -case 67: -#line 569 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 68: -#line 571 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_input, (NODE *) NULL); ; - break;} -case 69: -#line 576 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 70: -#line 578 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_output, (NODE *) NULL); ; - break;} -case 71: -#line 580 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_append, (NODE *) NULL); ; - break;} -case 72: -#line 582 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_pipe, (NODE *) NULL); ; - break;} -case 73: -#line 587 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 74: -#line 589 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 75: -#line 594 "./awk.y" -{ yyval.nodeval = make_param(yyvsp[0].sval); ; - break;} -case 76: -#line 596 "./awk.y" -{ yyval.nodeval = append_right(yyvsp[-2].nodeval, make_param(yyvsp[0].sval)); yyerrok; ; - break;} -case 77: -#line 598 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 78: -#line 600 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 79: -#line 602 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 80: -#line 608 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 81: -#line 610 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 82: -#line 615 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 83: -#line 617 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 84: -#line 622 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL); ; - break;} -case 85: -#line 624 "./awk.y" -{ - yyval.nodeval = append_right(yyvsp[-2].nodeval, - node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL)); - yyerrok; - ; - break;} -case 86: -#line 630 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 87: -#line 632 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 88: -#line 634 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 89: -#line 636 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 90: -#line 641 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 91: -#line 643 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 92: -#line 648 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL); ; - break;} -case 93: -#line 650 "./awk.y" -{ - yyval.nodeval = append_right(yyvsp[-2].nodeval, - node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL)); - yyerrok; - ; - break;} -case 94: -#line 656 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 95: -#line 658 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 96: -#line 660 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 97: -#line 662 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 98: -#line 667 "./awk.y" -{ want_assign = FALSE; ; - break;} -case 99: -#line 669 "./awk.y" -{ - if (do_lint && yyvsp[0].nodeval->type == Node_regex) - warning("Regular expression on left of assignment."); - yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-2].nodetypeval, yyvsp[0].nodeval); - ; - break;} -case 100: -#line 675 "./awk.y" -{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-3].nodeval); ; - break;} -case 101: -#line 677 "./awk.y" -{ - yyval.nodeval = node(yyvsp[0].nodeval, Node_K_getline, - node(yyvsp[-3].nodeval, Node_redirect_pipein, (NODE *) NULL)); - ; - break;} -case 102: -#line 682 "./awk.y" -{ - if (do_lint && ! io_allowed && yyvsp[0].nodeval == NULL) - warning("non-redirected getline undefined inside BEGIN or END action"); - yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval); - ; - break;} -case 103: -#line 688 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval); ; - break;} -case 104: -#line 690 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval); ; - break;} -case 105: -#line 692 "./awk.y" -{ - if (yyvsp[-2].nodeval->type == Node_regex) - warning("Regular expression on left of MATCH operator."); - yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, mk_rexp(yyvsp[0].nodeval)); - ; - break;} -case 106: -#line 698 "./awk.y" -{ - yyval.nodeval = yyvsp[0].nodeval; - if (do_lint && tokstart[0] == '*') { - /* possible C comment */ - int n = strlen(tokstart) - 1; - if (tokstart[n] == '*') - warning("regexp looks like a C comment, but is not"); - } - ; - break;} -case 107: -#line 708 "./awk.y" -{ - yyval.nodeval = node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_nomatch, - yyvsp[0].nodeval); - ; - break;} -case 108: -#line 716 "./awk.y" -{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-2].nodeval); ; - break;} -case 109: -#line 718 "./awk.y" -{ - if (do_lint && yyvsp[0].nodeval->type == Node_regex) - warning("Regular expression on left of comparison."); - yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); - ; - break;} -case 110: -#line 724 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_less, yyvsp[0].nodeval); ; - break;} -case 111: -#line 726 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_greater, yyvsp[0].nodeval); ; - break;} -case 112: -#line 728 "./awk.y" -{ yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_if_branches, yyvsp[0].nodeval));; - break;} -case 113: -#line 730 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 114: -#line 732 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_concat, yyvsp[0].nodeval); ; - break;} -case 115: -#line 737 "./awk.y" -{ want_assign = FALSE; ; - break;} -case 116: -#line 739 "./awk.y" -{ yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-2].nodetypeval, yyvsp[0].nodeval); ; - break;} -case 117: -#line 741 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval); ; - break;} -case 118: -#line 743 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval); ; - break;} -case 119: -#line 745 "./awk.y" -{ - if (do_lint && ! io_allowed && yyvsp[0].nodeval == NULL) - warning("non-redirected getline undefined inside BEGIN or END action"); - yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval); - ; - break;} -case 120: -#line 751 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 121: -#line 753 "./awk.y" -{ yyval.nodeval = node((NODE *) NULL, Node_nomatch, yyvsp[0].nodeval); ; - break;} -case 122: -#line 755 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, mk_rexp(yyvsp[0].nodeval)); ; - break;} -case 123: -#line 757 "./awk.y" -{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-2].nodeval); ; - break;} -case 124: -#line 759 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); ; - break;} -case 125: -#line 761 "./awk.y" -{ yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_if_branches, yyvsp[0].nodeval));; - break;} -case 126: -#line 763 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 127: -#line 765 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_concat, yyvsp[0].nodeval); ; - break;} -case 129: -#line 772 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_exp, yyvsp[0].nodeval); ; - break;} -case 130: -#line 774 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_times, yyvsp[0].nodeval); ; - break;} -case 131: -#line 776 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_quotient, yyvsp[0].nodeval); ; - break;} -case 132: -#line 778 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_mod, yyvsp[0].nodeval); ; - break;} -case 133: -#line 780 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_plus, yyvsp[0].nodeval); ; - break;} -case 134: -#line 782 "./awk.y" -{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_minus, yyvsp[0].nodeval); ; - break;} -case 135: -#line 784 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_postincrement, (NODE *) NULL); ; - break;} -case 136: -#line 786 "./awk.y" -{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_postdecrement, (NODE *) NULL); ; - break;} -case 137: -#line 791 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_not, (NODE *) NULL); ; - break;} -case 138: -#line 793 "./awk.y" -{ yyval.nodeval = yyvsp[-1].nodeval; ; - break;} -case 139: -#line 796 "./awk.y" -{ yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); ; - break;} -case 140: -#line 798 "./awk.y" -{ yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); ; - break;} -case 141: -#line 800 "./awk.y" -{ - if (do_lint) - warning("call of `length' without parentheses is not portable"); - yyval.nodeval = snode((NODE *) NULL, Node_builtin, (int) yyvsp[0].lval); - if (do_posix) - warning("call of `length' without parentheses is deprecated by POSIX"); - ; - break;} -case 142: -#line 808 "./awk.y" -{ - yyval.nodeval = node(yyvsp[-1].nodeval, Node_func_call, make_string(yyvsp[-3].sval, strlen(yyvsp[-3].sval))); - func_use(yyvsp[-3].sval, FUNC_USE); - param_sanity(yyvsp[-1].nodeval); - free(yyvsp[-3].sval); - ; - break;} -case 144: -#line 816 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_preincrement, (NODE *) NULL); ; - break;} -case 145: -#line 818 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_predecrement, (NODE *) NULL); ; - break;} -case 146: -#line 820 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 147: -#line 822 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 148: -#line 825 "./awk.y" -{ - if (yyvsp[0].nodeval->type == Node_val) { - yyvsp[0].nodeval->numbr = -(force_number(yyvsp[0].nodeval)); - yyval.nodeval = yyvsp[0].nodeval; - } else - yyval.nodeval = node(yyvsp[0].nodeval, Node_unary_minus, (NODE *) NULL); - ; - break;} -case 149: -#line 833 "./awk.y" -{ - /* - * was: $$ = $2 - * POSIX semantics: force a conversion to numeric type - */ - yyval.nodeval = node (make_number(0.0), Node_plus, yyvsp[0].nodeval); - ; - break;} -case 150: -#line 844 "./awk.y" -{ yyval.nodeval = NULL; ; - break;} -case 151: -#line 846 "./awk.y" -{ yyval.nodeval = yyvsp[0].nodeval; ; - break;} -case 152: -#line 851 "./awk.y" -{ yyval.nodeval = variable(yyvsp[0].sval, CAN_FREE, Node_var); ; - break;} -case 153: -#line 853 "./awk.y" -{ - if (yyvsp[-1].nodeval == NULL) { - fatal("invalid subscript expression"); - } else if (yyvsp[-1].nodeval->rnode == NULL) { - yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval->lnode); - freenode(yyvsp[-1].nodeval); - } else - yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval); - ; - break;} -case 154: -#line 863 "./awk.y" -{ yyval.nodeval = node(yyvsp[0].nodeval, Node_field_spec, (NODE *) NULL); ; - break;} -case 156: -#line 871 "./awk.y" -{ yyerrok; ; - break;} -case 157: -#line 875 "./awk.y" -{ yyerrok; ; - break;} -case 160: -#line 884 "./awk.y" -{ yyerrok; want_assign = FALSE; ; - break;} -case 161: -#line 887 "./awk.y" -{ yyerrok; ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 498 "/usr/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} -#line 890 "./awk.y" - - -struct token { - const char *operator; /* text to match */ - NODETYPE value; /* node type */ - int class; /* lexical class */ - unsigned flags; /* # of args. allowed and compatability */ -# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */ -# define A(n) (1<<(n)) -# define VERSION 0xFF00 /* old awk is zero */ -# define NOT_OLD 0x0100 /* feature not in old awk */ -# define NOT_POSIX 0x0200 /* feature not in POSIX */ -# define GAWKX 0x0400 /* gawk extension */ -# define RESX 0x0800 /* Bell Labs Research extension */ - NODE *(*ptr)(); /* function that implements this keyword */ -}; - - -/* Tokentab is sorted ascii ascending order, so it can be binary searched. */ -/* Function pointers come from declarations in awk.h. */ - -static struct token tokentab[] = { -{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0}, -{"END", Node_illegal, LEX_END, 0, 0}, -#ifdef ARRAYDEBUG -{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump}, -#endif -#ifdef BITOPS -{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and}, -#endif /* BITOPS */ -{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2}, -{"break", Node_K_break, LEX_BREAK, 0, 0}, -{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_close}, -#ifdef BITOPS -{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl}, -#endif /* BITOPS */ -{"continue", Node_K_continue, LEX_CONTINUE, 0, 0}, -{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos}, -{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0}, -{"do", Node_K_do, LEX_DO, NOT_OLD, 0}, -{"else", Node_illegal, LEX_ELSE, 0, 0}, -{"exit", Node_K_exit, LEX_EXIT, 0, 0}, -{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp}, -{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush}, -{"for", Node_K_for, LEX_FOR, 0, 0}, -{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, -{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0}, -{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, -{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0}, -{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, -{"if", Node_K_if, LEX_IF, 0, 0}, -{"in", Node_illegal, LEX_IN, 0, 0}, -{"index", Node_builtin, LEX_BUILTIN, A(2), do_index}, -{"int", Node_builtin, LEX_BUILTIN, A(1), do_int}, -{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length}, -{"log", Node_builtin, LEX_BUILTIN, A(1), do_log}, -#ifdef BITOPS -{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift}, -#endif /* BITOPS */ -{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_match}, -{"next", Node_K_next, LEX_NEXT, 0, 0}, -{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0}, -#ifdef BITOPS -{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or}, -#endif /* BITOPS */ -{"print", Node_K_print, LEX_PRINT, 0, 0}, -{"printf", Node_K_printf, LEX_PRINTF, 0, 0}, -{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand}, -{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0}, -#ifdef BITOPS -{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift}, -#endif /* BITOPS */ -{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin}, -{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split}, -{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf}, -{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt}, -{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand}, -#ifdef ARRAYDEBUG -{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme}, -#endif -{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime}, -#ifdef BITOPS -{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, -#endif /* BITOPS */ -{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, -{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, -{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, -{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime}, -{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower}, -{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper}, -{"while", Node_K_while, LEX_WHILE, 0, 0}, -#ifdef BITOPS -{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor}, -#endif /* BITOPS */ -}; - -/* yyerror --- print a syntax error message, show where */ - -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ -static void -yyerror(const char *m, ...) -#else -/* VARARGS0 */ -static void -yyerror(va_alist) -va_dcl -#endif -{ - va_list args; - const char *mesg = NULL; - register char *bp, *cp; - char *scan; - char buf[120]; - static char end_of_file_line[] = "(END OF FILE)"; - - errcount++; - /* Find the current line in the input file */ - if (lexptr && lexeme) { - if (thisline == NULL) { - cp = lexeme; - if (*cp == '\n') { - cp--; - mesg = "unexpected newline"; - } - for (; cp != lexptr_begin && *cp != '\n'; --cp) - continue; - if (*cp == '\n') - cp++; - thisline = cp; - } - /* NL isn't guaranteed */ - bp = lexeme; - while (bp < lexend && *bp && *bp != '\n') - bp++; - } else { - thisline = end_of_file_line; - bp = thisline + strlen(thisline); - } - msg("%.*s", (int) (bp - thisline), thisline); - bp = buf; - cp = buf + sizeof(buf) - 24; /* 24 more than longest msg. input */ - if (lexptr != NULL) { - scan = thisline; - while (bp < cp && scan < lexeme) - if (*scan++ == '\t') - *bp++ = '\t'; - else - *bp++ = ' '; - *bp++ = '^'; - *bp++ = ' '; - } -#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ - va_start(args, m); - if (mesg == NULL) - mesg = m; -#else - va_start(args); - if (mesg == NULL) - mesg = va_arg(args, char *); -#endif - strcpy(bp, mesg); - err("", buf, args); - va_end(args); -} - -/* get_src_buf --- read the next buffer of source program */ - -static char * -get_src_buf() -{ - static int samefile = FALSE; - static int nextfile = 0; - static char *buf = NULL; - static int fd; - int n; - register char *scan; - static int len = 0; - static int did_newline = FALSE; - int newfile; - struct stat sbuf; - -# define SLOP 128 /* enough space to hold most source lines */ - -again: - newfile = FALSE; - if (nextfile > numfiles) - return NULL; - - if (srcfiles[nextfile].stype == CMDLINE) { - if (len == 0) { - len = strlen(srcfiles[nextfile].val); - if (len == 0) { - /* - * Yet Another Special case: - * gawk '' /path/name - * Sigh. - */ - static int warned = FALSE; - - if (do_lint && ! warned) { - warned = TRUE; - warning("empty program text on command line"); - } - ++nextfile; - goto again; - } - sourceline = 1; - lexptr = lexptr_begin = srcfiles[nextfile].val; - lexend = lexptr + len; - } else if (! did_newline && *(lexptr-1) != '\n') { - /* - * The following goop is to ensure that the source - * ends with a newline and that the entire current - * line is available for error messages. - */ - int offset; - - did_newline = TRUE; - offset = lexptr - lexeme; - for (scan = lexeme; scan > lexptr_begin; scan--) - if (*scan == '\n') { - scan++; - break; - } - len = lexptr - scan; - emalloc(buf, char *, len+1, "get_src_buf"); - memcpy(buf, scan, len); - thisline = buf; - lexptr = buf + len; - *lexptr = '\n'; - lexeme = lexptr - offset; - lexptr_begin = buf; - lexend = lexptr + 1; - } else { - len = 0; - lexeme = lexptr = lexptr_begin = NULL; - } - if (lexptr == NULL && ++nextfile <= numfiles) - goto again; - return lexptr; - } - if (! samefile) { - source = srcfiles[nextfile].val; - if (source == NULL) { - if (buf != NULL) { - free(buf); - buf = NULL; - } - len = 0; - return lexeme = lexptr = lexptr_begin = NULL; - } - fd = pathopen(source); - if (fd <= INVALID_HANDLE) { - char *in; - - /* suppress file name and line no. in error mesg */ - in = source; - source = NULL; - fatal("can't open source file \"%s\" for reading (%s)", - in, strerror(errno)); - } - len = optimal_bufsize(fd, & sbuf); - newfile = TRUE; - if (buf != NULL) - free(buf); - emalloc(buf, char *, len + SLOP, "get_src_buf"); - lexptr_begin = buf + SLOP; - samefile = TRUE; - sourceline = 1; - } else { - /* - * Here, we retain the current source line (up to length SLOP) - * in the beginning of the buffer that was overallocated above - */ - int offset; - int linelen; - - offset = lexptr - lexeme; - for (scan = lexeme; scan > lexptr_begin; scan--) - if (*scan == '\n') { - scan++; - break; - } - linelen = lexptr - scan; - if (linelen > SLOP) - linelen = SLOP; - thisline = buf + SLOP - linelen; - memcpy(thisline, scan, linelen); - lexeme = buf + SLOP - offset; - lexptr_begin = thisline; - } - n = read(fd, buf + SLOP, len); - if (n == -1) - fatal("can't read sourcefile \"%s\" (%s)", - source, strerror(errno)); - if (n == 0) { - if (newfile) { - static int warned = FALSE; - - if (do_lint && ! warned) { - warned = TRUE; - warning("source file `%s' is empty", source); - } - } - if (fileno(stdin) != fd) /* safety */ - close(fd); - samefile = FALSE; - nextfile++; - if (lexeme) - *lexeme = '\0'; - len = 0; - goto again; - } - lexptr = buf + SLOP; - lexend = lexptr + n; - return buf; -} - -/* tokadd --- add a character to the token buffer */ - -#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok) - -/* tokexpand --- grow the token buffer */ - -char * -tokexpand() -{ - static int toksize = 60; - int tokoffset; - - tokoffset = tok - tokstart; - toksize *= 2; - if (tokstart != NULL) - erealloc(tokstart, char *, toksize, "tokexpand"); - else - emalloc(tokstart, char *, toksize, "tokexpand"); - tokend = tokstart + toksize; - tok = tokstart + tokoffset; - return tok; -} - -/* nextc --- get the next input character */ - -#if DEBUG -int -nextc() -{ - int c; - - if (lexptr && lexptr < lexend) - c = (int) (unsigned char) *lexptr++; - else if (get_src_buf()) - c = (int) (unsigned char) *lexptr++; - else - c = EOF; - - return c; -} -#else -#define nextc() ((lexptr && lexptr < lexend) ? \ - ((int) (unsigned char) *lexptr++) : \ - (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \ - ) -#endif - -/* pushback --- push a character back on the input */ - -#define pushback() (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr) - -/* allow_newline --- allow newline after &&, ||, ? and : */ - -static void -allow_newline() -{ - int c; - - for (;;) { - c = nextc(); - if (c == EOF) - break; - if (c == '#') { - while ((c = nextc()) != '\n' && c != EOF) - continue; - if (c == EOF) - break; - } - if (c == '\n') - sourceline++; - if (! isspace(c)) { - pushback(); - break; - } - } -} - -/* yylex --- Read the input and turn it into tokens. */ - -static int -yylex() -{ - register int c, c1; - int seen_e = FALSE; /* These are for numbers */ - int seen_point = FALSE; - int esc_seen; /* for literal strings */ - int low, mid, high; - static int did_newline = FALSE; - char *tokkey; - static int lasttok = 0, eof_warned = FALSE; - int inhex = FALSE; - - if (nextc() == EOF) { - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - } - pushback(); -#ifdef OS2 - /* - * added for OS/2's extproc feature of cmd.exe - * (like #! in BSD sh) - */ - if (strncasecmp(lexptr, "extproc ", 8) == 0) { - while (*lexptr && *lexptr != '\n') - lexptr++; - } -#endif - lexeme = lexptr; - thisline = NULL; - if (want_regexp) { - int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ - /* - * Counting brackets is non-trivial. [[] is ok, - * and so is [\]], with a point being that /[/]/ as a regexp - * constant has to work. - * - * Do not count [ or ] if either one is preceded by a \. - * A `[' should be counted if - * a) it is the first one so far (in_brack == 0) - * b) it is the `[' in `[:' - * A ']' should be counted if not preceded by a \, since - * it is either closing `:]' or just a plain list. - * According to POSIX, []] is how you put a ] into a set. - * Try to handle that too. - * - * The code for \ handles \[ and \]. - */ - - want_regexp = FALSE; - tok = tokstart; - for (;;) { - c = nextc(); - switch (c) { - case '[': - /* one day check for `.' and `=' too */ - if ((c1 = nextc()) == ':' || in_brack == 0) - in_brack++; - pushback(); - break; - case ']': - if (tokstart[0] == '[' - && (tok == tokstart + 1 - || (tok == tokstart + 2 - && tokstart[1] == '^'))) - /* do nothing */; - else - in_brack--; - break; - case '\\': - if ((c = nextc()) == EOF) { - yyerror("unterminated regexp ends with \\ at end of file"); - return lasttok = REGEXP; /* kludge */ - } else if (c == '\n') { - sourceline++; - continue; - } else { - tokadd('\\'); - tokadd(c); - continue; - } - break; - case '/': /* end of the regexp */ - if (in_brack > 0) - break; - - pushback(); - tokadd('\0'); - yylval.sval = tokstart; - return lasttok = REGEXP; - case '\n': - pushback(); - yyerror("unterminated regexp"); - return lasttok = REGEXP; /* kludge */ - case EOF: - yyerror("unterminated regexp at end of file"); - return lasttok = REGEXP; /* kludge */ - } - tokadd(c); - } - } -retry: - while ((c = nextc()) == ' ' || c == '\t') - continue; - - lexeme = lexptr ? lexptr - 1 : lexptr; - thisline = NULL; - tok = tokstart; - yylval.nodetypeval = Node_illegal; - - switch (c) { - case EOF: - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - - case '\n': - sourceline++; - return lasttok = NEWLINE; - - case '#': /* it's a comment */ - while ((c = nextc()) != '\n') { - if (c == EOF) { - if (lasttok != NEWLINE) { - lasttok = NEWLINE; - if (do_lint && ! eof_warned) { - warning( - "source file does not end in newline"); - eof_warned = TRUE; - } - return NEWLINE; /* fake it */ - } - return 0; - } - } - sourceline++; - return lasttok = NEWLINE; - - case '\\': -#ifdef RELAXED_CONTINUATION - /* - * This code puports to allow comments and/or whitespace - * after the `\' at the end of a line used for continuation. - * Use it at your own risk. We think it's a bad idea, which - * is why it's not on by default. - */ - if (! do_traditional) { - /* strip trailing white-space and/or comment */ - while ((c = nextc()) == ' ' || c == '\t') - continue; - if (c == '#') { - if (do_lint) - warning( - "use of `\\ #...' line continuation is not portable"); - while ((c = nextc()) != '\n') - if (c == EOF) - break; - } - pushback(); - } -#endif /* RELAXED_CONTINUATION */ - if (nextc() == '\n') { - sourceline++; - goto retry; - } else { - yyerror("backslash not last character on line"); - exit(1); - } - break; - - case '$': - want_assign = TRUE; - return lasttok = '$'; - - case ':': - case '?': - allow_newline(); - return lasttok = c; - - case ')': - case '(': - case ';': - case '{': - case ',': - want_assign = FALSE; - /* fall through */ - case '[': - case ']': - return lasttok = c; - - case '*': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_times; - return lasttok = ASSIGNOP; - } else if (do_posix) { - pushback(); - return lasttok = '*'; - } else if (c == '*') { - /* make ** and **= aliases for ^ and ^= */ - static int did_warn_op = FALSE, did_warn_assgn = FALSE; - - if (nextc() == '=') { - if (do_lint && ! did_warn_assgn) { - did_warn_assgn = TRUE; - warning("**= is not allowed by POSIX"); - warning("operator `**=' is not supported in old awk"); - } - yylval.nodetypeval = Node_assign_exp; - return ASSIGNOP; - } else { - pushback(); - if (do_lint && ! did_warn_op) { - did_warn_op = TRUE; - warning("** is not allowed by POSIX"); - warning("operator `**' is not supported in old awk"); - } - return lasttok = '^'; - } - } - pushback(); - return lasttok = '*'; - - case '/': - if (want_assign) { - if (nextc() == '=') { - yylval.nodetypeval = Node_assign_quotient; - return lasttok = ASSIGNOP; - } - pushback(); - } - return lasttok = '/'; - - case '%': - if (nextc() == '=') { - yylval.nodetypeval = Node_assign_mod; - return lasttok = ASSIGNOP; - } - pushback(); - return lasttok = '%'; - - case '^': - { - static int did_warn_op = FALSE, did_warn_assgn = FALSE; - - if (nextc() == '=') { - if (do_lint && ! did_warn_assgn) { - did_warn_assgn = TRUE; - warning("operator `^=' is not supported in old awk"); - } - yylval.nodetypeval = Node_assign_exp; - return lasttok = ASSIGNOP; - } - pushback(); - if (do_lint && ! did_warn_op) { - did_warn_op = TRUE; - warning("operator `^' is not supported in old awk"); - } - return lasttok = '^'; - } - - case '+': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_plus; - return lasttok = ASSIGNOP; - } - if (c == '+') - return lasttok = INCREMENT; - pushback(); - return lasttok = '+'; - - case '!': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_notequal; - return lasttok = RELOP; - } - if (c == '~') { - yylval.nodetypeval = Node_nomatch; - want_assign = FALSE; - return lasttok = MATCHOP; - } - pushback(); - return lasttok = '!'; - - case '<': - if (nextc() == '=') { - yylval.nodetypeval = Node_leq; - return lasttok = RELOP; - } - yylval.nodetypeval = Node_less; - pushback(); - return lasttok = '<'; - - case '=': - if (nextc() == '=') { - yylval.nodetypeval = Node_equal; - return lasttok = RELOP; - } - yylval.nodetypeval = Node_assign; - pushback(); - return lasttok = ASSIGNOP; - - case '>': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_geq; - return lasttok = RELOP; - } else if (c == '>') { - yylval.nodetypeval = Node_redirect_append; - return lasttok = APPEND_OP; - } - yylval.nodetypeval = Node_greater; - pushback(); - return lasttok = '>'; - - case '~': - yylval.nodetypeval = Node_match; - want_assign = FALSE; - return lasttok = MATCHOP; - - case '}': - /* - * Added did newline stuff. Easier than - * hacking the grammar. - */ - if (did_newline) { - did_newline = FALSE; - return lasttok = c; - } - did_newline++; - --lexptr; /* pick up } next time */ - return lasttok = NEWLINE; - - case '"': - esc_seen = FALSE; - while ((c = nextc()) != '"') { - if (c == '\n') { - pushback(); - yyerror("unterminated string"); - exit(1); - } - if (c == '\\') { - c = nextc(); - if (c == '\n') { - sourceline++; - continue; - } - esc_seen = TRUE; - tokadd('\\'); - } - if (c == EOF) { - pushback(); - yyerror("unterminated string"); - exit(1); - } - tokadd(c); - } - yylval.nodeval = make_str_node(tokstart, - tok - tokstart, esc_seen ? SCAN : 0); - yylval.nodeval->flags |= PERM; - return lasttok = YSTRING; - - case '-': - if ((c = nextc()) == '=') { - yylval.nodetypeval = Node_assign_minus; - return lasttok = ASSIGNOP; - } - if (c == '-') - return lasttok = DECREMENT; - pushback(); - return lasttok = '-'; - - case '.': - c = nextc(); - pushback(); - if (! isdigit(c)) - return lasttok = '.'; - else - c = '.'; - /* FALL THROUGH */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* It's a number */ - for (;;) { - int gotnumber = FALSE; - - tokadd(c); - switch (c) { -#ifdef BITOPS - case 'x': - case 'X': - if (do_traditional) - goto done; - if (tok == tokstart + 2) - inhex = TRUE; - break; -#endif /* BITOTS */ - case '.': - if (seen_point) { - gotnumber = TRUE; - break; - } - seen_point = TRUE; - break; - case 'e': - case 'E': - if (inhex) - break; - if (seen_e) { - gotnumber = TRUE; - break; - } - seen_e = TRUE; - if ((c = nextc()) == '-' || c == '+') - tokadd(c); - else - pushback(); - break; -#ifdef BITOPS - case 'a': - case 'A': - case 'b': - case 'B': - case 'c': - case 'C': - case 'D': - case 'd': - case 'f': - case 'F': - if (do_traditional || ! inhex) - goto done; - /* fall through */ -#endif - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - default: - done: - gotnumber = TRUE; - } - if (gotnumber) - break; - c = nextc(); - } - if (c != EOF) - pushback(); - else if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - tokadd('\0'); -#ifdef BITOPS - if (! do_traditional && isnondecimal(tokstart)) - yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart))); - else -#endif /* BITOPS */ - yylval.nodeval = make_number(atof(tokstart)); - yylval.nodeval->flags |= PERM; - return lasttok = YNUMBER; - - case '&': - if ((c = nextc()) == '&') { - yylval.nodetypeval = Node_and; - allow_newline(); - want_assign = FALSE; - return lasttok = LEX_AND; - } - pushback(); - return lasttok = '&'; - - case '|': - if ((c = nextc()) == '|') { - yylval.nodetypeval = Node_or; - allow_newline(); - want_assign = FALSE; - return lasttok = LEX_OR; - } - pushback(); - return lasttok = '|'; - } - - if (c != '_' && ! isalpha(c)) { - yyerror("Invalid char '%c' in expression\n", c); - exit(1); - } - - /* it's some type of name-type-thing. Find its length. */ - tok = tokstart; - while (is_identchar(c)) { - tokadd(c); - c = nextc(); - } - tokadd('\0'); - emalloc(tokkey, char *, tok - tokstart, "yylex"); - memcpy(tokkey, tokstart, tok - tokstart); - if (c != EOF) - pushback(); - else if (do_lint && ! eof_warned) { - warning("source file does not end in newline"); - eof_warned = TRUE; - } - - /* See if it is a special token. */ - low = 0; - high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1; - while (low <= high) { - int i; - - mid = (low + high) / 2; - c = *tokstart - tokentab[mid].operator[0]; - i = c ? c : strcmp(tokstart, tokentab[mid].operator); - - if (i < 0) /* token < mid */ - high = mid - 1; - else if (i > 0) /* token > mid */ - low = mid + 1; - else { - if (do_lint) { - if (tokentab[mid].flags & GAWKX) - warning("%s() is a gawk extension", - tokentab[mid].operator); - if (tokentab[mid].flags & RESX) - warning("%s() is a Bell Labs extension", - tokentab[mid].operator); - if (tokentab[mid].flags & NOT_POSIX) - warning("POSIX does not allow %s", - tokentab[mid].operator); - } - if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) - warning("%s is not supported in old awk", - tokentab[mid].operator); - if ((do_traditional && (tokentab[mid].flags & GAWKX)) - || (do_posix && (tokentab[mid].flags & NOT_POSIX))) - break; - if (tokentab[mid].class == LEX_BUILTIN - || tokentab[mid].class == LEX_LENGTH - ) - yylval.lval = mid; - else - yylval.nodetypeval = tokentab[mid].value; - - free(tokkey); - return lasttok = tokentab[mid].class; - } - } - - yylval.sval = tokkey; - if (*lexptr == '(') - return lasttok = FUNC_CALL; - else { - want_assign = TRUE; - return lasttok = NAME; - } -} - -/* node_common --- common code for allocating a new node */ - -static NODE * -node_common(op) -NODETYPE op; -{ - register NODE *r; - - getnode(r); - r->type = op; - r->flags = MALLOC; - /* if lookahead is NL, lineno is 1 too high */ - if (lexeme && *lexeme == '\n') - r->source_line = sourceline - 1; - else - r->source_line = sourceline; - r->source_file = source; - return r; -} - -/* node --- allocates a node with defined lnode and rnode. */ - -NODE * -node(left, op, right) -NODE *left, *right; -NODETYPE op; -{ - register NODE *r; - - r = node_common(op); - r->lnode = left; - r->rnode = right; - return r; -} - -/* snode --- allocate a node with defined subnode and proc for builtin - functions. Checks for arg. count and supplies defaults where - possible. */ - -static NODE * -snode(subn, op, idx) -NODETYPE op; -int idx; -NODE *subn; -{ - register NODE *r; - register NODE *n; - int nexp = 0; - int args_allowed; - - r = node_common(op); - - /* traverse expression list to see how many args. given */ - for (n = subn; n != NULL; n = n->rnode) { - nexp++; - if (nexp > 3) - break; - } - - /* check against how many args. are allowed for this builtin */ - args_allowed = tokentab[idx].flags & ARGS; - if (args_allowed && (args_allowed & A(nexp)) == 0) - fatal("%s() cannot have %d argument%c", - tokentab[idx].operator, nexp, nexp == 1 ? ' ' : 's'); - - r->proc = tokentab[idx].ptr; - - /* special case processing for a few builtins */ - /* - * FIXME: go through these to make sure that everything done - * here is really right. Move anything that's not into - * the corresponding routine. - */ - if (nexp == 0 && r->proc == do_length) { - subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), - Node_expression_list, - (NODE *) NULL); - } else if (r->proc == do_match) { - if (subn->rnode->lnode->type != Node_regex) - subn->rnode->lnode = mk_rexp(subn->rnode->lnode); - } else if (r->proc == do_sub || r->proc == do_gsub) { - if (subn->lnode->type != Node_regex) - subn->lnode = mk_rexp(subn->lnode); - if (nexp == 2) - append_right(subn, node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL)); - else if (subn->rnode->rnode->lnode->type == Node_val) { - if (do_lint) - warning("string literal as last arg of substitute"); - } else if (! isassignable(subn->rnode->rnode->lnode)) - yyerror("%s third parameter is not a changeable object", - r->proc == do_sub ? "sub" : "gsub"); - } else if (r->proc == do_gensub) { - if (subn->lnode->type != Node_regex) - subn->lnode = mk_rexp(subn->lnode); - if (nexp == 3) - append_right(subn, node(node(make_number(0.0), - Node_field_spec, - (NODE *) NULL), - Node_expression_list, - (NODE *) NULL)); - } else if (r->proc == do_split) { - if (nexp == 2) - append_right(subn, - node(FS_node, Node_expression_list, (NODE *) NULL)); - n = subn->rnode->rnode->lnode; - if (n->type != Node_regex) - subn->rnode->rnode->lnode = mk_rexp(n); - if (nexp == 2) - subn->rnode->rnode->lnode->re_flags |= FS_DFLT; - } - - r->subnode = subn; - return r; -} - -/* - * mkrangenode: - * This allocates a Node_line_range node with defined condpair and - * zeroes the trigger word to avoid the temptation of assuming that calling - * 'node( foo, Node_line_range, 0)' will properly initialize 'triggered'. - * Otherwise like node(). - */ - -static NODE * -mkrangenode(cpair) -NODE *cpair; -{ - register NODE *r; - - getnode(r); - r->type = Node_line_range; - r->condpair = cpair; - r->triggered = FALSE; - return r; -} - -/* make_for_loop --- build a for loop */ - -static NODE * -make_for_loop(init, cond, incr) -NODE *init, *cond, *incr; -{ - register FOR_LOOP_HEADER *r; - NODE *n; - - emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop"); - getnode(n); - n->type = Node_illegal; - r->init = init; - r->cond = cond; - r->incr = incr; - n->sub.nodep.r.hd = r; - return n; -} - -/* dup_parms --- return TRUE if there are duplicate parameters */ - -static int -dup_parms(func) -NODE *func; -{ - register NODE *np; - char *fname, **names; - int count, i, j, dups; - NODE *params; - - if (func == NULL) /* error earlier */ - return TRUE; - - fname = func->param; - count = func->param_cnt; - params = func->rnode; - - if (count == 0) /* no args, no problem */ - return FALSE; - - if (params == NULL) /* error earlier */ - return TRUE; - - emalloc(names, char **, count * sizeof(char *), "dup_parms"); - - i = 0; - for (np = params; np != NULL; np = np->rnode) { - if (np->param == NULL) { /* error earlier, give up, go home */ - free(names); - return TRUE; - } - names[i++] = np->param; - } - - dups = 0; - for (i = 1; i < count; i++) { - for (j = 0; j < i; j++) { - if (strcmp(names[i], names[j]) == 0) { - dups++; - error( - "function `%s': parameter #%d, `%s', duplicates parameter #%d", - fname, i+1, names[j], j+1); - } - } - } - - free(names); - return (dups > 0 ? TRUE : FALSE); -} - -/* - * install: - * Install a name in the symbol table, even if it is already there. - * Caller must check against redefinition if that is desired. - */ - -NODE * -install(name, value) -char *name; -NODE *value; -{ - register NODE *hp; - register size_t len; - register int bucket; - - len = strlen(name); - bucket = hash(name, len, (unsigned long) HASHSIZE); - getnode(hp); - hp->type = Node_hashnode; - hp->hnext = variables[bucket]; - variables[bucket] = hp; - hp->hlength = len; - hp->hvalue = value; - hp->hname = name; - hp->hvalue->vname = name; - return hp->hvalue; -} - -/* lookup --- find the most recent hash node for name installed by install */ - -NODE * -lookup(name) -const char *name; -{ - register NODE *bucket; - register size_t len; - - len = strlen(name); - for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)]; - bucket != NULL; bucket = bucket->hnext) - if (bucket->hlength == len && STREQN(bucket->hname, name, len)) - return bucket->hvalue; - - return NULL; -} - -/* - * append_right: - * Add new to the rightmost branch of LIST. This uses n^2 time, so we make - * a simple attempt at optimizing it. - */ - -static NODE * -append_right(list, new) -NODE *list, *new; -{ - register NODE *oldlist; - static NODE *savefront = NULL, *savetail = NULL; - - if (list == NULL || new == NULL) - return list; - - oldlist = list; - if (savefront == oldlist) { - savetail = savetail->rnode = new; - return oldlist; - } else - savefront = oldlist; - while (list->rnode != NULL) - list = list->rnode; - savetail = list->rnode = new; - return oldlist; -} - -/* - * func_install: - * check if name is already installed; if so, it had better have Null value, - * in which case def is added as the value. Otherwise, install name with def - * as value. - */ - -static void -func_install(params, def) -NODE *params; -NODE *def; -{ - NODE *r; - NODE *n; - - /* check for function foo(foo) { ... }. bleh. */ - for (n = params->rnode; n != NULL; n = n->rnode) { - if (strcmp(n->param, params->param) == 0) - fatal("function `%s': can't use function name as parameter name", - params->param); - } - - pop_params(params->rnode); - pop_var(params, FALSE); - r = lookup(params->param); - if (r != NULL) { - fatal("function name `%s' previously defined", params->param); - } else - (void) install(params->param, node(params, Node_func, def)); - - func_use(params->param, FUNC_DEFINE); -} - -/* pop_var --- remove a variable from the symbol table */ - -static void -pop_var(np, freeit) -NODE *np; -int freeit; -{ - register NODE *bucket, **save; - register size_t len; - char *name; - - name = np->param; - len = strlen(name); - save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]); - for (bucket = *save; bucket != NULL; bucket = bucket->hnext) { - if (len == bucket->hlength && STREQN(bucket->hname, name, len)) { - *save = bucket->hnext; - freenode(bucket); - if (freeit) - free(np->param); - return; - } - save = &(bucket->hnext); - } -} - -/* pop_params --- remove list of function parameters from symbol table */ - -/* - * pop parameters out of the symbol table. do this in reverse order to - * avoid reading freed memory if there were duplicated parameters. - */ -static void -pop_params(params) -NODE *params; -{ - if (params == NULL) - return; - pop_params(params->rnode); - pop_var(params, TRUE); -} - -/* make_param --- make NAME into a function parameter */ - -static NODE * -make_param(name) -char *name; -{ - NODE *r; - - getnode(r); - r->type = Node_param_list; - r->rnode = NULL; - r->param = name; - r->param_cnt = param_counter++; - return (install(name, r)); -} - -static struct fdesc { - char *name; - short used; - short defined; - struct fdesc *next; -} *ftable[HASHSIZE]; - -/* func_use --- track uses and definitions of functions */ - -static void -func_use(name, how) -char *name; -enum defref how; -{ - struct fdesc *fp; - int len; - int ind; - - len = strlen(name); - ind = hash(name, len, HASHSIZE); - - for (fp = ftable[ind]; fp != NULL; fp = fp->next) { - if (strcmp(fp->name, name) == 0) { - if (how == FUNC_DEFINE) - fp->defined++; - else - fp->used++; - return; - } - } - - /* not in the table, fall through to allocate a new one */ - - emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use"); - memset(fp, '\0', sizeof(struct fdesc)); - emalloc(fp->name, char *, len + 1, "func_use"); - strcpy(fp->name, name); - if (how == FUNC_DEFINE) - fp->defined++; - else - fp->used++; - fp->next = ftable[ind]; - ftable[ind] = fp; -} - -/* check_funcs --- verify functions that are called but not defined */ - -static void -check_funcs() -{ - struct fdesc *fp, *next; - int i; - - for (i = 0; i < HASHSIZE; i++) { - for (fp = ftable[i]; fp != NULL; fp = fp->next) { -#ifdef REALLYMEAN - /* making this the default breaks old code. sigh. */ - if (fp->defined == 0) { - error( - "function `%s' called but never defined", fp->name); - errcount++; - } -#else - if (do_lint && fp->defined == 0) - warning( - "function `%s' called but never defined", fp->name); -#endif - if (do_lint && fp->used == 0) { - warning("function `%s' defined but never called", - fp->name); - } - } - } - - /* now let's free all the memory */ - for (i = 0; i < HASHSIZE; i++) { - for (fp = ftable[i]; fp != NULL; fp = next) { - next = fp->next; - free(fp->name); - free(fp); - } - } -} - -/* param_sanity --- look for parameters that are regexp constants */ - -static void -param_sanity(arglist) -NODE *arglist; -{ - NODE *argp, *arg; - int i; - - for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) { - arg = argp->lnode; - if (arg->type == Node_regex) - warning("regexp constant for parameter #%d yields boolean value", i); - } -} - -/* variable --- make sure NAME is in the symbol table */ - -NODE * -variable(name, can_free, type) -char *name; -int can_free; -NODETYPE type; -{ - register NODE *r; - static int env_loaded = FALSE; - - if (! env_loaded && STREQ(name, "ENVIRON")) { - load_environ(); - env_loaded = TRUE; - } - if ((r = lookup(name)) == NULL) - r = install(name, node(Nnull_string, type, (NODE *) NULL)); - else if (can_free) - free(name); - return r; -} - -/* mk_rexp --- make a regular expression constant */ - -static NODE * -mk_rexp(exp) -NODE *exp; -{ - NODE *n; - - if (exp->type == Node_regex) - return exp; - - getnode(n); - n->type = Node_regex; - n->re_exp = exp; - n->re_text = NULL; - n->re_reg = NULL; - n->re_flags = 0; - n->re_cnt = 1; - return n; -} - -/* isnoeffect --- when used as a statement, has no side effects */ - -/* - * To be completely general, we should recursively walk the parse - * tree, to make sure that all the subexpressions also have no effect. - * Instead, we just weaken the actual warning that's printed, up above - * in the grammar. - */ - -static int -isnoeffect(type) -NODETYPE type; -{ - switch (type) { - case Node_times: - case Node_quotient: - case Node_mod: - case Node_plus: - case Node_minus: - case Node_subscript: - case Node_concat: - case Node_exp: - case Node_unary_minus: - case Node_field_spec: - case Node_and: - case Node_or: - case Node_equal: - case Node_notequal: - case Node_less: - case Node_greater: - case Node_leq: - case Node_geq: - case Node_match: - case Node_nomatch: - case Node_not: - case Node_val: - case Node_in_array: - case Node_NF: - case Node_NR: - case Node_FNR: - case Node_FS: - case Node_RS: - case Node_FIELDWIDTHS: - case Node_IGNORECASE: - case Node_OFS: - case Node_ORS: - case Node_OFMT: - case Node_CONVFMT: - return TRUE; - default: - break; /* keeps gcc -Wall happy */ - } - - return FALSE; -} - -/* isassignable --- can this node be assigned to? */ - -static int -isassignable(n) -register NODE *n; -{ - switch (n->type) { - case Node_var: - case Node_FIELDWIDTHS: - case Node_RS: - case Node_FS: - case Node_FNR: - case Node_NR: - case Node_NF: - case Node_IGNORECASE: - case Node_OFMT: - case Node_CONVFMT: - case Node_ORS: - case Node_OFS: - case Node_field_spec: - case Node_subscript: - return TRUE; - case Node_param_list: - return ((n->flags & FUNC) == 0); /* ok if not func name */ - default: - break; /* keeps gcc -Wall happy */ - } - return FALSE; -} - -/* for debugging */ -NODE * -stopme(tree) -NODE *tree; -{ - return tmp_number((AWKNUM) 0.0); -} diff --git a/contrib/awk/config.h b/contrib/awk/config.h deleted file mode 100644 index c745db168550..000000000000 --- a/contrib/awk/config.h +++ /dev/null @@ -1,207 +0,0 @@ -/* config.h. Generated automatically by configure. */ -/* configh.in. Generated automatically from configure.in by autoheader. */ -/* - * acconfig.h -- configuration definitions for gawk. - */ - -/* - * Copyright (C) 1995-1997 the Free Software Foundation, Inc. - * - * This file is part of GAWK, the GNU implementation of the - * AWK Programming Language. - * - * GAWK is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GAWK is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* #undef _ALL_SOURCE */ -#endif - -/* Define if using alloca.c. */ -/* #undef C_ALLOCA */ - -/* Define if type char is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -/* #undef __CHAR_UNSIGNED__ */ -#endif - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. - This function is required for alloca.c support on those systems. */ -/* #undef CRAY_STACKSEG_END */ - -/* Define to the type of elements in the array set by `getgroups'. - Usually this is either `int' or `gid_t'. */ -#define GETGROUPS_T gid_t - -/* Define if the `getpgrp' function takes no argument. */ -#define GETPGRP_VOID 1 - -/* Define to `int' if <sys/types.h> doesn't define. */ -/* #undef gid_t */ - -/* Define if you have alloca, as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ -/* #undef HAVE_ALLOCA_H */ - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - -/* Define if you have a working `mmap' system call. */ -#define HAVE_MMAP 1 - -/* Define if your struct stat has st_blksize. */ -#define HAVE_ST_BLKSIZE 1 - -/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define if your struct tm has tm_zone. */ -#define HAVE_TM_ZONE 1 - -/* Define if you don't have tm_zone but do have the external array - tzname. */ -/* #undef HAVE_TZNAME */ - -/* Define if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - -/* Define if on MINIX. */ -/* #undef _MINIX */ - -/* Define to `int' if <sys/types.h> doesn't define. */ -/* #undef pid_t */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define to `unsigned' if <sys/types.h> doesn't define. */ -/* #undef size_t */ - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown - */ -/* #undef STACK_DIRECTION */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if your <sys/time.h> declares struct tm. */ -/* #undef TM_IN_SYS_TIME */ - -/* Define to `int' if <sys/types.h> doesn't define. */ -/* #undef uid_t */ - -#define HAVE_STRINGIZE 1 /* can use ANSI # operator in cpp */ -#define REGEX_MALLOC 1 /* use malloc instead of alloca in regex.c */ -#define SPRINTF_RET int /* return type of sprintf */ -/* #undef BITOPS */ /* bitwise ops (undocumented feature) */ -/* #undef NONDECDATA */ /* non-decimal input data (undocumented feature) */ - -/* Define if you have the fmod function. */ -#define HAVE_FMOD 1 - -/* Define if you have the getpagesize function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define if you have the madvise function. */ -#define HAVE_MADVISE 1 - -/* Define if you have the memcmp function. */ -#define HAVE_MEMCMP 1 - -/* Define if you have the memcpy function. */ -#define HAVE_MEMCPY 1 - -/* Define if you have the memset function. */ -#define HAVE_MEMSET 1 - -/* Define if you have the setlocale function. */ -#define HAVE_SETLOCALE 1 - -/* Define if you have the strchr function. */ -#define HAVE_STRCHR 1 - -/* Define if you have the strerror function. */ -#define HAVE_STRERROR 1 - -/* Define if you have the strftime function. */ -#define HAVE_STRFTIME 1 - -/* Define if you have the strncasecmp function. */ -#define HAVE_STRNCASECMP 1 - -/* Define if you have the strtod function. */ -#define HAVE_STRTOD 1 - -/* Define if you have the system function. */ -#define HAVE_SYSTEM 1 - -/* Define if you have the tzset function. */ -#define HAVE_TZSET 1 - -/* Define if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the <locale.h> header file. */ -#define HAVE_LOCALE_H 1 - -/* Define if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define if you have the <signum.h> header file. */ -/* #undef HAVE_SIGNUM_H */ - -/* Define if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the <strings.h> header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define if you have the m library (-lm). */ -#define HAVE_LIBM 1 - -#include <custom.h> /* overrides for stuff autoconf can't deal with */ diff --git a/contrib/awk/doc/awk.1 b/contrib/awk/doc/awk.1 deleted file mode 100644 index f15d4f1d692e..000000000000 --- a/contrib/awk/doc/awk.1 +++ /dev/null @@ -1,2627 +0,0 @@ -.ds PX \s-1POSIX\s+1 -.ds UX \s-1UNIX\s+1 -.ds AN \s-1ANSI\s+1 -.TH GAWK 1 "Apr 28 1999" "Free Software Foundation" "Utility Commands" -.SH NAME -gawk \- pattern scanning and processing language -.SH SYNOPSIS -.B gawk -[ POSIX or GNU style options ] -.B \-f -.I program-file -[ -.B \-\^\- -] file .\^.\^. -.br -.B gawk -[ POSIX or GNU style options ] -[ -.B \-\^\- -] -.I program-text -file .\^.\^. -.SH DESCRIPTION -.I Gawk -is the GNU Project's implementation of the AWK programming language. -It conforms to the definition of the language in -the \*(PX 1003.2 Command Language And Utilities Standard. -This version in turn is based on the description in -.IR "The AWK Programming Language" , -by Aho, Kernighan, and Weinberger, -with the additional features found in the System V Release 4 version -of \*(UX -.IR awk . -.I Gawk -also provides more recent Bell Labs -.I awk -extensions, and some GNU-specific extensions. -.PP -The command line consists of options to -.I gawk -itself, the AWK program text (if not supplied via the -.B \-f -or -.B \-\^\-file -options), and values to be made -available in the -.B ARGC -and -.B ARGV -pre-defined AWK variables. -.SH OPTION FORMAT -.PP -.I Gawk -options may be either the traditional \*(PX one letter options, -or the GNU style long options. \*(PX options start with a single ``\-'', -while long options start with ``\-\^\-''. -Long options are provided for both GNU-specific features and -for \*(PX mandated features. -.PP -Following the \*(PX standard, -.IR gawk -specific -options are supplied via arguments to the -.B \-W -option. Multiple -.B \-W -options may be supplied -Each -.B \-W -option has a corresponding long option, as detailed below. -Arguments to long options are either joined with the option -by an -.B = -sign, with no intervening spaces, or they may be provided in the -next command line argument. -Long options may be abbreviated, as long as the abbreviation -remains unique. -.SH OPTIONS -.PP -.I Gawk -accepts the following options. -.TP -.PD 0 -.BI \-F " fs" -.TP -.PD -.BI \-\^\-field-separator " fs" -Use -.I fs -for the input field separator (the value of the -.B FS -predefined -variable). -.TP -.PD 0 -\fB\-v\fI var\fB\^=\^\fIval\fR -.TP -.PD -\fB\-\^\-assign \fIvar\fB\^=\^\fIval\fR -Assign the value -.IR val , -to the variable -.IR var , -before execution of the program begins. -Such variable values are available to the -.B BEGIN -block of an AWK program. -.TP -.PD 0 -.BI \-f " program-file" -.TP -.PD -.BI \-\^\-file " program-file" -Read the AWK program source from the file -.IR program-file , -instead of from the first command line argument. -Multiple -.B \-f -(or -.BR \-\^\-file ) -options may be used. -.TP -.PD 0 -.BI \-mf " NNN" -.TP -.PD -.BI \-mr " NNN" -Set various memory limits to the value -.IR NNN . -The -.B f -flag sets the maximum number of fields, and the -.B r -flag sets the maximum record size. These two flags and the -.B \-m -option are from the Bell Labs research version of \*(UX -.IR awk . -They are ignored by -.IR gawk , -since -.I gawk -has no pre-defined limits. -.TP -.PD 0 -.B "\-W traditional" -.TP -.PD 0 -.B "\-W compat" -.TP -.PD 0 -.B \-\^\-traditional -.TP -.PD -.B \-\^\-compat -Run in -.I compatibility -mode. In compatibility mode, -.I gawk -behaves identically to \*(UX -.IR awk ; -none of the GNU-specific extensions are recognized. -The use of -.B \-\^\-traditional -is preferred over the other forms of this option. -See -.BR "GNU EXTENSIONS" , -below, for more information. -.TP -.PD 0 -.B "\-W copyleft" -.TP -.PD 0 -.B "\-W copyright" -.TP -.PD 0 -.B \-\^\-copyleft -.TP -.PD -.B \-\^\-copyright -Print the short version of the GNU copyright information message on -the standard output, and exits successfully. -.TP -.PD 0 -.B "\-W help" -.TP -.PD 0 -.B "\-W usage" -.TP -.PD 0 -.B \-\^\-help -.TP -.PD -.B \-\^\-usage -Print a relatively short summary of the available options on -the standard output. -(Per the -.IR "GNU Coding Standards" , -these options cause an immediate, successful exit.) -.TP -.PD 0 -.B "\-W lint" -.TP -.PD -.B \-\^\-lint -Provide warnings about constructs that are -dubious or non-portable to other AWK implementations. -.TP -.PD 0 -.B "\-W lint\-old" -.TP -.PD -.B \-\^\-lint\-old -Provide warnings about constructs that are -not portable to the original version of Unix -.IR awk . -.ig -.\" This option is left undocumented, on purpose. -.TP -.PD 0 -.B "\-W nostalgia" -.TP -.PD -.B \-\^\-nostalgia -Provide a moment of nostalgia for long time -.I awk -users. -.. -.TP -.PD 0 -.B "\-W posix" -.TP -.PD -.B \-\^\-posix -This turns on -.I compatibility -mode, with the following additional restrictions: -.RS -.TP \w'\(bu'u+1n -\(bu -.B \ex -escape sequences are not recognized. -.TP -\(bu -Only space and tab act as field separators when -.B FS -is set to a single space, newline does not. -.TP -\(bu -The synonym -.B func -for the keyword -.B function -is not recognized. -.TP -\(bu -The operators -.B ** -and -.B **= -cannot be used in place of -.B ^ -and -.BR ^= . -.TP -\(bu -The -.B fflush() -function is not available. -.RE -.TP -.PD 0 -.B "\-W re\-interval" -.TP -.PD -.B \-\^\-re\-interval -Enable the use of -.I "interval expressions" -in regular expression matching -(see -.BR "Regular Expressions" , -below). -Interval expressions were not traditionally available in the -AWK language. The POSIX standard added them, to make -.I awk -and -.I egrep -consistent with each other. -However, their use is likely -to break old AWK programs, so -.I gawk -only provides them if they are requested with this option, or when -.B \-\^\-posix -is specified. -.TP -.PD 0 -.BI "\-W source " program-text -.TP -.PD -.BI \-\^\-source " program-text" -Use -.I program-text -as AWK program source code. -This option allows the easy intermixing of library functions (used via the -.B \-f -and -.B \-\^\-file -options) with source code entered on the command line. -It is intended primarily for medium to large AWK programs used -in shell scripts. -.TP -.PD 0 -.B "\-W version" -.TP -.PD -.B \-\^\-version -Print version information for this particular copy of -.I gawk -on the standard output. -This is useful mainly for knowing if the current copy of -.I gawk -on your system -is up to date with respect to whatever the Free Software Foundation -is distributing. -This is also useful when reporting bugs. -(Per the -.IR "GNU Coding Standards" , -these options cause an immediate, successful exit.) -.TP -.B \-\^\- -Signal the end of options. This is useful to allow further arguments to the -AWK program itself to start with a ``\-''. -This is mainly for consistency with the argument parsing convention used -by most other \*(PX programs. -.PP -In compatibility mode, -any other options are flagged as illegal, but are otherwise ignored. -In normal operation, as long as program text has been supplied, unknown -options are passed on to the AWK program in the -.B ARGV -array for processing. This is particularly useful for running AWK -programs via the ``#!'' executable interpreter mechanism. -.SH AWK PROGRAM EXECUTION -.PP -An AWK program consists of a sequence of pattern-action statements -and optional function definitions. -.RS -.PP -\fIpattern\fB { \fIaction statements\fB }\fR -.br -\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements\fB }\fR -.RE -.PP -.I Gawk -first reads the program source from the -.IR program-file (s) -if specified, -from arguments to -.BR \-\^\-source , -or from the first non-option argument on the command line. -The -.B \-f -and -.B \-\^\-source -options may be used multiple times on the command line. -.I Gawk -will read the program text as if all the -.IR program-file s -and command line source texts -had been concatenated together. This is useful for building libraries -of AWK functions, without having to include them in each new AWK -program that uses them. It also provides the ability to mix library -functions with command line programs. -.PP -The environment variable -.B AWKPATH -specifies a search path to use when finding source files named with -the -.B \-f -option. If this variable does not exist, the default path is -\fB".:/usr/local/share/awk"\fR. -(The actual directory may vary, depending upon how -.I gawk -was built and installed.) -If a file name given to the -.B \-f -option contains a ``/'' character, no path search is performed. -.PP -.I Gawk -executes AWK programs in the following order. -First, -all variable assignments specified via the -.B \-v -option are performed. -Next, -.I gawk -compiles the program into an internal form. -Then, -.I gawk -executes the code in the -.B BEGIN -block(s) (if any), -and then proceeds to read -each file named in the -.B ARGV -array. -If there are no files named on the command line, -.I gawk -reads the standard input. -.PP -If a filename on the command line has the form -.IB var = val -it is treated as a variable assignment. The variable -.I var -will be assigned the value -.IR val . -(This happens after any -.B BEGIN -block(s) have been run.) -Command line variable assignment -is most useful for dynamically assigning values to the variables -AWK uses to control how input is broken into fields and records. It -is also useful for controlling state if multiple passes are needed over -a single data file. -.PP -If the value of a particular element of -.B ARGV -is empty (\fB""\fR), -.I gawk -skips over it. -.PP -For each record in the input, -.I gawk -tests to see if it matches any -.I pattern -in the AWK program. -For each pattern that the record matches, the associated -.I action -is executed. -The patterns are tested in the order they occur in the program. -.PP -Finally, after all the input is exhausted, -.I gawk -executes the code in the -.B END -block(s) (if any). -.SH VARIABLES, RECORDS AND FIELDS -AWK variables are dynamic; they come into existence when they are -first used. Their values are either floating-point numbers or strings, -or both, -depending upon how they are used. AWK also has one dimensional -arrays; arrays with multiple dimensions may be simulated. -Several pre-defined variables are set as a program -runs; these will be described as needed and summarized below. -.SS Records -Normally, records are separated by newline characters. You can control how -records are separated by assigning values to the built-in variable -.BR RS . -If -.B RS -is any single character, that character separates records. -Otherwise, -.B RS -is a regular expression. Text in the input that matches this -regular expression will separate the record. -However, in compatibility mode, -only the first character of its string -value is used for separating records. -If -.B RS -is set to the null string, then records are separated by -blank lines. -When -.B RS -is set to the null string, the newline character always acts as -a field separator, in addition to whatever value -.B FS -may have. -.SS Fields -.PP -As each input record is read, -.I gawk -splits the record into -.IR fields , -using the value of the -.B FS -variable as the field separator. -If -.B FS -is a single character, fields are separated by that character. -If -.B FS -is the null string, then each individual character becomes a -separate field. -Otherwise, -.B FS -is expected to be a full regular expression. -In the special case that -.B FS -is a single space, fields are separated -by runs of spaces and/or tabs and/or newlines. -(But see the discussion of -.BR \-\-posix , -below). -Note that the value of -.B IGNORECASE -(see below) will also affect how fields are split when -.B FS -is a regular expression, and how records are separated when -.B RS -is a regular expression. -.PP -If the -.B FIELDWIDTHS -variable is set to a space separated list of numbers, each field is -expected to have fixed width, and -.I gawk -will split up the record using the specified widths. The value of -.B FS -is ignored. -Assigning a new value to -.B FS -overrides the use of -.BR FIELDWIDTHS , -and restores the default behavior. -.PP -Each field in the input record may be referenced by its position, -.BR $1 , -.BR $2 , -and so on. -.B $0 -is the whole record. The value of a field may be assigned to as well. -Fields need not be referenced by constants: -.RS -.PP -.ft B -n = 5 -.br -print $n -.ft R -.RE -.PP -prints the fifth field in the input record. -The variable -.B NF -is set to the total number of fields in the input record. -.PP -References to non-existent fields (i.e. fields after -.BR $NF ) -produce the null-string. However, assigning to a non-existent field -(e.g., -.BR "$(NF+2) = 5" ) -will increase the value of -.BR NF , -create any intervening fields with the null string as their value, and -cause the value of -.B $0 -to be recomputed, with the fields being separated by the value of -.BR OFS . -References to negative numbered fields cause a fatal error. -Decrementing -.B NF -causes the values of fields past the new value to be lost, and the value of -.B $0 -to be recomputed, with the fields being separated by the value of -.BR OFS . -.SS Built-in Variables -.PP -.IR Gawk 's -built-in variables are: -.PP -.TP \w'\fBFIELDWIDTHS\fR'u+1n -.B ARGC -The number of command line arguments (does not include options to -.IR gawk , -or the program source). -.TP -.B ARGIND -The index in -.B ARGV -of the current file being processed. -.TP -.B ARGV -Array of command line arguments. The array is indexed from -0 to -.B ARGC -\- 1. -Dynamically changing the contents of -.B ARGV -can control the files used for data. -.TP -.B CONVFMT -The conversion format for numbers, \fB"%.6g"\fR, by default. -.TP -.B ENVIRON -An array containing the values of the current environment. -The array is indexed by the environment variables, each element being -the value of that variable (e.g., \fBENVIRON["HOME"]\fP might be -.BR /home/arnold ). -Changing this array does not affect the environment seen by programs which -.I gawk -spawns via redirection or the -.B system() -function. -(This may change in a future version of -.IR gawk .) -.\" but don't hold your breath... -.TP -.B ERRNO -If a system error occurs either doing a redirection for -.BR getline , -during a read for -.BR getline , -or during a -.BR close() , -then -.B ERRNO -will contain -a string describing the error. -.TP -.B FIELDWIDTHS -A white-space separated list of fieldwidths. When set, -.I gawk -parses the input into fields of fixed width, instead of using the -value of the -.B FS -variable as the field separator. -The fixed field width facility is still experimental; the -semantics may change as -.I gawk -evolves over time. -.TP -.B FILENAME -The name of the current input file. -If no files are specified on the command line, the value of -.B FILENAME -is ``\-''. -However, -.B FILENAME -is undefined inside the -.B BEGIN -block. -.TP -.B FNR -The input record number in the current input file. -.TP -.B FS -The input field separator, a space by default. See -.BR Fields , -above. -.TP -.B IGNORECASE -Controls the case-sensitivity of all regular expression -and string operations. If -.B IGNORECASE -has a non-zero value, then string comparisons and -pattern matching in rules, -field splitting with -.BR FS , -record separating with -.BR RS , -regular expression -matching with -.B ~ -and -.BR !~ , -and the -.BR gensub() , -.BR gsub() , -.BR index() , -.BR match() , -.BR split() , -and -.B sub() -pre-defined functions will all ignore case when doing regular expression -operations. Thus, if -.B IGNORECASE -is not equal to zero, -.B /aB/ -matches all of the strings \fB"ab"\fP, \fB"aB"\fP, \fB"Ab"\fP, -and \fB"AB"\fP. -As with all AWK variables, the initial value of -.B IGNORECASE -is zero, so all regular expression and string -operations are normally case-sensitive. -Under Unix, the full ISO 8859-1 Latin-1 character set is used -when ignoring case. -.B NOTE: -In versions of -.I gawk -prior to 3.0, -.B IGNORECASE -only affected regular expression operations. It now affects string -comparisons as well. -.TP -.B NF -The number of fields in the current input record. -.TP -.B NR -The total number of input records seen so far. -.TP -.B OFMT -The output format for numbers, \fB"%.6g"\fR, by default. -.TP -.B OFS -The output field separator, a space by default. -.TP -.B ORS -The output record separator, by default a newline. -.TP -.B RS -The input record separator, by default a newline. -.TP -.B RT -The record terminator. -.I Gawk -sets -.B RT -to the input text that matched the character or regular expression -specified by -.BR RS . -.TP -.B RSTART -The index of the first character matched by -.BR match() ; -0 if no match. -.TP -.B RLENGTH -The length of the string matched by -.BR match() ; -\-1 if no match. -.TP -.B SUBSEP -The character used to separate multiple subscripts in array -elements, by default \fB"\e034"\fR. -.SS Arrays -.PP -Arrays are subscripted with an expression between square brackets -.RB ( [ " and " ] ). -If the expression is an expression list -.RI ( expr ", " expr " ...)" -then the array subscript is a string consisting of the -concatenation of the (string) value of each expression, -separated by the value of the -.B SUBSEP -variable. -This facility is used to simulate multiply dimensioned -arrays. For example: -.PP -.RS -.ft B -i = "A";\^ j = "B";\^ k = "C" -.br -x[i, j, k] = "hello, world\en" -.ft R -.RE -.PP -assigns the string \fB"hello, world\en"\fR to the element of the array -.B x -which is indexed by the string \fB"A\e034B\e034C"\fR. All arrays in AWK -are associative, i.e. indexed by string values. -.PP -The special operator -.B in -may be used in an -.B if -or -.B while -statement to see if an array has an index consisting of a particular -value. -.PP -.RS -.ft B -.nf -if (val in array) - print array[val] -.fi -.ft -.RE -.PP -If the array has multiple subscripts, use -.BR "(i, j) in array" . -.PP -The -.B in -construct may also be used in a -.B for -loop to iterate over all the elements of an array. -.PP -An element may be deleted from an array using the -.B delete -statement. -The -.B delete -statement may also be used to delete the entire contents of an array, -just by specifying the array name without a subscript. -.SS Variable Typing And Conversion -.PP -Variables and fields -may be (floating point) numbers, or strings, or both. How the -value of a variable is interpreted depends upon its context. If used in -a numeric expression, it will be treated as a number, if used as a string -it will be treated as a string. -.PP -To force a variable to be treated as a number, add 0 to it; to force it -to be treated as a string, concatenate it with the null string. -.PP -When a string must be converted to a number, the conversion is accomplished -using -.IR atof (3). -A number is converted to a string by using the value of -.B CONVFMT -as a format string for -.IR sprintf (3), -with the numeric value of the variable as the argument. -However, even though all numbers in AWK are floating-point, -integral values are -.I always -converted as integers. Thus, given -.PP -.RS -.ft B -.nf -CONVFMT = "%2.2f" -a = 12 -b = a "" -.fi -.ft R -.RE -.PP -the variable -.B b -has a string value of \fB"12"\fR and not \fB"12.00"\fR. -.PP -.I Gawk -performs comparisons as follows: -If two variables are numeric, they are compared numerically. -If one value is numeric and the other has a string value that is a -``numeric string,'' then comparisons are also done numerically. -Otherwise, the numeric value is converted to a string and a string -comparison is performed. -Two strings are compared, of course, as strings. -According to the \*(PX standard, even if two strings are -numeric strings, a numeric comparison is performed. However, this is -clearly incorrect, and -.I gawk -does not do this. -.PP -Note that string constants, such as \fB"57"\fP, are -.I not -numeric strings, they are string constants. The idea of ``numeric string'' -only applies to fields, -.B getline -input, -.BR FILENAME , -.B ARGV -elements, -.B ENVIRON -elements and the elements of an array created by -.B split() -that are numeric strings. -The basic idea is that -.IR "user input" , -and only user input, that looks numeric, -should be treated that way. -.PP -Uninitialized variables have the numeric value 0 and the string value "" -(the null, or empty, string). -.SH PATTERNS AND ACTIONS -AWK is a line oriented language. The pattern comes first, and then the -action. Action statements are enclosed in -.B { -and -.BR } . -Either the pattern may be missing, or the action may be missing, but, -of course, not both. If the pattern is missing, the action will be -executed for every single record of input. -A missing action is equivalent to -.RS -.PP -.B "{ print }" -.RE -.PP -which prints the entire record. -.PP -Comments begin with the ``#'' character, and continue until the -end of the line. -Blank lines may be used to separate statements. -Normally, a statement ends with a newline, however, this is not the -case for lines ending in -a ``,'', -.BR { , -.BR ? , -.BR : , -.BR && , -or -.BR || . -Lines ending in -.B do -or -.B else -also have their statements automatically continued on the following line. -In other cases, a line can be continued by ending it with a ``\e'', -in which case the newline will be ignored. -.PP -Multiple statements may -be put on one line by separating them with a ``;''. -This applies to both the statements within the action part of a -pattern-action pair (the usual case), -and to the pattern-action statements themselves. -.SS Patterns -AWK patterns may be one of the following: -.PP -.RS -.nf -.B BEGIN -.B END -.BI / "regular expression" / -.I "relational expression" -.IB pattern " && " pattern -.IB pattern " || " pattern -.IB pattern " ? " pattern " : " pattern -.BI ( pattern ) -.BI ! " pattern" -.IB pattern1 ", " pattern2 -.fi -.RE -.PP -.B BEGIN -and -.B END -are two special kinds of patterns which are not tested against -the input. -The action parts of all -.B BEGIN -patterns are merged as if all the statements had -been written in a single -.B BEGIN -block. They are executed before any -of the input is read. Similarly, all the -.B END -blocks are merged, -and executed when all the input is exhausted (or when an -.B exit -statement is executed). -.B BEGIN -and -.B END -patterns cannot be combined with other patterns in pattern expressions. -.B BEGIN -and -.B END -patterns cannot have missing action parts. -.PP -For -.BI / "regular expression" / -patterns, the associated statement is executed for each input record that matches -the regular expression. -Regular expressions are the same as those in -.IR egrep (1), -and are summarized below. -.PP -A -.I "relational expression" -may use any of the operators defined below in the section on actions. -These generally test whether certain fields match certain regular expressions. -.PP -The -.BR && , -.BR || , -and -.B ! -operators are logical AND, logical OR, and logical NOT, respectively, as in C. -They do short-circuit evaluation, also as in C, and are used for combining -more primitive pattern expressions. As in most languages, parentheses -may be used to change the order of evaluation. -.PP -The -.B ?\^: -operator is like the same operator in C. If the first pattern is true -then the pattern used for testing is the second pattern, otherwise it is -the third. Only one of the second and third patterns is evaluated. -.PP -The -.IB pattern1 ", " pattern2 -form of an expression is called a -.IR "range pattern" . -It matches all input records starting with a record that matches -.IR pattern1 , -and continuing until a record that matches -.IR pattern2 , -inclusive. It does not combine with any other sort of pattern expression. -.SS Regular Expressions -Regular expressions are the extended kind found in -.IR egrep . -They are composed of characters as follows: -.TP \w'\fB[^\fIabc...\fB]\fR'u+2n -.I c -matches the non-metacharacter -.IR c . -.TP -.I \ec -matches the literal character -.IR c . -.TP -.B . -matches any character -.I including -newline. -.TP -.B ^ -matches the beginning of a string. -.TP -.B $ -matches the end of a string. -.TP -.BI [ abc... ] -character list, matches any of the characters -.IR abc... . -.TP -.BI [^ abc... ] -negated character list, matches any character except -.IR abc... . -.TP -.IB r1 | r2 -alternation: matches either -.I r1 -or -.IR r2 . -.TP -.I r1r2 -concatenation: matches -.IR r1 , -and then -.IR r2 . -.TP -.IB r + -matches one or more -.IR r 's. -.TP -.IB r * -matches zero or more -.IR r 's. -.TP -.IB r ? -matches zero or one -.IR r 's. -.TP -.BI ( r ) -grouping: matches -.IR r . -.TP -.PD 0 -.IB r { n } -.TP -.PD 0 -.IB r { n ,} -.TP -.PD -.IB r { n , m } -One or two numbers inside braces denote an -.IR "interval expression" . -If there is one number in the braces, the preceding regexp -.I r -is repeated -.I n -times. If there are two numbers separated by a comma, -.I r -is repeated -.I n -to -.I m -times. -If there is one number followed by a comma, then -.I r -is repeated at least -.I n -times. -.sp .5 -Interval expressions are only available if either -.B \-\^\-posix -or -.B \-\^\-re\-interval -is specified on the command line. -.TP -.B \ey -matches the empty string at either the beginning or the -end of a word. -.TP -.B \eB -matches the empty string within a word. -.TP -.B \e< -matches the empty string at the beginning of a word. -.TP -.B \e> -matches the empty string at the end of a word. -.TP -.B \ew -matches any word-constituent character (letter, digit, or underscore). -.TP -.B \eW -matches any character that is not word-constituent. -.TP -.B \e` -matches the empty string at the beginning of a buffer (string). -.TP -.B \e' -matches the empty string at the end of a buffer. -.PP -The escape sequences that are valid in string constants (see below) -are also legal in regular expressions. -.PP -.I "Character classes" -are a new feature introduced in the POSIX standard. -A character class is a special notation for describing -lists of characters that have a specific attribute, but where the -actual characters themselves can vary from country to country and/or -from character set to character set. For example, the notion of what -is an alphabetic character differs in the USA and in France. -.PP -A character class is only valid in a regexp -.I inside -the brackets of a character list. Character classes consist of -.BR [: , -a keyword denoting the class, and -.BR :] . -Here are the character -classes defined by the POSIX standard. -.TP -.B [:alnum:] -Alphanumeric characters. -.TP -.B [:alpha:] -Alphabetic characters. -.TP -.B [:blank:] -Space or tab characters. -.TP -.B [:cntrl:] -Control characters. -.TP -.B [:digit:] -Numeric characters. -.TP -.B [:graph:] -Characters that are both printable and visible. -(A space is printable, but not visible, while an -.B a -is both.) -.TP -.B [:lower:] -Lower-case alphabetic characters. -.TP -.B [:print:] -Printable characters (characters that are not control characters.) -.TP -.B [:punct:] -Punctuation characters (characters that are not letter, digits, -control characters, or space characters). -.TP -.B [:space:] -Space characters (such as space, tab, and formfeed, to name a few). -.TP -.B [:upper:] -Upper-case alphabetic characters. -.TP -.B [:xdigit:] -Characters that are hexadecimal digits. -.PP -For example, before the POSIX standard, to match alphanumeric -characters, you would have had to write -.BR /[A\-Za\-z0\-9]/ . -If your character set had other alphabetic characters in it, this would not -match them. With the POSIX character classes, you can write -.BR /[[:alnum:]]/ , -and this will match -.I all -the alphabetic and numeric characters in your character set. -.PP -Two additional special sequences can appear in character lists. -These apply to non-ASCII character sets, which can have single symbols -(called -.IR "collating elements" ) -that are represented with more than one -character, as well as several characters that are equivalent for -.IR collating , -or sorting, purposes. (E.g., in French, a plain ``e'' -and a grave-accented e\` are equivalent.) -.TP -Collating Symbols -A collating symbols is a multi-character collating element enclosed in -.B [. -and -.BR .] . -For example, if -.B ch -is a collating element, then -.B [[.ch.]] -is a regexp that matches this collating element, while -.B [ch] -is a regexp that matches either -.B c -or -.BR h . -.TP -Equivalence Classes -An equivalence class is a locale-specific name for a list of -characters that are equivalent. The name is enclosed in -.B [= -and -.BR =] . -For example, the name -.B e -might be used to represent all of -``e,'' ``e\`,'' and ``e\`.'' -In this case, -.B [[=e]] -is a regexp -that matches any of - .BR e , - .BR e\' , -or - .BR e\` . -.PP -These features are very valuable in non-English speaking locales. -The library functions that -.I gawk -uses for regular expression matching -currently only recognize POSIX character classes; they do not recognize -collating symbols or equivalence classes. -.PP -The -.BR \ey , -.BR \eB , -.BR \e< , -.BR \e> , -.BR \ew , -.BR \eW , -.BR \e` , -and -.B \e' -operators are specific to -.IR gawk ; -they are extensions based on facilities in the GNU regexp libraries. -.PP -The various command line options -control how -.I gawk -interprets characters in regexps. -.TP -No options -In the default case, -.I gawk -provide all the facilities of -POSIX regexps and the GNU regexp operators described above. -However, interval expressions are not supported. -.TP -.B \-\^\-posix -Only POSIX regexps are supported, the GNU operators are not special. -(E.g., -.B \ew -matches a literal -.BR w ). -Interval expressions are allowed. -.TP -.B \-\^\-traditional -Traditional Unix -.I awk -regexps are matched. The GNU operators -are not special, interval expressions are not available, and neither -are the POSIX character classes -.RB ( [[:alnum:]] -and so on). -Characters described by octal and hexadecimal escape sequences are -treated literally, even if they represent regexp metacharacters. -.TP -.B \-\^\-re\-interval -Allow interval expressions in regexps, even if -.B \-\^\-traditional -has been provided. -.SS Actions -Action statements are enclosed in braces, -.B { -and -.BR } . -Action statements consist of the usual assignment, conditional, and looping -statements found in most languages. The operators, control statements, -and input/output statements -available are patterned after those in C. -.SS Operators -.PP -The operators in AWK, in order of decreasing precedence, are -.PP -.TP "\w'\fB*= /= %= ^=\fR'u+1n" -.BR ( \&... ) -Grouping -.TP -.B $ -Field reference. -.TP -.B "++ \-\^\-" -Increment and decrement, both prefix and postfix. -.TP -.B ^ -Exponentiation (\fB**\fR may also be used, and \fB**=\fR for -the assignment operator). -.TP -.B "+ \- !" -Unary plus, unary minus, and logical negation. -.TP -.B "* / %" -Multiplication, division, and modulus. -.TP -.B "+ \-" -Addition and subtraction. -.TP -.I space -String concatenation. -.TP -.PD 0 -.B "< >" -.TP -.PD 0 -.B "<= >=" -.TP -.PD -.B "!= ==" -The regular relational operators. -.TP -.B "~ !~" -Regular expression match, negated match. -.B NOTE: -Do not use a constant regular expression -.RB ( /foo/ ) -on the left-hand side of a -.B ~ -or -.BR !~ . -Only use one on the right-hand side. The expression -.BI "/foo/ ~ " exp -has the same meaning as \fB(($0 ~ /foo/) ~ \fIexp\fB)\fR. -This is usually -.I not -what was intended. -.TP -.B in -Array membership. -.TP -.B && -Logical AND. -.TP -.B || -Logical OR. -.TP -.B ?: -The C conditional expression. This has the form -.IB expr1 " ? " expr2 " : " expr3\c -\&. If -.I expr1 -is true, the value of the expression is -.IR expr2 , -otherwise it is -.IR expr3 . -Only one of -.I expr2 -and -.I expr3 -is evaluated. -.TP -.PD 0 -.B "= += \-=" -.TP -.PD -.B "*= /= %= ^=" -Assignment. Both absolute assignment -.BI ( var " = " value ) -and operator-assignment (the other forms) are supported. -.SS Control Statements -.PP -The control statements are -as follows: -.PP -.RS -.nf -\fBif (\fIcondition\fB) \fIstatement\fR [ \fBelse\fI statement \fR] -\fBwhile (\fIcondition\fB) \fIstatement \fR -\fBdo \fIstatement \fBwhile (\fIcondition\fB)\fR -\fBfor (\fIexpr1\fB; \fIexpr2\fB; \fIexpr3\fB) \fIstatement\fR -\fBfor (\fIvar \fBin\fI array\fB) \fIstatement\fR -\fBbreak\fR -\fBcontinue\fR -\fBdelete \fIarray\^\fB[\^\fIindex\^\fB]\fR -\fBdelete \fIarray\^\fR -\fBexit\fR [ \fIexpression\fR ] -\fB{ \fIstatements \fB} -.fi -.RE -.SS "I/O Statements" -.PP -The input/output statements are as follows: -.PP -.TP "\w'\fBprintf \fIfmt, expr-list\fR'u+1n" -.BI close( file ) -Close file (or pipe, see below). -.TP -.B getline -Set -.B $0 -from next input record; set -.BR NF , -.BR NR , -.BR FNR . -.TP -.BI "getline <" file -Set -.B $0 -from next record of -.IR file ; -set -.BR NF . -.TP -.BI getline " var" -Set -.I var -from next input record; set -.BR NR , -.BR FNR . -.TP -.BI getline " var" " <" file -Set -.I var -from next record of -.IR file . -.TP -.B next -Stop processing the current input record. The next input record -is read and processing starts over with the first pattern in the -AWK program. If the end of the input data is reached, the -.B END -block(s), if any, are executed. -.TP -.B "nextfile" -Stop processing the current input file. The next input record read -comes from the next input file. -.B FILENAME -and -.B ARGIND -are updated, -.B FNR -is reset to 1, and processing starts over with the first pattern in the -AWK program. If the end of the input data is reached, the -.B END -block(s), if any, are executed. -.B NOTE: -Earlier versions of gawk used -.BR "next file" , -as two words. While this usage is still recognized, it generates a -warning message and will eventually be removed. -.TP -.B print -Prints the current record. -The output record is terminated with the value of the -.B ORS -variable. -.TP -.BI print " expr-list" -Prints expressions. -Each expression is separated by the value of the -.B OFS -variable. -The output record is terminated with the value of the -.B ORS -variable. -.TP -.BI print " expr-list" " >" file -Prints expressions on -.IR file . -Each expression is separated by the value of the -.B OFS -variable. The output record is terminated with the value of the -.B ORS -variable. -.TP -.BI printf " fmt, expr-list" -Format and print. -.TP -.BI printf " fmt, expr-list" " >" file -Format and print on -.IR file . -.TP -.BI system( cmd-line ) -Execute the command -.IR cmd-line , -and return the exit status. -(This may not be available on non-\*(PX systems.) -.TP -\&\fBfflush(\fR[\fIfile\^\fR]\fB)\fR -Flush any buffers associated with the open output file or pipe -.IR file . -If -.I file -is missing, then standard output is flushed. -If -.I file -is the null string, -then all open output files and pipes -have their buffers flushed. -.PP -Other input/output redirections are also allowed. For -.B print -and -.BR printf , -.BI >> file -appends output to the -.IR file , -while -.BI | " command" -writes on a pipe. -In a similar fashion, -.IB command " | getline" -pipes into -.BR getline . -The -.BR getline -command will return 0 on end of file, and \-1 on an error. -.SS The \fIprintf\fP\^ Statement -.PP -The AWK versions of the -.B printf -statement and -.B sprintf() -function -(see below) -accept the following conversion specification formats: -.TP -.B %c -An \s-1ASCII\s+1 character. -If the argument used for -.B %c -is numeric, it is treated as a character and printed. -Otherwise, the argument is assumed to be a string, and the only first -character of that string is printed. -.TP -.PD 0 -.B %d -.TP -.PD -.B %i -A decimal number (the integer part). -.TP -.PD 0 -.B %e -.TP -.PD -.B %E -A floating point number of the form -.BR [\-]d.dddddde[+\^\-]dd . -The -.B %E -format uses -.B E -instead of -.BR e . -.TP -.B %f -A floating point number of the form -.BR [\-]ddd.dddddd . -.TP -.PD 0 -.B %g -.TP -.PD -.B %G -Use -.B %e -or -.B %f -conversion, whichever is shorter, with nonsignificant zeros suppressed. -The -.B %G -format uses -.B %E -instead of -.BR %e . -.TP -.B %o -An unsigned octal number (again, an integer). -.TP -.B %s -A character string. -.TP -.PD 0 -.B %x -.TP -.PD -.B %X -An unsigned hexadecimal number (an integer). -.The -.B %X -format uses -.B ABCDEF -instead of -.BR abcdef . -.TP -.B %% -A single -.B % -character; no argument is converted. -.PP -There are optional, additional parameters that may lie between the -.B % -and the control letter: -.TP -.B \- -The expression should be left-justified within its field. -.TP -.I space -For numeric conversions, prefix positive values with a space, and -negative values with a minus sign. -.TP -.B + -The plus sign, used before the width modifier (see below), -says to always supply a sign for numeric conversions, even if the data -to be formatted is positive. The -.B + -overrides the space modifier. -.TP -.B # -Use an ``alternate form'' for certain control letters. -For -.BR %o , -supply a leading zero. -For -.BR %x , -and -.BR %X , -supply a leading -.BR 0x -or -.BR 0X -for -a nonzero result. -For -.BR %e , -.BR %E , -and -.BR %f , -the result will always contain a -decimal point. -For -.BR %g , -and -.BR %G , -trailing zeros are not removed from the result. -.TP -.B 0 -A leading -.B 0 -(zero) acts as a flag, that indicates output should be -padded with zeroes instead of spaces. -This applies even to non-numeric output formats. -This flag only has an effect when the field width is wider than the -value to be printed. -.TP -.I width -The field should be padded to this width. The field is normally padded -with spaces. If the -.B 0 -flag has been used, it is padded with zeroes. -.TP -.BI \&. prec -A number that specifies the precision to use when printing. -For the -.BR %e , -.BR %E , -and -.BR %f -formats, this specifies the -number of digits you want printed to the right of the decimal point. -For the -.BR %g , -and -.B %G -formats, it specifies the maximum number -of significant digits. For the -.BR %d , -.BR %o , -.BR %i , -.BR %u , -.BR %x , -and -.B %X -formats, it specifies the minimum number of -digits to print. For a string, it specifies the maximum number of -characters from the string that should be printed. -.PP -The dynamic -.I width -and -.I prec -capabilities of the \*(AN C -.B printf() -routines are supported. -A -.B * -in place of either the -.B width -or -.B prec -specifications will cause their values to be taken from -the argument list to -.B printf -or -.BR sprintf() . -.SS Special File Names -.PP -When doing I/O redirection from either -.B print -or -.B printf -into a file, -or via -.B getline -from a file, -.I gawk -recognizes certain special filenames internally. These filenames -allow access to open file descriptors inherited from -.IR gawk 's -parent process (usually the shell). -Other special filenames provide access to information about the running -.B gawk -process. -The filenames are: -.TP \w'\fB/dev/stdout\fR'u+1n -.B /dev/pid -Reading this file returns the process ID of the current process, -in decimal, terminated with a newline. -.TP -.B /dev/ppid -Reading this file returns the parent process ID of the current process, -in decimal, terminated with a newline. -.TP -.B /dev/pgrpid -Reading this file returns the process group ID of the current process, -in decimal, terminated with a newline. -.TP -.B /dev/user -Reading this file returns a single record terminated with a newline. -The fields are separated with spaces. -.B $1 -is the value of the -.IR getuid (2) -system call, -.B $2 -is the value of the -.IR geteuid (2) -system call, -.B $3 -is the value of the -.IR getgid (2) -system call, and -.B $4 -is the value of the -.IR getegid (2) -system call. -If there are any additional fields, they are the group IDs returned by -.IR getgroups (2). -Multiple groups may not be supported on all systems. -.TP -.B /dev/stdin -The standard input. -.TP -.B /dev/stdout -The standard output. -.TP -.B /dev/stderr -The standard error output. -.TP -.BI /dev/fd/\^ n -The file associated with the open file descriptor -.IR n . -.PP -These are particularly useful for error messages. For example: -.PP -.RS -.ft B -print "You blew it!" > "/dev/stderr" -.ft R -.RE -.PP -whereas you would otherwise have to use -.PP -.RS -.ft B -print "You blew it!" | "cat 1>&2" -.ft R -.RE -.PP -These file names may also be used on the command line to name data files. -.SS Numeric Functions -.PP -AWK has the following pre-defined arithmetic functions: -.PP -.TP \w'\fBsrand(\fR[\fIexpr\^\fR]\fB)\fR'u+1n -.BI atan2( y , " x" ) -returns the arctangent of -.I y/x -in radians. -.TP -.BI cos( expr ) -returns the cosine of -.IR expr , -which is in radians. -.TP -.BI exp( expr ) -the exponential function. -.TP -.BI int( expr ) -truncates to integer. -.TP -.BI log( expr ) -the natural logarithm function. -.TP -.B rand() -returns a random number between 0 and 1. -.TP -.BI sin( expr ) -returns the sine of -.IR expr , -which is in radians. -.TP -.BI sqrt( expr ) -the square root function. -.TP -\&\fBsrand(\fR[\fIexpr\^\fR]\fB)\fR -uses -.I expr -as a new seed for the random number generator. If no -.I expr -is provided, the time of day will be used. -The return value is the previous seed for the random -number generator. -.SS String Functions -.PP -.I Gawk -has the following pre-defined string functions: -.PP -.TP "\w'\fBsprintf(\^\fIfmt\fB\^, \fIexpr-list\^\fB)\fR'u+1n" -\fBgensub(\fIr\fB, \fIs\fB, \fIh \fR[\fB, \fIt\fR]\fB)\fR -search the target string -.I t -for matches of the regular expression -.IR r . -If -.I h -is a string beginning with -.B g -or -.BR G , -then replace all matches of -.I r -with -.IR s . -Otherwise, -.I h -is a number indicating which match of -.I r -to replace. -If no -.I t -is supplied, -.B $0 -is used instead. -Within the replacement text -.IR s , -the sequence -.BI \e n\fR, -where -.I n -is a digit from 1 to 9, may be used to indicate just the text that -matched the -.IR n 'th -parenthesized subexpression. The sequence -.B \e0 -represents the entire matched text, as does the character -.BR & . -Unlike -.B sub() -and -.BR gsub() , -the modified string is returned as the result of the function, -and the original target string is -.I not -changed. -.TP "\w'\fBsprintf(\^\fIfmt\fB\^, \fIexpr-list\^\fB)\fR'u+1n" -\fBgsub(\fIr\fB, \fIs \fR[\fB, \fIt\fR]\fB)\fR -for each substring matching the regular expression -.I r -in the string -.IR t , -substitute the string -.IR s , -and return the number of substitutions. -If -.I t -is not supplied, use -.BR $0 . -An -.B & -in the replacement text is replaced with the text that was actually matched. -Use -.B \e& -to get a literal -.BR & . -See -.I "AWK Language Programming" -for a fuller discussion of the rules for -.BR &'s -and backslashes in the replacement text of -.BR sub() , -.BR gsub() , -and -.BR gensub() . -.TP -.BI index( s , " t" ) -returns the index of the string -.I t -in the string -.IR s , -or 0 if -.I t -is not present. -.TP -\fBlength(\fR[\fIs\fR]\fB) -returns the length of the string -.IR s , -or the length of -.B $0 -if -.I s -is not supplied. -.TP -.BI match( s , " r" ) -returns the position in -.I s -where the regular expression -.I r -occurs, or 0 if -.I r -is not present, and sets the values of -.B RSTART -and -.BR RLENGTH . -.TP -\fBsplit(\fIs\fB, \fIa \fR[\fB, \fIr\fR]\fB)\fR -splits the string -.I s -into the array -.I a -on the regular expression -.IR r , -and returns the number of fields. If -.I r -is omitted, -.B FS -is used instead. -The array -.I a -is cleared first. -Splitting behaves identically to field splitting, described above. -.TP -.BI sprintf( fmt , " expr-list" ) -prints -.I expr-list -according to -.IR fmt , -and returns the resulting string. -.TP -\fBsub(\fIr\fB, \fIs \fR[\fB, \fIt\fR]\fB)\fR -just like -.BR gsub() , -but only the first matching substring is replaced. -.TP -\fBsubstr(\fIs\fB, \fIi \fR[\fB, \fIn\fR]\fB)\fR -returns the at most -.IR n -character -substring of -.I s -starting at -.IR i . -If -.I n -is omitted, the rest of -.I s -is used. -.TP -.BI tolower( str ) -returns a copy of the string -.IR str , -with all the upper-case characters in -.I str -translated to their corresponding lower-case counterparts. -Non-alphabetic characters are left unchanged. -.TP -.BI toupper( str ) -returns a copy of the string -.IR str , -with all the lower-case characters in -.I str -translated to their corresponding upper-case counterparts. -Non-alphabetic characters are left unchanged. -.SS Time Functions -.PP -Since one of the primary uses of AWK programs is processing log files -that contain time stamp information, -.I gawk -provides the following two functions for obtaining time stamps and -formatting them. -.PP -.TP "\w'\fBsystime()\fR'u+1n" -.B systime() -returns the current time of day as the number of seconds since the Epoch -(Midnight UTC, January 1, 1970 on \*(PX systems). -.TP -\fBstrftime(\fR[\fIformat \fR[\fB, \fItimestamp\fR]]\fB)\fR -formats -.I timestamp -according to the specification in -.IR format. -The -.I timestamp -should be of the same form as returned by -.BR systime() . -If -.I timestamp -is missing, the current time of day is used. -If -.I format -is missing, a default format equivalent to the output of -.IR date (1) -will be used. -See the specification for the -.B strftime() -function in \*(AN C for the format conversions that are -guaranteed to be available. -A public-domain version of -.IR strftime (3) -and a man page for it come with -.IR gawk ; -if that version was used to build -.IR gawk , -then all of the conversions described in that man page are available to -.IR gawk. -.SS String Constants -.PP -String constants in AWK are sequences of characters enclosed -between double quotes (\fB"\fR). Within strings, certain -.I "escape sequences" -are recognized, as in C. These are: -.PP -.TP \w'\fB\e\^\fIddd\fR'u+1n -.B \e\e -A literal backslash. -.TP -.B \ea -The ``alert'' character; usually the \s-1ASCII\s+1 \s-1BEL\s+1 character. -.TP -.B \eb -backspace. -.TP -.B \ef -form-feed. -.TP -.B \en -newline. -.TP -.B \er -carriage return. -.TP -.B \et -horizontal tab. -.TP -.B \ev -vertical tab. -.TP -.BI \ex "\^hex digits" -The character represented by the string of hexadecimal digits following -the -.BR \ex . -As in \*(AN C, all following hexadecimal digits are considered part of -the escape sequence. -(This feature should tell us something about language design by committee.) -E.g., \fB"\ex1B"\fR is the \s-1ASCII\s+1 \s-1ESC\s+1 (escape) character. -.TP -.BI \e ddd -The character represented by the 1-, 2-, or 3-digit sequence of octal -digits. E.g. \fB"\e033"\fR is the \s-1ASCII\s+1 \s-1ESC\s+1 (escape) character. -.TP -.BI \e c -The literal character -.IR c\^ . -.PP -The escape sequences may also be used inside constant regular expressions -(e.g., -.B "/[\ \et\ef\en\er\ev]/" -matches whitespace characters). -.PP -In compatibility mode, the characters represented by octal and -hexadecimal escape sequences are treated literally when used in -regexp constants. Thus, -.B /a\e52b/ -is equivalent to -.BR /a\e*b/ . -.SH FUNCTIONS -Functions in AWK are defined as follows: -.PP -.RS -\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements \fB}\fR -.RE -.PP -Functions are executed when they are called from within expressions -in either patterns or actions. Actual parameters supplied in the function -call are used to instantiate the formal parameters declared in the function. -Arrays are passed by reference, other variables are passed by value. -.PP -Since functions were not originally part of the AWK language, the provision -for local variables is rather clumsy: They are declared as extra parameters -in the parameter list. The convention is to separate local variables from -real parameters by extra spaces in the parameter list. For example: -.PP -.RS -.ft B -.nf -function f(p, q, a, b) # a & b are local -{ - \&..... -} - -/abc/ { ... ; f(1, 2) ; ... } -.fi -.ft R -.RE -.PP -The left parenthesis in a function call is required -to immediately follow the function name, -without any intervening white space. -This is to avoid a syntactic ambiguity with the concatenation operator. -This restriction does not apply to the built-in functions listed above. -.PP -Functions may call each other and may be recursive. -Function parameters used as local variables are initialized -to the null string and the number zero upon function invocation. -.PP -Use -.BI return " expr" -to return a value from a function. The return value is undefined if no -value is provided, or if the function returns by ``falling off'' the -end. -.PP -If -.B \-\^\-lint -has been provided, -.I gawk -will warn about calls to undefined functions at parse time, -instead of at run time. -Calling an undefined function at run time is a fatal error. -.PP -The word -.B func -may be used in place of -.BR function . -.SH EXAMPLES -.nf -Print and sort the login names of all users: - -.ft B - BEGIN { FS = ":" } - { print $1 | "sort" } - -.ft R -Count lines in a file: - -.ft B - { nlines++ } - END { print nlines } - -.ft R -Precede each line by its number in the file: - -.ft B - { print FNR, $0 } - -.ft R -Concatenate and line number (a variation on a theme): - -.ft B - { print NR, $0 } -.ft R -.fi -.SH SEE ALSO -.IR egrep (1), -.IR getpid (2), -.IR getppid (2), -.IR getpgrp (2), -.IR getuid (2), -.IR geteuid (2), -.IR getgid (2), -.IR getegid (2), -.IR getgroups (2) -.PP -.IR "The AWK Programming Language" , -Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger, -Addison-Wesley, 1988. ISBN 0-201-07981-X. -.PP -.IR "AWK Language Programming" , -Edition 1.0, published by the Free Software Foundation, 1995. -.SH POSIX COMPATIBILITY -A primary goal for -.I gawk -is compatibility with the \*(PX standard, as well as with the -latest version of \*(UX -.IR awk . -To this end, -.I gawk -incorporates the following user visible -features which are not described in the AWK book, -but are part of the Bell Labs version of -.IR awk , -and are in the \*(PX standard. -.PP -The -.B \-v -option for assigning variables before program execution starts is new. -The book indicates that command line variable assignment happens when -.I awk -would otherwise open the argument as a file, which is after the -.B BEGIN -block is executed. However, in earlier implementations, when such an -assignment appeared before any file names, the assignment would happen -.I before -the -.B BEGIN -block was run. Applications came to depend on this ``feature.'' -When -.I awk -was changed to match its documentation, this option was added to -accommodate applications that depended upon the old behavior. -(This feature was agreed upon by both the AT&T and GNU developers.) -.PP -The -.B \-W -option for implementation specific features is from the \*(PX standard. -.PP -When processing arguments, -.I gawk -uses the special option ``\fB\-\^\-\fP'' to signal the end of -arguments. -In compatibility mode, it will warn about, but otherwise ignore, -undefined options. -In normal operation, such arguments are passed on to the AWK program for -it to process. -.PP -The AWK book does not define the return value of -.BR srand() . -The \*(PX standard -has it return the seed it was using, to allow keeping track -of random number sequences. Therefore -.B srand() -in -.I gawk -also returns its current seed. -.PP -Other new features are: -The use of multiple -.B \-f -options (from MKS -.IR awk ); -the -.B ENVIRON -array; the -.BR \ea , -and -.BR \ev -escape sequences (done originally in -.I gawk -and fed back into AT&T's); the -.B tolower() -and -.B toupper() -built-in functions (from AT&T); and the \*(AN C conversion specifications in -.B printf -(done first in AT&T's version). -.SH GNU EXTENSIONS -.I Gawk -has a number of extensions to \*(PX -.IR awk . -They are described in this section. All the extensions described here -can be disabled by -invoking -.I gawk -with the -.B \-\^\-traditional -option. -.PP -The following features of -.I gawk -are not available in -\*(PX -.IR awk . -.RS -.TP \w'\(bu'u+1n -\(bu -The -.B \ex -escape sequence. -(Disabled with -.BR \-\^\-posix .) -.TP \w'\(bu'u+1n -\(bu -The -.B fflush() -function. -(Disabled with -.BR \-\^\-posix .) -.TP -\(bu -The -.BR systime(), -.BR strftime(), -and -.B gensub() -functions. -.TP -\(bu -The special file names available for I/O redirection are not recognized. -.TP -\(bu -The -.BR ARGIND , -.BR ERRNO , -and -.B RT -variables are not special. -.TP -\(bu -The -.B IGNORECASE -variable and its side-effects are not available. -.TP -\(bu -The -.B FIELDWIDTHS -variable and fixed-width field splitting. -.TP -\(bu -The use of -.B RS -as a regular expression. -.TP -\(bu -The ability to split out individual characters using the null string -as the value of -.BR FS , -and as the third argument to -.BR split() . -.TP -\(bu -No path search is performed for files named via the -.B \-f -option. Therefore the -.B AWKPATH -environment variable is not special. -.TP -\(bu -The use of -.B "nextfile" -to abandon processing of the current input file. -.TP -\(bu -The use of -.BI delete " array" -to delete the entire contents of an array. -.RE -.PP -The AWK book does not define the return value of the -.B close() -function. -.IR Gawk\^ 's -.B close() -returns the value from -.IR fclose (3), -or -.IR pclose (3), -when closing a file or pipe, respectively. -.PP -When -.I gawk -is invoked with the -.B \-\^\-traditional -option, -if the -.I fs -argument to the -.B \-F -option is ``t'', then -.B FS -will be set to the tab character. -Note that typing -.B "gawk \-F\et \&..." -simply causes the shell to quote the ``t,'', and does not pass -``\et'' to the -.B \-F -option. -Since this is a rather ugly special case, it is not the default behavior. -This behavior also does not occur if -.B \-\^\-posix -has been specified. -To really get a tab character as the field separator, it is best to use -quotes: -.BR "gawk \-F'\et' \&..." . -.ig -.PP -If -.I gawk -was compiled for debugging, it will -accept the following additional options: -.TP -.PD 0 -.B \-Wparsedebug -.TP -.PD -.B \-\^\-parsedebug -Turn on -.IR yacc (1) -or -.IR bison (1) -debugging output during program parsing. -This option should only be of interest to the -.I gawk -maintainers, and may not even be compiled into -.IR gawk . -.. -.SH HISTORICAL FEATURES -There are two features of historical AWK implementations that -.I gawk -supports. -First, it is possible to call the -.B length() -built-in function not only with no argument, but even without parentheses! -Thus, -.RS -.PP -.ft B -a = length # Holy Algol 60, Batman! -.ft R -.RE -.PP -is the same as either of -.RS -.PP -.ft B -a = length() -.br -a = length($0) -.ft R -.RE -.PP -This feature is marked as ``deprecated'' in the \*(PX standard, and -.I gawk -will issue a warning about its use if -.B \-\^\-lint -is specified on the command line. -.PP -The other feature is the use of either the -.B continue -or the -.B break -statements outside the body of a -.BR while , -.BR for , -or -.B do -loop. Traditional AWK implementations have treated such usage as -equivalent to the -.B next -statement. -.I Gawk -will support this usage if -.B \-\^\-traditional -has been specified. -.SH ENVIRONMENT VARIABLES -If -.B POSIXLY_CORRECT -exists in the environment, then -.I gawk -behaves exactly as if -.B \-\^\-posix -had been specified on the command line. -If -.B \-\^\-lint -has been specified, -.I gawk -will issue a warning message to this effect. -.PP -The -.B AWKPATH -environment variable can be used to provide a list of directories that -.I gawk -will search when looking for files named via the -.B \-f -and -.B \-\^\-file -options. -.SH BUGS -The -.B \-F -option is not necessary given the command line variable assignment feature; -it remains only for backwards compatibility. -.PP -If your system actually has support for -.B /dev/fd -and the associated -.BR /dev/stdin , -.BR /dev/stdout , -and -.B /dev/stderr -files, you may get different output from -.I gawk -than you would get on a system without those files. When -.I gawk -interprets these files internally, it synchronizes output to the standard -output with output to -.BR /dev/stdout , -while on a system with those files, the output is actually to different -open files. -Caveat Emptor. -.PP -Syntactically invalid single character programs tend to overflow -the parse stack, generating a rather unhelpful message. Such programs -are surprisingly difficult to diagnose in the completely general case, -and the effort to do so really is not worth it. -.SH VERSION INFORMATION -This man page documents -.IR gawk , -version 3.0.4. -.SH AUTHORS -The original version of \*(UX -.I awk -was designed and implemented by Alfred Aho, -Peter Weinberger, and Brian Kernighan of AT&T Bell Labs. Brian Kernighan -continues to maintain and enhance it. -.PP -Paul Rubin and Jay Fenlason, -of the Free Software Foundation, wrote -.IR gawk , -to be compatible with the original version of -.I awk -distributed in Seventh Edition \*(UX. -John Woods contributed a number of bug fixes. -David Trueman, with contributions -from Arnold Robbins, made -.I gawk -compatible with the new version of \*(UX -.IR awk . -Arnold Robbins is the current maintainer. -.PP -The initial DOS port was done by Conrad Kwok and Scott Garfinkle. -Scott Deifik is the current DOS maintainer. Pat Rankin did the -port to VMS, and Michal Jaegermann did the port to the Atari ST. -The port to OS/2 was done by Kai Uwe Rommel, with contributions and -help from Darrel Hankerson. Fred Fish supplied support for the Amiga. -.SH BUG REPORTS -If you find a bug in -.IR gawk , -please send electronic mail to -.BR bug-gnu-utils@gnu.org , -.I with -a carbon copy to -.BR arnold@gnu.org . -Please include your operating system and its revision, the version of -.IR gawk , -what C compiler you used to compile it, and a test program -and data that are as small as possible for reproducing the problem. -.PP -Before sending a bug report, please do two things. First, verify that -you have the latest version of -.IR gawk . -Many bugs (usually subtle ones) are fixed at each release, and if -yours is out of date, the problem may already have been solved. -Second, please read this man page and the reference manual carefully to -be sure that what you think is a bug really is, instead of just a quirk -in the language. -.PP -Whatever you do, do -.B NOT -post a bug report in -.BR comp.lang.awk . -While the -.I gawk -developers occasionally read this newsgroup, posting bug reports there -is an unreliable way to report bugs. Instead, please use the electronic mail -addresses given above. -.SH ACKNOWLEDGEMENTS -Brian Kernighan of Bell Labs -provided valuable assistance during testing and debugging. -We thank him. -.SH COPYING PERMISSIONS -Copyright \(co) 1996,97,98,99 Free Software Foundation, Inc. -.PP -Permission is granted to make and distribute verbatim copies of -this manual page provided the copyright notice and this permission -notice are preserved on all copies. -.ig -Permission is granted to process this file through troff and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual page). -.. -.PP -Permission is granted to copy and distribute modified versions of this -manual page under the conditions for verbatim copying, provided that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual page into another language, under the above conditions for -modified versions, except that this permission notice may be stated in -a translation approved by the Foundation. diff --git a/contrib/awk/missing.c b/contrib/awk/missing.c deleted file mode 100644 index 7494d7668c2b..000000000000 --- a/contrib/awk/missing.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Do all necessary includes here, so that we don't have to worry about - * overlapping includes in the files in missing.d. - */ -#include "awk.h" - - -#ifdef atarist -/* - * this will work with gcc compiler - for other compilers you may - * have to replace path separators in this file into backslashes - */ -#include "atari/stack.c" -#include "atari/tmpnam.c" -#endif /* atarist */ - -#ifndef HAVE_SYSTEM -#ifdef atarist -#include "atari/system.c" -#else -#include "missing/system.c" -#endif -#endif /* HAVE_SYSTEM */ - -#ifndef HAVE_MEMCMP -#include "missing/memcmp.c" -#endif /* HAVE_MEMCMP */ - -#ifndef HAVE_MEMCPY -#include "missing/memcpy.c" -#endif /* HAVE_MEMCPY */ - -#ifndef HAVE_MEMSET -#include "missing/memset.c" -#endif /* HAVE_MEMSET */ - -#ifndef HAVE_STRNCASECMP -#include "missing/strncasecmp.c" -#endif /* HAVE_STRCASE */ - -#ifndef HAVE_STRERROR -#include "missing/strerror.c" -#endif /* HAVE_STRERROR */ - -#ifndef HAVE_STRFTIME -#include "missing/strftime.c" -#endif /* HAVE_STRFTIME */ - -#ifndef HAVE_STRCHR -#include "missing/strchr.c" -#endif /* HAVE_STRCHR */ - -#ifndef HAVE_STRTOD -#include "missing/strtod.c" -#endif /* HAVE_STRTOD */ - -#ifndef HAVE_TZSET -#include "missing/tzset.c" -#endif /* HAVE_TZSET */ diff --git a/contrib/awk/patchlevel.h b/contrib/awk/patchlevel.h deleted file mode 100644 index e44bc0911df6..000000000000 --- a/contrib/awk/patchlevel.h +++ /dev/null @@ -1 +0,0 @@ -#define PATCHLEVEL 6 diff --git a/contrib/awk/test/Makefile b/contrib/awk/test/Makefile deleted file mode 100644 index 1a9168ef12cb..000000000000 --- a/contrib/awk/test/Makefile +++ /dev/null @@ -1,451 +0,0 @@ -# Generated automatically from Makefile.in by configure. -# Makefile for GNU Awk test suite. -# -# Copyright (C) 1988-1997 the Free Software Foundation, Inc. -# -# This file is part of GAWK, the GNU implementation of the -# AWK Programming Language. -# -# GAWK is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GAWK is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -SHELL = /bin/sh -AWK = ../gawk -CMP = cmp - -srcdir = . - -bigtest: basic unix-tests gawk.extensions - -basic: msg swaplns messages argarray longwrds \ - getline fstabplus compare arrayref rs fsrs rand \ - fsbs negexp asgext anchgsub splitargv awkpath nfset reparse \ - convfmt arrayparm paramdup nonl defref nofmtch litoct resplit \ - rswhite prmarscl sclforin sclifin intprec childin noeffect \ - numsubstr pcntplus prmreuse math fldchg fldchgnf reindops \ - sprintfc backgsub tweakfld clsflnam mmap8k fnarray \ - dynlj substr eofsplit prt1eval gsubasgn prtoeval gsubtest splitwht \ - back89 tradanch nlfldsep splitvar intest nfldstr nors fnarydel \ - noparms funstack clobber delarprm prdupval - -unix-tests: poundbang fflush getlnhd pipeio1 pipeio2 strftlng pid - -gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ - badargs strftime gensub gnureops reint nondec - -extra: regtest inftest - -poundbang:: - @cp $(AWK) /tmp/gawk && $(srcdir)/poundbang $(srcdir)/poundbang >_`basename $@` - @rm -f /tmp/gawk - $(CMP) $(srcdir)/poundbang.ok _`basename $@` && rm -f _`basename $@` - -msg:: - @echo 'Any output from "cmp" is bad news, although some differences' - @echo 'in floating point values are probably benign -- in particular,' - @echo 'some systems may omit a leading zero and the floating point' - @echo 'precision may lead to slightly different output in a few cases.' - -swaplns:: - @$(AWK) -f $(srcdir)/swaplns.awk $(srcdir)/swaplns.in >_$@ - $(CMP) $(srcdir)/swaplns.ok _$@ && rm -f _$@ - -messages:: - @$(AWK) -f $(srcdir)/messages.awk >out2 2>out3 - { $(CMP) $(srcdir)/out1.ok out1 && $(CMP) $(srcdir)/out2.ok out2 && \ - $(CMP) $(srcdir)/out3.ok out3 && rm -f out1 out2 out3; } || \ - { { test -d /dev/fd || test -d /proc/self/fd; } && \ - echo IT IS OK THAT THIS TEST FAILED; } - -argarray:: - @case $(srcdir) in \ - .) : ;; \ - *) cp $(srcdir)/argarray.in . ;; \ - esac - @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@ - $(CMP) $(srcdir)/argarray.ok _$@ && rm -f _$@ - -fstabplus:: - @echo '1 2' | $(AWK) -f $(srcdir)/fstabplus.awk >_$@ - $(CMP) $(srcdir)/fstabplus.ok _$@ && rm -f _$@ - -fsrs:: - @$(AWK) -f $(srcdir)/fsrs.awk $(srcdir)/fsrs.in >_$@ - $(CMP) $(srcdir)/fsrs.ok _$@ && rm -f _$@ - -igncfs:: - @$(AWK) -f $(srcdir)/igncfs.awk $(srcdir)/igncfs.in >_$@ - $(CMP) $(srcdir)/igncfs.ok _$@ && rm -f _$@ - -longwrds:: - @$(AWK) -f $(srcdir)/longwrds.awk $(srcdir)/manpage | sort >_$@ - $(CMP) $(srcdir)/longwrds.ok _$@ && rm -f _$@ - -fieldwdth:: - @echo '123456789' | $(AWK) -v FIELDWIDTHS="2 3 4" '{ print $$2}' >_$@ - $(CMP) $(srcdir)/fieldwdth.ok _$@ && rm -f _$@ - -ignrcase:: - @echo xYz | $(AWK) -v IGNORECASE=1 '{ sub(/y/, ""); print}' >_$@ - $(CMP) $(srcdir)/ignrcase.ok _$@ && rm -f _$@ - -regtest:: - @echo 'Some of the output from regtest is very system specific, do not' - @echo 'be distressed if your output differs from that distributed.' - @echo 'Manual inspection is called for.' - AWK=`pwd`/$(AWK) $(srcdir)/regtest - -posix:: - @echo '1:2,3 4' | $(AWK) -f $(srcdir)/posix.awk >_$@ - $(CMP) $(srcdir)/posix.ok _$@ && rm -f _$@ - -manyfiles:: - @rm -rf junk - @mkdir junk - @$(AWK) 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >_$@ - @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@ - @echo "This number better be 1 ->" | tr -d '\012' - @wc -l junk/* | $(AWK) '$$1 != 2' | wc -l - @rm -rf junk _$@ - -compare:: - @$(AWK) -f $(srcdir)/compare.awk 0 1 $(srcdir)/compare.in >_$@ - $(CMP) $(srcdir)/compare.ok _$@ && rm -f _$@ - -arrayref:: - @$(AWK) -f $(srcdir)/arrayref.awk >_$@ - $(CMP) $(srcdir)/arrayref.ok _$@ && rm -f _$@ - -rs:: - @$(AWK) -v RS="" '{ print $$1, $$2}' $(srcdir)/rs.in >_$@ - $(CMP) $(srcdir)/rs.ok _$@ && rm -f _$@ - -fsbs:: - @$(AWK) -v FS='\' '{ print $$1, $$2 }' $(srcdir)/fsbs.in >_$@ - $(CMP) $(srcdir)/fsbs.ok _$@ && rm -f _$@ - -inftest:: - @echo This test is very machine specific... - @$(AWK) -f $(srcdir)/inftest.awk >_$@ - $(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@ - -getline:: - @$(AWK) -f $(srcdir)/getline.awk $(srcdir)/getline.awk $(srcdir)/getline.awk >_$@ - $(CMP) $(srcdir)/getline.ok _$@ && rm -f _$@ - -rand:: - @$(AWK) -f $(srcdir)/rand.awk >_$@ - $(CMP) $(srcdir)/rand.ok _$@ && rm -f _$@ - -negexp:: - @$(AWK) 'BEGIN { a = -2; print 10^a }' >_$@ - $(CMP) $(srcdir)/negexp.ok _$@ && rm -f _$@ - -asgext:: - @$(AWK) -f $(srcdir)/asgext.awk $(srcdir)/asgext.in >_$@ - $(CMP) $(srcdir)/asgext.ok _$@ && rm -f _$@ - -anchgsub:: - @$(AWK) -f $(srcdir)/anchgsub.awk $(srcdir)/anchgsub.in >_$@ - $(CMP) $(srcdir)/anchgsub.ok _$@ && rm -f _$@ - -splitargv:: - @$(AWK) -f $(srcdir)/splitargv.awk $(srcdir)/splitargv.in >_$@ - $(CMP) $(srcdir)/splitargv.ok _$@ && rm -f _$@ - -awkpath:: - @AWKPATH="$(srcdir):$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@ - $(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@ - -nfset:: - @$(AWK) -f $(srcdir)/nfset.awk $(srcdir)/nfset.in >_$@ - $(CMP) $(srcdir)/nfset.ok _$@ && rm -f _$@ - -reparse:: - @$(AWK) -f $(srcdir)/reparse.awk $(srcdir)/reparse.in >_$@ - $(CMP) $(srcdir)/reparse.ok _$@ && rm -f _$@ - -argtest:: - @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@ - $(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@ - -badargs:: - @-$(AWK) -f 2>&1 | grep -v patchlevel >_$@ - $(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@ - -convfmt:: - @$(AWK) -f $(srcdir)/convfmt.awk >_$@ - $(CMP) $(srcdir)/convfmt.ok _$@ && rm -f _$@ - -arrayparm:: - @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/arrayparm.ok _$@ && rm -f _$@ - -paramdup:: - @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/paramdup.ok _$@ && rm -f _$@ - -nonl:: - @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1 - $(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@ - -defref:: - @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/defref.ok _$@ && rm -f _$@ - -nofmtch:: - @-AWKPATH=$(srcdir) $(AWK) --lint -f nofmtch.awk >_$@ 2>&1 - $(CMP) $(srcdir)/nofmtch.ok _$@ && rm -f _$@ - -strftime:: - : this test could fail on slow machines or on a second boundary, - : so if it does, double check the actual results - @LC_ALL=C; export LC_ALL; LANC=C; export LANG; \ - date | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; \ - print > "strftime.ok" ; \ - print strftime() > "'_$@'" }' - $(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0 - -litoct:: - @echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@ - $(CMP) $(srcdir)/litoct.ok _$@ && rm -f _$@ - -gensub:: - @$(AWK) -f $(srcdir)/gensub.awk $(srcdir)/gensub.in >_$@ - $(CMP) $(srcdir)/gensub.ok _$@ && rm -f _$@ - -resplit:: - @echo a:b:c d:e:f | $(AWK) '{ FS = ":"; $$0 = $$0; print $$2 }' > _$@ - $(CMP) $(srcdir)/resplit.ok _$@ && rm -f _$@ - -rswhite:: - @$(AWK) -f $(srcdir)/rswhite.awk $(srcdir)/rswhite.in > _$@ - $(CMP) $(srcdir)/rswhite.ok _$@ && rm -f _$@ - -prmarscl:: - @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/prmarscl.ok _$@ && rm -f _$@ - -sclforin:: - @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/sclforin.ok _$@ && rm -f _$@ - -sclifin:: - @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/sclifin.ok _$@ && rm -f _$@ - -intprec:: - @-$(AWK) -f $(srcdir)/intprec.awk > _$@ 2>&1 - $(CMP) $(srcdir)/intprec.ok _$@ && rm -f _$@ - -childin:: - @echo hi | $(AWK) 'BEGIN { "cat" | getline; print; close("cat") }' > _$@ - $(CMP) $(srcdir)/childin.ok _$@ && rm -f _$@ - -noeffect:: - @-AWKPATH=$(srcdir) $(AWK) --lint -f noeffect.awk > _$@ 2>&1 - $(CMP) $(srcdir)/noeffect.ok _$@ && rm -f _$@ - -numsubstr:: - @-AWKPATH=$(srcdir) $(AWK) -f numsubstr.awk $(srcdir)/numsubstr.in >_$@ - $(CMP) $(srcdir)/numsubstr.ok _$@ && rm -f _$@ - -gnureops:: - @$(AWK) -f $(srcdir)/gnureops.awk >_$@ - $(CMP) $(srcdir)/gnureops.ok _$@ && rm -f _$@ - -pcntplus:: - @$(AWK) -f $(srcdir)/pcntplus.awk >_$@ - $(CMP) $(srcdir)/pcntplus.ok _$@ && rm -f _$@ - -prmreuse:: - @$(AWK) -f $(srcdir)/prmreuse.awk >_$@ - $(CMP) $(srcdir)/prmreuse.ok _$@ && rm -f _$@ - -math:: - @$(AWK) -f $(srcdir)/math.awk >_$@ - $(CMP) $(srcdir)/math.ok _$@ && rm -f _$@ - -fflush:: - @$(srcdir)/fflush.sh >_$@ - $(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@ - -fldchg:: - @$(AWK) -f $(srcdir)/fldchg.awk $(srcdir)/fldchg.in >_$@ - $(CMP) $(srcdir)/fldchg.ok _$@ && rm -f _$@ - -fldchgnf:: - @$(AWK) -f $(srcdir)/fldchgnf.awk $(srcdir)/fldchgnf.in >_$@ - $(CMP) $(srcdir)/fldchgnf.ok _$@ && rm -f _$@ - -reindops:: - @$(AWK) -f $(srcdir)/reindops.awk $(srcdir)/reindops.in >_$@ - $(CMP) $(srcdir)/reindops.ok _$@ && rm -f _$@ - -sprintfc:: - @$(AWK) -f $(srcdir)/sprintfc.awk $(srcdir)/sprintfc.in >_$@ - $(CMP) $(srcdir)/sprintfc.ok _$@ && rm -f _$@ - -getlnhd:: - @$(AWK) -f $(srcdir)/getlnhd.awk >_$@ - $(CMP) $(srcdir)/getlnhd.ok _$@ && rm -f _$@ - -backgsub:: - @$(AWK) -f $(srcdir)/backgsub.awk $(srcdir)/backgsub.in >_$@ - $(CMP) $(srcdir)/backgsub.ok _$@ && rm -f _$@ - -tweakfld:: - @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@ - @rm -f errors.cleanup - $(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@ - -clsflnam:: - @$(AWK) -f $(srcdir)/clsflnam.awk $(srcdir)/clsflnam.in >_$@ - $(CMP) $(srcdir)/clsflnam.ok _$@ && rm -f _$@ - -mmap8k:: - @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@ - $(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@ - -fnarray:: - @-AWKPATH=$(srcdir) $(AWK) -f fnarray.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/fnarray.ok _$@ && rm -f _$@ - -dynlj:: - @$(AWK) -f $(srcdir)/dynlj.awk >_$@ - $(CMP) $(srcdir)/dynlj.ok _$@ && rm -f _$@ - -substr:: - @$(AWK) -f $(srcdir)/substr.awk >_$@ - $(CMP) $(srcdir)/substr.ok _$@ && rm -f _$@ - -eofsplit:: - @$(AWK) -f $(srcdir)/eofsplit.awk >_$@ - $(CMP) $(srcdir)/eofsplit.ok _$@ && rm -f _$@ - -prt1eval:: - @$(AWK) -f $(srcdir)/prt1eval.awk >_$@ - $(CMP) $(srcdir)/prt1eval.ok _$@ && rm -f _$@ - -gsubasgn:: - @-AWKPATH=$(srcdir) $(AWK) -f gsubasgn.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/gsubasgn.ok _$@ && rm -f _$@ - -prtoeval:: - @$(AWK) -f $(srcdir)/prtoeval.awk >_$@ - $(CMP) $(srcdir)/prtoeval.ok _$@ && rm -f _$@ - -gsubtest:: - @$(AWK) -f $(srcdir)/gsubtest.awk >_$@ - $(CMP) $(srcdir)/gsubtest.ok _$@ && rm -f _$@ - -splitwht:: - @$(AWK) -f $(srcdir)/splitwht.awk >_$@ - $(CMP) $(srcdir)/splitwht.ok _$@ && rm -f _$@ - -back89:: - @$(AWK) '/a\8b/' $(srcdir)/back89.in >_$@ - $(CMP) $(srcdir)/back89.ok _$@ && rm -f _$@ - -tradanch:: - @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@ - $(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@ - -nlfldsep:: - @$(AWK) -f $(srcdir)/nlfldsep.awk $(srcdir)/nlfldsep.in > _$@ - $(CMP) $(srcdir)/nlfldsep.ok _$@ && rm -f _$@ - -splitvar:: - @$(AWK) -f $(srcdir)/splitvar.awk $(srcdir)/splitvar.in >_$@ - $(CMP) $(srcdir)/splitvar.ok _$@ && rm -f _$@ - -intest:: - @$(AWK) -f $(srcdir)/intest.awk >_$@ - $(CMP) $(srcdir)/intest.ok _$@ && rm -f _$@ - -# AIX /bin/sh exec's the last command in a list, therefore issue a ":" -# command so that pid.sh is fork'ed as a child before being exec'ed. -pid:: - @AWKPATH=$(srcdir) AWK=$(AWK) $(SHELL) $(srcdir)/pid.sh $$$$ > _`basename $@` ; : - $(CMP) $(srcdir)/pid.ok _`basename $@` && rm -f _`basename $@` _`basename $@`.in - -strftlng:: - @TZ=UTC; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@ - @if $(CMP) -s $(srcdir)/strftlng.ok _$@ ; then : ; else \ - TZ=UTC0; export TZ; $(AWK) -f $(srcdir)/strftlng.awk >_$@ ; \ - fi - $(CMP) $(srcdir)/strftlng.ok _$@ && rm -f _$@ - -nfldstr:: - @echo | $(AWK) '$$1 == 0 { print "bug" }' > _$@ - $(CMP) $(srcdir)/nfldstr.ok _$@ && rm -f _$@ - -nors:: - @echo A B C D E | tr -d '\12' | $(AWK) '{ print $$NF }' - $(srcdir)/nors.in > _$@ - $(CMP) $(srcdir)/nors.ok _$@ && rm -f _$@ - -fnarydel:: - @$(AWK) -f $(srcdir)/fnarydel.awk >_$@ - $(CMP) $(srcdir)/fnarydel.ok _$@ && rm -f _$@ - -reint:: - @$(AWK) --re-interval -f $(srcdir)/reint.awk $(srcdir)/reint.in >_$@ - $(CMP) $(srcdir)/reint.ok _$@ && rm -f _$@ - -noparms:: - @-AWKPATH=$(srcdir) $(AWK) -f noparms.awk >_$@ 2>&1 || exit 0 - $(CMP) $(srcdir)/noparms.ok _$@ && rm -f _$@ - -pipeio1:: - @$(AWK) -f $(srcdir)/pipeio1.awk >_$@ - @rm -f test1 test2 - $(CMP) $(srcdir)/pipeio1.ok _$@ && rm -f _$@ - -pipeio2:: - @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@ - $(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@ - -funstack:: - @$(AWK) -f $(srcdir)/funstack.awk $(srcdir)/funstack.in >_$@ - $(CMP) $(srcdir)/funstack.ok _$@ && rm -f _$@ - -clobber:: - @$(AWK) -f $(srcdir)/clobber.awk >_$@ - $(CMP) $(srcdir)/clobber.ok seq && $(CMP) $(srcdir)/clobber.ok _$@ && rm -f _$@ - @rm -f seq - -delarprm:: - @$(AWK) -f $(srcdir)/delarprm.awk >_$@ - $(CMP) $(srcdir)/delarprm.ok _$@ && rm -f _$@ - -prdupval:: - @$(AWK) -f $(srcdir)/prdupval.awk $(srcdir)/prdupval.in >_$@ - $(CMP) $(srcdir)/prdupval.ok _$@ && rm -f _$@ - -nondec:: - @if grep BITOP ../config.h | grep define > /dev/null; \ - then \ - $(AWK) -f $(srcdir)/nondec.awk >_$@; \ - else \ - cp $(srcdir)/nondec.ok _$@; \ - fi - $(CMP) $(srcdir)/nondec.ok _$@ && rm -f _$@ - -clean: - rm -fr _* core junk out1 out2 out3 strftime.ok test1 test2 seq *~ - -distclean: clean - rm -f Makefile - -maintainer-clean: distclean diff --git a/contrib/awk/test/poundbang b/contrib/awk/test/poundbang deleted file mode 100755 index d60652e3ecf0..000000000000 --- a/contrib/awk/test/poundbang +++ /dev/null @@ -1,3 +0,0 @@ -#! /tmp/gawk -f - { ccount += length($0) } -END { printf "average line length is %2.4f\n", ccount/NR} diff --git a/contrib/awk/test/reg/exp.awk b/contrib/awk/test/reg/exp.awk deleted file mode 100644 index 4e707f891a77..000000000000 --- a/contrib/awk/test/reg/exp.awk +++ /dev/null @@ -1 +0,0 @@ -BEGIN { print exp(0), exp(1000000), exp(0.5) } diff --git a/contrib/awk/test/reg/exp.good b/contrib/awk/test/reg/exp.good deleted file mode 100644 index 07b88537dd81..000000000000 --- a/contrib/awk/test/reg/exp.good +++ /dev/null @@ -1,2 +0,0 @@ -1 gawk: reg/exp.awk:1: warning: exp argument 1e+06 is out of range -Inf 1.64872 diff --git a/contrib/awk/test/reg/exp.in b/contrib/awk/test/reg/exp.in deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/awk/test/reg/exp.in +++ /dev/null diff --git a/contrib/awk/test/reg/log.awk b/contrib/awk/test/reg/log.awk deleted file mode 100644 index bcae90b8132d..000000000000 --- a/contrib/awk/test/reg/log.awk +++ /dev/null @@ -1 +0,0 @@ -BEGIN { print log(0), log(-1), log(100) } diff --git a/contrib/awk/test/reg/log.good b/contrib/awk/test/reg/log.good deleted file mode 100644 index 857ab7703650..000000000000 --- a/contrib/awk/test/reg/log.good +++ /dev/null @@ -1,4 +0,0 @@ -log: SING error --Inf gawk: reg/log.awk:1: warning: log called with negative argument -1 -log: DOMAIN error -NaN 4.60517 diff --git a/contrib/awk/test/reg/log.in b/contrib/awk/test/reg/log.in deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/awk/test/reg/log.in +++ /dev/null diff --git a/contrib/awk/test/regtest b/contrib/awk/test/regtest deleted file mode 100755 index 72b0dbf9aa56..000000000000 --- a/contrib/awk/test/regtest +++ /dev/null @@ -1,18 +0,0 @@ -#! /bin/sh - -case "$AWK" in -"") AWK=../gawk ;; -esac -#AWK=${AWK:-../gawk} - -for i in reg/*.awk -do - it=`basename $i .awk` - $AWK -f $i <reg/$it.in >reg/$it.out 2>&1 - if cmp -s reg/$it.out reg/$it.good - then - rm -f reg/$it.out - else - echo "regtest: $it fails" - fi -done |