├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── api.md ├── awk.sln ├── awklib.vcxproj ├── awklib.vcxproj.filters ├── include ├── awk.h ├── awklib │ ├── awk.h │ └── err.h ├── node.h └── proto.h ├── libtest ├── libtest.cpp ├── libtest.vcxproj ├── libtest.vcxproj.filters └── tests │ ├── 10_field_expression.tst │ ├── 11_field_change.tst │ ├── 12_regexp_pattern.tst │ ├── 13_nf.tst │ ├── 14_forloop.tst │ ├── 15_diveq.tst │ ├── 16_field_change1.tst │ ├── 17_field_change2.tst │ ├── 18_array.tst │ ├── 19_array.tst │ ├── 1_grammar.tst │ ├── 1_printall.tst │ ├── 20_array.tst │ ├── 21_array.tst │ ├── 22_arith.tst │ ├── 23_arith.tst │ ├── 24_regexp_pattern.tst │ ├── 25_assert.tst │ ├── 25_rgexp_pattern.tst │ ├── 26_avg.tst │ ├── 27_field_change.tst │ ├── 28_filename.tst │ ├── 29_beginexit.tst │ ├── 2_printnr.tst │ ├── 30_beginnext.tst │ ├── 31_break.tst │ ├── 32_break.tst │ ├── 33_break.tst │ ├── 34_missing_field.tst │ ├── 35_builtins.tst │ ├── 36_cat.tst │ ├── 37_cat.tst │ ├── 38_cat.tst │ ├── 39_cmp.tst │ ├── 3_changefs.tst │ ├── 40_coerce.tst │ ├── 41_coerce.tst │ ├── 42_comment.tst │ ├── 43_comment.tst │ ├── 44_concat.tst │ ├── 45_cond.tst │ ├── 46_contin.tst │ ├── 47_count.tst │ ├── 48_crlf.tst │ ├── 49_acum.tst │ ├── 4_changeofs.tst │ ├── 50_fsofs.tst │ ├── 51_delete.tst │ ├── 52_delete.tst │ ├── 53_delete.tst │ ├── 54_delete.tst │ ├── 55_do.tst │ ├── 56_or_expr.tst │ ├── 57_else.tst │ ├── 58_exit.tst │ ├── 59_exit.tst │ ├── 5_concat.tst │ ├── 60_diveq_pattern.tst │ ├── 61_multiple_begin.tst │ ├── 62_nflvar.tst │ ├── 63_fun.tst │ ├── 64_funarg.tst │ ├── 64_recursive.tst │ ├── 65_funackermann.tst │ ├── 66_expconv.tst │ ├── 67_for.tst │ ├── 68_for.tst │ ├── 69_for.tst │ ├── 6_fieldassign.tst │ ├── 70_for.tst │ ├── 71_sqrt.tst │ ├── 72_expr.tst │ ├── 73_match.tst │ ├── 74_func.tst │ ├── 75_func.tst │ ├── 76_func.tst │ ├── 77_func.tst │ ├── 78_func.tst │ ├── 7_select.tst │ ├── 80_format4.tst │ ├── 81_func.tst │ ├── 82_func.tst │ ├── 83_func.tst │ ├── 84_func.tst │ ├── 85_func.tst │ ├── 86_factorial.tst │ ├── 87_fibbo.tst │ ├── 88_multidim.tst │ ├── 89_func.tst │ ├── 8_while.tst │ ├── 90_func.tst │ ├── 91_func.tst │ ├── 92_func.tst │ ├── 93_vf.tst │ ├── 94_vf.tst │ ├── 95_vf.tst │ ├── 96_vf.tst │ ├── 97_set.tst │ ├── 98_set.tst │ ├── 99_set.tst │ └── 9_patmatch.tst ├── make_release.bat ├── make_release.proj ├── mklinks.bat ├── samples ├── interp │ ├── interp.cpp │ ├── interp.vcxproj │ └── interp.vcxproj.filters └── wc │ ├── wc.cpp │ ├── wc.vcxproj │ └── wc.vcxproj.filters ├── src ├── array.cpp ├── awkgram.y ├── b.cpp ├── cell.cpp ├── interp.cpp ├── lex.cpp ├── lib.cpp ├── libmain.cpp ├── parse.cpp ├── run.cpp └── tran.cpp └── yacc_compile.bat /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | *.user 3 | src/ytab.cpp 4 | src/ytab.h 5 | exe/ 6 | o/ 7 | lib/ 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Mircea Neacsu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | /**************************************************************** 24 | Copyright (C) Lucent Technologies 1997 25 | All Rights Reserved 26 | 27 | Permission to use, copy, modify, and distribute this software and 28 | its documentation for any purpose and without fee is hereby 29 | granted, provided that the above copyright notice appear in all 30 | copies and that both that the copyright notice and this 31 | permission notice and warranty disclaimer appear in supporting 32 | documentation, and that the name Lucent Technologies or any of 33 | its entities not be used in advertising or publicity pertaining 34 | to distribution of the software without specific, written prior 35 | permission. 36 | 37 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 38 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 39 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 40 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 41 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 42 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 44 | THIS SOFTWARE. 45 | ****************************************************************/ 46 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # /**************************************************************** 2 | # Copyright (C) Lucent Technologies 1997 3 | # All Rights Reserved 4 | # 5 | # Permission to use, copy, modify, and distribute this software and 6 | # its documentation for any purpose and without fee is hereby 7 | # granted, provided that the above copyright notice appear in all 8 | # copies and that both that the copyright notice and this 9 | # permission notice and warranty disclaimer appear in supporting 10 | # documentation, and that the name Lucent Technologies or any of 11 | # its entities not be used in advertising or publicity pertaining 12 | # to distribution of the software without specific, written prior 13 | # permission. 14 | # 15 | # LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | # IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | # SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | # THIS SOFTWARE. 23 | # ****************************************************************/ 24 | 25 | # default architecture 26 | ifndef ARCH 27 | ARCH = x64 28 | endif 29 | 30 | # compiler(s) 31 | CXX := g++ 32 | CPPFLAGS := -std=c++11 -I include/ -Wall -pedantic 33 | 34 | CC := gcc 35 | CFLAGS := -I include/ -Wall -pedantic 36 | 37 | # yacc options. pick one; this varies a lot by system. 38 | #YFLAGS = -d -S 39 | YACC = bison -d -y 40 | #YACC = yacc -d 41 | # -S uses sprintf in yacc parser instead of sprint 42 | 43 | # output folders 44 | OBJDIR := o/awk 45 | LIBDIR := lib 46 | 47 | ifeq ($(ARCH), x64) 48 | OBJDIR := $(OBJDIR)/x64 49 | LIBDIR := $(LIBDIR)/x64 50 | else 51 | OBJDIR := $(OBJDIR)/x86 52 | LIBDIR := $(LIBDIR)/x86 53 | CPPFLAGS += -m32 54 | CFLAGS += -m32 55 | endif 56 | 57 | ifdef _DEBUG 58 | OBJDIR := $(OBJDIR)/Debug 59 | LIBDIR := $(LIBDIR)/Debug 60 | CPPFLAGS += -g -D_DEBUG=$(_DEBUG) -DYYDEBUG 61 | CFLAGS += -g -D_DEBUG=$(_DEBUG) -DYYDEBUG 62 | else 63 | CPPFLAGS += -O3 -DNDEBUG 64 | CFLAGS += -O3 -DNDEBUG 65 | OBJDIR := $(OBJDIR)/Release 66 | LIBDIR := $(LIBDIR)/Release 67 | endif 68 | 69 | # name of output library 70 | LIB = $(LIBDIR)/libawk.a 71 | 72 | OFILES = b.o lex.o lib.o libmain.o parse.o run.o tran.o ytab.o 73 | 74 | OBJS = $(addprefix $(OBJDIR)/,$(OFILES)) 75 | 76 | all: $(LIB) 77 | 78 | # AWK library target 79 | $(LIB): | $(LIBDIR) 80 | 81 | $(LIB): $(OBJS) 82 | ar rcs $@ $^ 83 | 84 | # Object modules 85 | $(OBJS) : | $(OBJDIR) 86 | 87 | $(LIBDIR) $(OBJDIR): 88 | mkdir -p $@ 89 | 90 | # Grammar files 91 | ytab.h ytab.cpp: awkgram.y awk.h proto.h 92 | $(YACC) $(YFLAGS) -o ytab.cpp $< 93 | mv ytab.hpp ytab.h 94 | 95 | $(OBJDIR)/%.o: %.cpp proto.h ytab.h awk.h 96 | $(CXX) $(CPPFLAGS) -c -o $@ $< 97 | 98 | # test program 99 | libtest/test1: libtest/libtest.cpp $(LIB) 100 | $(CXX) $(CPPFLAGS) -o $@ -L $(LIBDIR)/ $< -lutpp -lawk 101 | 102 | # Other stuff 103 | clean: 104 | rm -f *.o *.obj maketab maketab.exe *.bb *.bbg *.da *.gcov *.gcno *.gcda ytab.* 105 | 106 | cleaner: 107 | rm -f a.out *.o *.obj maketab maketab.exe *.bb *.bbg *.da *.gcov *.gcno *.gcda 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded AWK Interpreter 2 | 3 | Copyright (c) 2019-2021 Mircea Neacsu 4 | 5 | This library is an AWK interpreter that can be embedded in C/C++ 6 | programs. The code is based on the [One True AWK](https://github.com/onetrueawk/awk) 7 | code. 8 | 9 | ## Description ## 10 | The library allows you to build and run an AWK interpreter in your C/C++ 11 | program using only a few function calls. The AWK code can call external functions 12 | provided by your C program and, conversely, the C code can access AWK variables. 13 | 14 | Here is an example of a simple word counting application: 15 | ````C++ 16 | #include 17 | 18 | int main (int argc, char **argv) 19 | { 20 | AWKINTERP* interp = awk_init (NULL); 21 | awk_setprog (interp, R"( 22 | {wc += NF; bc += length($0)}\ 23 | END {print NR, wc, bc, ARGV[1]})"; 24 | awk_compile (interp); 25 | if (argc > 1) 26 | awk_addarg (interp, argv[1]); 27 | awk_exec (interp); 28 | awk_end (interp); 29 | } 30 | ```` 31 | The program produces an output similar to the 'wc' utility. 32 | 33 | See the [API document](api.md) for details. 34 | 35 | ## Contents ## 36 | - __awklib__ - the AWK library 37 | - __libtest__ - library test suite 38 | - __testdir__ - tests for stand-alone interpreter (and by extension for the AWK library) 39 | - __samples__ - various sample applications: 40 | - __wc__ - Word counting application shown above 41 | - __interp__ - Stand-alone AWK interpreter using the AWK library 42 | 43 | ## Building ## 44 | You need a YACC or bison compiler to compile the AWK grammar. The library itself 45 | doesn't have any other dependencies. 46 | 47 | Edit and run the _makelinks.bat_ file to create the required symbolic links 48 | before building the project. 49 | 50 | The library test suite requires the 51 | [UTPP test framework](https://bitbucket.org/neacsum/utpp) 52 | 53 | ## Installation ## 54 | All projects have been tested under Visual Studio 2019. 55 | 56 | ## Contributing ## 57 | Contributors are welcome. Currently version 2 is in the making with important enhancements. 58 | 59 | For style rules please consult my [style guide](https://gist.github.com/neacsum/2abf84e818cf3fe06fe73a7640bf4703). 60 | 61 | ## Development Notes ## 62 | ### Version 1 ### 63 | When doing this project I had the definite sensation of touching a piece of 64 | computer science history. Just the AWK name invokes, in my mind, revered giants 65 | of this field (my first book on compilers was Aho and Ullman 'green dragon book'). 66 | 67 | As such, I've tried to touch the code as little as possible, choosing only to wrap 68 | existing code in the high level library functions. Some areas however had to be 69 | changed more extensively. 70 | 71 | Function call mechanism has been almost completely rewritten. It needed to be 72 | enhanced to allow for external function calls. At the same time I dissolved 73 | the function call stack into the C program stack. 74 | 75 | In many cases allocated memory was not released. The original code was 76 | for a stand-alone program that has the benefit of an operating system doing 77 | cleanup when the program finishes. Meanwhile an embedded interpreter 78 | can be invoked many times so allocated memory has to be released. 79 | 80 | I would have liked to maintain the project as pure C code. Unfortunately error 81 | handling restrictions forced me to move to C++. In a stand-alone program, 82 | exiting abruptly when an error condition is encountered is perfectly OK. 83 | When this is converted to a function call, the function has to return (with an 84 | error code indication). The simplest solution that preserved most of the 85 | original code was to wrap the code in try-catch blocks. 86 | 87 | ### Version 2 ### 88 | After spending more time with this project, I discovered a number of inconveniences derived from the original purpose of the code base (it was a standalone program) or from its age. In this version I gave up on any pretense that this is anything but C++ code. Here is a list of what has been addressed so far in version 2: 89 | - Inability to reuse a compiled AWK script with different input data. 90 | - Lack of thread safety. This is still somewhat of a work in progress. Currently the the whole API is protected by a `awk_in_use` mutex. Future versions should have a more fine grained mechanism. 91 | - Regular expression machinery (in b.cpp file) was replaced with `std::regex` objects 92 | - Most memory management moved to `new/delete` operators from `malloc/free`. 93 | - True multidimensional arrays similar to [arrays of arrays](https://www.gnu.org/software/gawk/manual/html_node/Arrays-of-Arrays.html) in *gawk*. I didn't really _need_ those but the change in grammar, required to implement them, was so small that I couldn't resist :) 94 | - Much expanded testing (see `libtest` project) infrastructure. Apart from API tests, most tests (over 100 of them at last count) were taken from the One True AWK project. 95 | 96 | The API has remained largely unchanged. Only the `awk_err` function takes an additional pointer to interpreter parameters. 97 | 98 | -------------------------------------------------------------------------------- /awk.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31624.102 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "awklib", "awklib.vcxproj", "{DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtest", "libtest\libtest.vcxproj", "{12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} = {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "interp", "samples\interp\interp.vcxproj", "{398F290F-49A7-498A-9DD2-AE6235E37995}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} = {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} 16 | EndProjectSection 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wc", "samples\wc\wc.vcxproj", "{E615F757-7F86-4A97-AB3C-4D9E23EBC02C}" 19 | ProjectSection(ProjectDependencies) = postProject 20 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} = {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} 21 | EndProjectSection 22 | EndProject 23 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A991355-D633-4FC5-931F-4489FFF464FC}" 24 | ProjectSection(SolutionItems) = preProject 25 | api.md = api.md 26 | README.md = README.md 27 | EndProjectSection 28 | EndProject 29 | Global 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|x64 = Debug|x64 32 | Debug|x86 = Debug|x86 33 | Release|x64 = Release|x64 34 | Release|x86 = Release|x86 35 | EndGlobalSection 36 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 37 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Debug|x64.ActiveCfg = Debug|x64 38 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Debug|x64.Build.0 = Debug|x64 39 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Debug|x86.ActiveCfg = Debug|Win32 40 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Debug|x86.Build.0 = Debug|Win32 41 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Release|x64.ActiveCfg = Release|x64 42 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Release|x64.Build.0 = Release|x64 43 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Release|x86.ActiveCfg = Release|Win32 44 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0}.Release|x86.Build.0 = Release|Win32 45 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Debug|x64.ActiveCfg = Debug|x64 46 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Debug|x64.Build.0 = Debug|x64 47 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Debug|x86.ActiveCfg = Debug|Win32 48 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Debug|x86.Build.0 = Debug|Win32 49 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Release|x64.ActiveCfg = Release|x64 50 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Release|x64.Build.0 = Release|x64 51 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Release|x86.ActiveCfg = Release|Win32 52 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3}.Release|x86.Build.0 = Release|Win32 53 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Debug|x64.ActiveCfg = Debug|x64 54 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Debug|x64.Build.0 = Debug|x64 55 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Debug|x86.ActiveCfg = Debug|Win32 56 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Debug|x86.Build.0 = Debug|Win32 57 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Release|x64.ActiveCfg = Release|x64 58 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Release|x64.Build.0 = Release|x64 59 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Release|x86.ActiveCfg = Release|Win32 60 | {398F290F-49A7-498A-9DD2-AE6235E37995}.Release|x86.Build.0 = Release|Win32 61 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Debug|x64.ActiveCfg = Debug|x64 62 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Debug|x64.Build.0 = Debug|x64 63 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Debug|x86.ActiveCfg = Debug|Win32 64 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Debug|x86.Build.0 = Debug|Win32 65 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Release|x64.ActiveCfg = Release|x64 66 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Release|x64.Build.0 = Release|x64 67 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Release|x86.ActiveCfg = Release|Win32 68 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C}.Release|x86.Build.0 = Release|Win32 69 | EndGlobalSection 70 | GlobalSection(SolutionProperties) = preSolution 71 | HideSolutionNode = FALSE 72 | EndGlobalSection 73 | GlobalSection(ExtensibilityGlobals) = postSolution 74 | SolutionGuid = {F454734B-3BA9-4BE3-94E7-46AD7D9BDBA9} 75 | EndGlobalSection 76 | EndGlobal 77 | -------------------------------------------------------------------------------- /awklib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {DCE89B2F-59F8-4912-AA40-CA68A1AD1FE0} 24 | Win32Proj 25 | awklib 26 | 10.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | true 38 | v142 39 | Unicode 40 | 41 | 42 | StaticLibrary 43 | false 44 | v142 45 | true 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 76 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 77 | 78 | 79 | true 80 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 81 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 82 | 83 | 84 | false 85 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 86 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 87 | 88 | 89 | false 90 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 91 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 92 | 93 | 94 | 95 | Level3 96 | Disabled 97 | YYDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)include 100 | 101 | 102 | true 103 | Console 104 | 105 | 106 | 107 | 108 | Level3 109 | Disabled 110 | YYDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 111 | true 112 | $(SolutionDir)include 113 | 114 | 115 | true 116 | Console 117 | 118 | 119 | 120 | 121 | Level3 122 | MaxSpeed 123 | true 124 | true 125 | _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) 126 | true 127 | $(SolutionDir)include 128 | 129 | 130 | true 131 | true 132 | true 133 | Console 134 | 135 | 136 | 137 | 138 | Level3 139 | MaxSpeed 140 | true 141 | true 142 | _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) 143 | true 144 | $(SolutionDir)include 145 | 146 | 147 | true 148 | true 149 | true 150 | Console 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | Document 176 | yacc_compile.bat 177 | yacc_compile.bat 178 | yacc_compile.bat 179 | yacc_compile.bat 180 | Compiling grammar 181 | Compiling grammar 182 | Compiling grammar 183 | Compiling grammar 184 | src\ytab.h;src\ytab.cpp 185 | src\ytab.h;src\ytab.cpp 186 | src\ytab.h;src\ytab.cpp 187 | src\ytab.h;src\ytab.cpp 188 | false 189 | false 190 | false 191 | false 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /awklib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | 49 | 50 | Header Files 51 | 52 | 53 | Header Files 54 | 55 | 56 | Header Files 57 | 58 | 59 | Header Files 60 | 61 | 62 | Header Files 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /include/awk.h: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | #pragma once 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | typedef double Awkfloat; 33 | 34 | #define xfree(a) { if ((a) != NULL) { free((void *) (a)); (a) = NULL; } } 35 | #define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf */ 36 | 37 | int errprintf (const char *fmt, ...); 38 | #ifdef NDEBUG 39 | /* errprintf should be optimized out of existence */ 40 | # define dprintf 1? 0 : errprintf 41 | #else 42 | extern int dbg; 43 | #define dprintf (dbg==0)? 0 : errprintf 44 | #define YYDBGOUT (dbg<=2)? 0 : errprintf 45 | #endif 46 | 47 | #define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ 48 | #define NSYMTAB 50 /* initial size of a symbol table */ 49 | 50 | 51 | class Array; 52 | class Node; 53 | 54 | /// Cell: all information about a variable or constant 55 | class Cell { 56 | public: 57 | enum class type { 58 | CELL, 59 | CTEMP, // temporary 60 | CFUNC, //function definition 61 | EXTFUNC, // external function 62 | FLD, //input field ($1, $2,...) 63 | REC, //input record ($0) 64 | CNF, //NF 65 | //JUMP types 66 | JUMP_FIRST, 67 | JEXIT, JNEXT, JBREAK, JCONT, JRET, JNEXTFILE, 68 | JUMP_LAST, 69 | 70 | BTRUE, //true value 71 | BFALSE //false value 72 | }; 73 | 74 | Cell (const char *n=nullptr, type t=Cell::type::CELL, unsigned char flags=0, Awkfloat f = 0.); 75 | ~Cell (); 76 | Cell& operator =(const Cell& rhs); 77 | void setsval (const char* s); 78 | void setfval (Awkfloat f); 79 | const char* getsval (); 80 | Awkfloat getfval (); 81 | const char* getpssval (); 82 | void clear (); 83 | void makearray (size_t sz = NSYMTAB); 84 | bool match (const char* s, bool anchored=false); 85 | bool pmatch (const char* s, size_t& start, size_t& len, bool anchored = false); 86 | 87 | type ctype; /* Cell type, see above */ 88 | unsigned char flags;/* type flags */ 89 | #define NUM 0x01 /* number value is valid */ 90 | #define STR 0x02 /* string value is valid */ 91 | #define CONVC 0x04 /* string was converted from number via CONVFMT */ 92 | #define PREDEF 0x08 /* predefined variable*/ 93 | #define ARR 0x10 94 | #define REGEX 0x20 95 | #define CONST 0x80 96 | 97 | std::string nval; /* name */ 98 | std::string sval; /* string value */ 99 | Awkfloat fval; /* value as number */ 100 | union { 101 | void* funptr; /* pointer to external function body */ 102 | Array* arrval; /* reuse for array pointer */ 103 | Node* nodeptr; /* reuse for function pointer */ 104 | std::regex* re; /* reuse for regex pointer*/ 105 | }; 106 | 107 | Cell *cnext; /* ptr to next in arrays*/ 108 | #ifndef NDEBUG 109 | int id; 110 | #endif 111 | 112 | bool isarr () const { return (flags & ARR) != 0; } 113 | bool isfcn () const { return (ctype == type::CFUNC) || (ctype == type::EXTFUNC); } 114 | bool isfld () const { return ctype == type::FLD; } 115 | bool isnf () const { return ctype == type::CNF; } 116 | 117 | bool isregex () const { return (flags & REGEX) != 0; } 118 | bool isrec () const { return ctype == type::REC; } 119 | bool isnext () const { return ctype == type::JNEXT || ctype == type::JNEXTFILE; } 120 | bool isret () const { return ctype == type::JRET; } 121 | bool isbreak () const { return ctype == type::JBREAK; } 122 | bool iscont () const { return ctype == type::JCONT; } 123 | bool isjump () const { return ctype > type::JUMP_FIRST && ctype < type::JUMP_LAST; } 124 | bool isexit () const { return ctype== type::JEXIT; } 125 | bool istrue () const { return ctype == type::BTRUE; } 126 | bool istemp () const { return ctype == type::CTEMP; } 127 | 128 | private: 129 | std::string fmt; /* CONVFMT/OFMT value used to convert from number */ 130 | void update_str_val (); 131 | }; 132 | 133 | class Array { /* symbol table array */ 134 | public: 135 | class Iterator { 136 | public: 137 | Iterator operator ++(int); 138 | Iterator& operator ++(); 139 | Cell* operator *(); 140 | Cell* operator ->() { return operator *(); }; 141 | bool operator == (const Iterator& other) const; 142 | bool operator != (const Iterator& other) const { return !operator== (other); } 143 | 144 | private: 145 | Iterator (const Array* a); 146 | const Array* owner; 147 | int ipos; 148 | Cell* ptr; 149 | friend class Array; 150 | }; 151 | 152 | Array (int n); 153 | ~Array (); 154 | Cell* setsym (const char* n, const char* s, double f, unsigned int t); 155 | Cell* setsym (const char* n, Array* arr, int addl_flags); 156 | Cell* removesym (const std::string& n); 157 | void deletecell (Iterator& p); 158 | Cell* lookup (const char* name); 159 | int length () const; 160 | int size () const; 161 | 162 | Iterator begin () const; 163 | Iterator end () const; 164 | #ifndef NDEBUG 165 | void print (); 166 | #endif 167 | 168 | private: 169 | void rehash (); 170 | Cell* insert_sym (const char* n); 171 | 172 | int nelem; /* elements in table right now */ 173 | int sz; /* size of tab */ 174 | Cell **tab; /* hash table pointers */ 175 | }; 176 | 177 | /* function types */ 178 | #define FLENGTH 1 179 | #define FSQRT 2 180 | #define FEXP 3 181 | #define FLOG 4 182 | #define FINT 5 183 | #define FSYSTEM 6 184 | #define FRAND 7 185 | #define FSRAND 8 186 | #define FSIN 9 187 | #define FCOS 10 188 | #define FATAN 11 189 | #define FTOUPPER 12 190 | #define FTOLOWER 13 191 | #define FFLUSH 14 192 | 193 | /* Node: parse tree is made of nodes, with Cell's at bottom */ 194 | class Node 195 | { 196 | public: 197 | typedef std::vector< std::unique_ptr > Arguments; 198 | typedef Cell* (*pfun)(const Node::Arguments& a, int); 199 | 200 | Node (); 201 | Node (int tokid, pfun fn, int iarg, Node* arg1); 202 | Node (int tokid, pfun fn, int iarg, Node* arg1, Node* arg2); 203 | Node (int tokid, pfun fn, int iarg, Node* arg1, Node* arg2, Node* arg3); 204 | Node (int tokid, pfun fn, int iarg, Node* arg1, Node* arg2, Node* arg3, Node* arg4); 205 | ~Node (); 206 | 207 | bool isvalue () const; 208 | Cell* to_cell () const; 209 | int ntype; // node type, see below 210 | #define NVALUE 1 //value node - has only one argument that is a Cell 211 | #define NSTAT 2 //statement node 212 | #define NEXPR 3 213 | pfun proc; 214 | Node *nnext; 215 | int lineno; 216 | int tokid; //!< token id 217 | Arguments arg; //!< array of node arguments 218 | int iarg; //!< int argument 219 | #ifndef NDEBUG 220 | int id; // 221 | #endif 222 | }; 223 | 224 | typedef Node::pfun pfun; 225 | 226 | #define NIL ((Node *) 0) 227 | 228 | extern int pairstack[], paircnt; 229 | 230 | struct FILE_STRUC { 231 | FILE *fp; 232 | char *fname; 233 | int mode; /* '|', 'a', 'w' => LE/LT, GT */ 234 | }; 235 | 236 | typedef int (*inproc)(); 237 | typedef int (*outproc)(const char *buf, size_t len); 238 | 239 | // Function call frame 240 | struct Frame { 241 | Cell *fcn; //the function 242 | Cell **args; //arguments 243 | int nargs; //number of arguments 244 | }; 245 | 246 | 247 | class Interpreter { 248 | public: 249 | Interpreter (); 250 | ~Interpreter (); 251 | void syminit (); 252 | void envinit (); 253 | void makefields (size_t nf); 254 | 255 | void std_redirect (int nf, const char* fname); 256 | void run (); 257 | void clean_symtab (); 258 | void closeall (); 259 | void initgetrec (); 260 | bool getrec (Cell* cell); 261 | void nextfile (); 262 | int getchar (FILE* inf); 263 | bool readrec (Cell* cell, FILE* inf); 264 | const char* getargv (int n); 265 | int putstr (const char* str, FILE* fp); 266 | void setclvar (const char* s); 267 | void fldbld (); 268 | void recbld (); 269 | void cleanfld (int n1, int n2); 270 | void setlastfld (int n); 271 | Cell* fieldadr (int n); 272 | void growfldtab (size_t n); 273 | Node* nodealloc (int n); 274 | Cell* makedfa (const char* s); 275 | 276 | int status; //!< Interpreter status. See below 277 | #define AWKS_INIT 1 //!< status block initialized 278 | #define AWKS_COMPILING 2 //!< compilation started 279 | #define AWKS_COMPILED 3 //!< Program compiled 280 | #define AWKS_RUN 4 //!< Program running 281 | #define AWKS_DONE 5 //!< Program finished 282 | 283 | int err; //!< Last error or warning 284 | char errmsg[1024]; //!< Last error message 285 | bool first_run; //!< true on first run after compile 286 | int lineno; //!< line number in awk program 287 | Array *symtab; //!< symbol table 288 | Node *prog_root; //!< root of parsing tree 289 | int argno; //!< current input argument number */ 290 | Array *envir; //!< environment variables 291 | Array* argvtab; //!< ARGV[n] array 292 | std::mt19937 randgen; //!< Random number generator 293 | unsigned int rand_seed; //!< Random generator seed 294 | char *lexprog; //!< AWK script 295 | char *lexptr; //!< pointer in AWK script 296 | int nprog; //!< number of programs 297 | int curprog; //!< current program being compiled 298 | char **progs; //!< array of program filenames 299 | FILE_STRUC *files; //!< opened files 300 | //!< 0 = stdin 301 | //!< 1 = stdout 302 | //!< 2 = stderr 303 | int nfiles; //!< number of entries in files table 304 | FILE* infile; //!< current input file 305 | inproc inredir; //!< input redirection function 306 | outproc outredir; //!< output redirection function 307 | struct Frame fn; //!< frame data for current function call 308 | bool donerec; //!< true if record is valid (no fld has changed) 309 | bool donefld; //!< true if record broken into fields 310 | std::vector< std::unique_ptr > fldtab; //!< $0, $1, ... 311 | std::vector< std::unique_ptr > ratab; //!< cache of last few regex 312 | 313 | #define CELL_FS predefs[0] 314 | #define CELL_RS predefs[1] 315 | #define CELL_OFS predefs[2] 316 | #define CELL_ORS predefs[3] 317 | #define CELL_OFMT predefs[4] 318 | #define CELL_CONVFMT predefs[5] 319 | #define CELL_NF predefs[6] 320 | #define CELL_FILENAME predefs[7] 321 | #define CELL_NR predefs[8] 322 | #define CELL_FNR predefs[9] 323 | #define CELL_SUBSEP predefs[10] 324 | #define CELL_RSTART predefs[11] 325 | #define CELL_RLENGTH predefs[12] 326 | #define CELL_ARGC predefs[13] 327 | 328 | #define NPREDEF 14 329 | Cell* predefs[NPREDEF]; //!< Predefined variables 330 | 331 | private: 332 | int refldbld (const char* rec); 333 | 334 | //TODO remove next line when finished converting to OO 335 | void* interp; //only to highlight inconsistent use. 336 | }; 337 | 338 | #define FS (interp->CELL_FS->sval) 339 | #define RS (interp->CELL_RS->sval) 340 | #define OFS (interp->CELL_OFS->sval) 341 | #define ORS (interp->CELL_ORS->sval) 342 | #define OFMT (interp->CELL_OFMT->sval) 343 | #define CONVFMT (interp->CELL_CONVFMT->sval) 344 | #define NF (interp->CELL_NF->fval) 345 | #define FILENAME (interp->CELL_FILENAME->sval) 346 | #define NR (interp->CELL_NR->fval) 347 | #define FNR (interp->CELL_FNR->fval) 348 | #define SUBSEP (interp->CELL_SUBSEP->sval) 349 | #define RSTART (interp->CELL_RSTART->fval) 350 | #define RLENGTH (interp->CELL_RLENGTH->fval) 351 | #define ARGC (interp->CELL_ARGC->fval) 352 | 353 | #define MY_FS (CELL_FS->sval) 354 | #define MY_RS (CELL_RS->sval) 355 | #define MY_OFS (CELL_OFS->sval) 356 | #define MY_ORS (CELL_ORS->sval) 357 | #define MY_OFMT (CELL_OFMT->sval) 358 | #define MY_CONVFMT (CELL_CONVFMT->sval) 359 | #define MY_NF (CELL_NF->fval) 360 | #define MY_FILENAME (CELL_FILENAME->sval) 361 | #define MY_NR (CELL_NR->fval) 362 | #define MY_FNR (CELL_FNR->fval) 363 | #define MY_SUBSEP (CELL_SUBSEP->sval) 364 | #define MY_RSTART (CELL_RSTART->fval) 365 | #define MY_RLENGTH (CELL_RLENGTH->fval) 366 | #define MY_ARGC (CELL_ARGC->fval) 367 | 368 | //extern Interpreter *interp; 369 | 370 | struct awk_exception { 371 | awk_exception (Interpreter &interp, int code, const char* msg); 372 | Interpreter& interp; 373 | int err; 374 | }; 375 | 376 | // --------------------------- Global variables ------------------------------ 377 | extern Cell* literal_null; 378 | 379 | 380 | // -------------------------- Inline functions ------------------------------- 381 | inline 382 | Cell* Node::to_cell () const 383 | { 384 | assert (ntype == NVALUE); 385 | return (Cell*)arg[0].get (); 386 | } 387 | 388 | inline 389 | bool Node::isvalue () const 390 | { 391 | return ntype == NVALUE; 392 | } 393 | 394 | inline 395 | int Array::length () const 396 | { 397 | return nelem; 398 | } 399 | 400 | inline 401 | int Array::size () const 402 | { 403 | return sz; 404 | } 405 | -------------------------------------------------------------------------------- /include/awklib/awk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*! 4 | \file awk.h 5 | \brief Embedded AWK library API 6 | 7 | (c) Mircea Neacsu 2019-2021 8 | See README file for full copyright information. 9 | */ 10 | #include 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | struct AWKINTERP 15 | { 16 | void* unused; 17 | }; 18 | 19 | typedef int (*inproc)(); 20 | typedef int (*outproc)(const char *buf, size_t len); 21 | 22 | struct awksymb { 23 | const char *name; 24 | const char *index; 25 | 26 | unsigned int flags; //variable type flags 27 | #define AWKSYMB_NUM 1 //numeric value 28 | #define AWKSYMB_STR 2 //string value 29 | #define AWKSYMB_ARR 4 //variable is an array 30 | double fval; 31 | char *sval; 32 | }; 33 | 34 | typedef void (*awkfunc)(AWKINTERP *pinter, awksymb* ret, int nargs, awksymb* args); 35 | 36 | AWKINTERP* awk_init (const char **vars); 37 | int awk_err (AWKINTERP* pinter, const char **msg); 38 | int awk_setprog (AWKINTERP* pinter, const char *prog); 39 | int awk_addprogfile (AWKINTERP* pinter, const char *progfile); 40 | int awk_compile (AWKINTERP* pinter); 41 | int awk_addarg (AWKINTERP* pinter, const char *arg); 42 | int awk_exec (AWKINTERP* pinter); 43 | int awk_run (AWKINTERP* pinter, const char *prog); 44 | void awk_end (AWKINTERP* pinter); 45 | int awk_setdebug (int level); 46 | void awk_infunc (AWKINTERP* pinter, inproc user_input); 47 | void awk_outfunc (AWKINTERP* pinter, outproc user_output); 48 | int awk_setoutput (AWKINTERP* pinter, const char *fname); 49 | int awk_setinput (AWKINTERP* pinter, const char *fname); 50 | int awk_redirect (AWKINTERP* pinter, int n, const char* fname); 51 | int awk_addfunc (AWKINTERP *pinter, const char *fname, awkfunc fn, int nargs); 52 | int awk_getvar (AWKINTERP *pinter, awksymb* var); 53 | int awk_setvar (AWKINTERP *pinter, awksymb* var); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #ifdef _MSC_VER 60 | #pragma comment (lib, "awklib") 61 | #endif 62 | -------------------------------------------------------------------------------- /include/awklib/err.h: -------------------------------------------------------------------------------- 1 | /*! 2 | \file awkerr.h 3 | \brief Error codes from embedded AWK library 4 | 5 | (c) Mircea Neacsu 2019 6 | See README file for full copyright information. 7 | */ 8 | #pragma once 9 | 10 | //AWK error codes 11 | #define AWK_ERR_NOMEM -1 //out of memory 12 | #define AWK_ERR_NOPROG -2 //no program given 13 | #define AWK_ERR_INPROG -3 //cannot open program file 14 | #define AWK_ERR_INVVAR -4 //invalid variable argument 15 | #define AWK_ERR_BADSTAT -5 //invalid interpreter status 16 | #define AWK_ERR_PROGFILE -6 //program file or string already set 17 | #define AWK_ERR_SYNTAX -7 //syntax error 18 | #define AWK_ERR_INFILE -8 //cannot open input file 19 | #define AWK_ERR_LIMIT -9 //limit exceeded 20 | #define AWK_ERR_ARG -10 //invalid argument 21 | #define AWK_ERR_FPE -11 //floating point error 22 | #define AWK_ERR_OTHER -12 //other errors 23 | #define AWK_ERR_RUNTIME -13 //runtime error 24 | #define AWK_ERR_OUTFILE -14 //output file error 25 | #define AWK_ERR_PIPE -15 //pipe error 26 | #define AWK_ERR_NOVAR -16 //variable not found 27 | #define AWK_ERR_ARRAY -17 //variable is an array 28 | #define AWK_ERR_INVTYPE -18 //invalid variable type 29 | -------------------------------------------------------------------------------- /include/node.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /include/proto.h: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | 25 | #include 26 | 27 | void setfname (Cell *); 28 | int constnode (Node *); 29 | const char* strnode (Node *); 30 | Node* notnull (Node *); 31 | int yylex (void*); 32 | int yyparse (void*); 33 | void yyinit (void); 34 | void startreg (void); 35 | 36 | Node* nodedfa (const char* str); 37 | 38 | int pgetc (void); 39 | char* cursource (void); 40 | 41 | Node* exptostat (Node *); 42 | Node* stat1 (int tok, pfun fn, Node* a0, int iarg = 0); 43 | Node* stat2 (int tok, pfun fn, Node* a0, Node* a1, int iarg = 0); 44 | Node* stat3 (int tok, pfun fn, Node* a0, Node* a1, Node* a2, int iarg = 0); 45 | Node* stat4 (int tok, pfun fn, Node* a0, Node* a1, Node* a2, Node* a3, int iarg = 0); 46 | Node* op1 (int tok, pfun fn, Node *, int iarg = 0); 47 | Node* op2 (int tok, pfun fn, Node *, Node *, int iarg = 0); 48 | Node* op3 (int tok, pfun fn, Node *, Node *, Node *, int iarg = 0); 49 | Node* op4 (int tok, pfun fn, Node *, Node *, Node *, Node *, int iarg = 0); 50 | Node* celltonode (Cell *c, Cell::type t = Cell::type::CELL, int flags = 0); 51 | Node* rectonode (); 52 | Node* nullnode (); 53 | Node* makearr (Node *); 54 | Node* pa2stat (Node *, Node *, Node *); 55 | Node* linkum (Node *, Node *); 56 | void defn (Cell *, Node *, Node *); 57 | int isarg (const char *); 58 | void funnyvar (const Cell *, const char *); 59 | char* tostring (const char *); 60 | char* qstring (const char *str, int delim); 61 | 62 | void yyerror (const char *); 63 | void fpecatch (int); 64 | int input (void); 65 | void WARNING (const char *, ...); 66 | double errcheck (double, const char *); 67 | int isclvar (const char *); 68 | bool is_number (const char *); 69 | inline 70 | bool is_number (const std::string& c) 71 | { 72 | return is_number (c.c_str ()); 73 | } 74 | 75 | void adjbuf (char **pb, size_t *sz, size_t min, int q, char **pbp); 76 | void tempfree (Cell *a); 77 | 78 | Cell* program (const Node::Arguments&, int); 79 | Cell* call (const Node::Arguments&, int); 80 | Cell* arg (const Node::Arguments&, int); 81 | Cell* jump (const Node::Arguments&, int); 82 | Cell* awkgetline (const Node::Arguments&, int); 83 | Cell* getnf (const Node::Arguments&, int); 84 | Cell* array (const Node::Arguments&, int); 85 | Cell* awkdelete (const Node::Arguments&, int); 86 | Cell* intest (const Node::Arguments&, int); 87 | Cell* matchop (const Node::Arguments&, int); 88 | Cell* matchfun (const Node::Arguments& a, int); 89 | Cell* boolop (const Node::Arguments&, int); 90 | Cell* relop (const Node::Arguments&, int); 91 | Cell* indirect (const Node::Arguments&, int); 92 | Cell* substr (const Node::Arguments&, int); 93 | Cell* sindex (const Node::Arguments&, int); 94 | Cell* awksprintf (const Node::Arguments&, int); 95 | Cell* awkprintf (const Node::Arguments&, int); 96 | Cell* arith (const Node::Arguments&, int); 97 | Cell* incrdecr (const Node::Arguments&, int); 98 | Cell* assign (const Node::Arguments&, int); 99 | Cell* cat (const Node::Arguments&, int); 100 | Cell* pastat (const Node::Arguments&, int); 101 | Cell* dopa2 (const Node::Arguments&, int); 102 | Cell* split (const Node::Arguments&, int); 103 | Cell* condexpr (const Node::Arguments&, int); 104 | Cell* ifstat (const Node::Arguments&, int); 105 | Cell* whilestat (const Node::Arguments&, int); 106 | Cell* dostat (const Node::Arguments&, int); 107 | Cell* forstat (const Node::Arguments&, int); 108 | Cell* instat (const Node::Arguments&, int); 109 | Cell* bltin (const Node::Arguments&, int); 110 | Cell* printstat (const Node::Arguments&, int); 111 | Cell* nullproc (const Node::Arguments&, int); 112 | FILE* redirect (int, Node& ); 113 | FILE* openfile (int, const char *); 114 | const char* filename (FILE *); 115 | Cell* closefile (const Node::Arguments&, int); 116 | Cell* sub (const Node::Arguments&, int); 117 | Cell* gsub (const Node::Arguments&, int); 118 | void requote (std::string& s); 119 | 120 | // TODO: make it member of Node 121 | Cell* execute (const Node* u); 122 | inline 123 | Cell* execute (const std::unique_ptr& u) 124 | { 125 | return execute (u.get ()); 126 | } 127 | 128 | FILE* popen (const char *, const char *); 129 | int pclose (FILE *); 130 | 131 | void SYNTAX (const char*, ...); 132 | void FATAL (int err, const char*, ...); 133 | 134 | #ifndef NDEBUG 135 | void print_cell (Cell* c, int indent); 136 | const char *flags2str (int flags); 137 | std::string quote (const std::string& in); 138 | #else 139 | inline void print_cell (Cell* c, int indent) {}; 140 | inline const char* flags2str (int flags) { return ""; }; 141 | inline std::string quote (const std::string& in) { 142 | return in; 143 | }; 144 | #endif 145 | -------------------------------------------------------------------------------- /libtest/libtest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {12F8205B-15C0-4E0E-B9A4-3EBDEBC750B3} 24 | Win32Proj 25 | libtest 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 76 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 77 | 78 | 79 | true 80 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 81 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 82 | 83 | 84 | false 85 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 86 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 87 | 88 | 89 | false 90 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 91 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 92 | 93 | 94 | 95 | Level3 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)include 100 | 101 | 102 | true 103 | Console 104 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | true 113 | $(SolutionDir)include 114 | 115 | 116 | true 117 | Console 118 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 119 | 120 | 121 | 122 | 123 | Level3 124 | MaxSpeed 125 | true 126 | true 127 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | true 129 | $(SolutionDir)include 130 | 131 | 132 | true 133 | true 134 | true 135 | Console 136 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 137 | 138 | 139 | 140 | 141 | Level3 142 | MaxSpeed 143 | true 144 | true 145 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 146 | true 147 | $(SolutionDir)include 148 | 149 | 150 | true 151 | true 152 | true 153 | Console 154 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /libtest/libtest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /libtest/tests/10_field_expression.tst: -------------------------------------------------------------------------------- 1 | #Expression for field number 2 | {i=$(1); print $(i+1), $0} 3 | 4 | ##Input 5 | 1 Now is the time for all good men to come to the aid of the party. 6 | 2 party. Now is the time for all good men to come to the aid of the 7 | 3 the party. Now is the time for all good men to come to the aid of 8 | 4 of the party. Now is the time for all good men to come to the aid 9 | 5 aid of the party. Now is the time for all good men to come to the 10 | 6 the aid of the party. Now is the time for all good men to come to 11 | 7 to the aid of the party. Now is the time for all good men to come 12 | 8 come to the aid of the party. Now is the time for all good men to 13 | 9 to come to the aid of the party. Now is the time for all good men 14 | 10 men to come to the aid of the party. Now is the time for all good 15 | 11 good men to come to the aid of the party. Now is the time for all 16 | 12 all good men to come to the aid of the party. Now is the time for 17 | 13 for all good men to come to the aid of the party. Now is the time 18 | 14 time for all good men to come to the aid of the party. Now is the 19 | 15 the time for all good men to come to the aid of the party. Now is 20 | 16 is the time for all good men to come to the aid of the party. Now 21 | ##Output 22 | Now 1 Now is the time for all good men to come to the aid of the party. 23 | Now 2 party. Now is the time for all good men to come to the aid of the 24 | Now 3 the party. Now is the time for all good men to come to the aid of 25 | Now 4 of the party. Now is the time for all good men to come to the aid 26 | Now 5 aid of the party. Now is the time for all good men to come to the 27 | Now 6 the aid of the party. Now is the time for all good men to come to 28 | Now 7 to the aid of the party. Now is the time for all good men to come 29 | Now 8 come to the aid of the party. Now is the time for all good men to 30 | Now 9 to come to the aid of the party. Now is the time for all good men 31 | Now 10 men to come to the aid of the party. Now is the time for all good 32 | Now 11 good men to come to the aid of the party. Now is the time for all 33 | Now 12 all good men to come to the aid of the party. Now is the time for 34 | Now 13 for all good men to come to the aid of the party. Now is the time 35 | Now 14 time for all good men to come to the aid of the party. Now is the 36 | Now 15 the time for all good men to come to the aid of the party. Now is 37 | Now 16 is the time for all good men to come to the aid of the party. Now 38 | ##END -------------------------------------------------------------------------------- /libtest/tests/11_field_change.tst: -------------------------------------------------------------------------------- 1 | #Changing a field changes the whole record 2 | {$(1) = "xxx"; print $1,$0} 3 | 4 | ##Input 5 | 1 Now is the time for all good men to come to the aid of the party. 6 | 2 party. Now is the time for all good men to come to the aid of the 7 | 3 the party. Now is the time for all good men to come to the aid of 8 | 4 of the party. Now is the time for all good men to come to the aid 9 | 5 aid of the party. Now is the time for all good men to come to the 10 | 6 the aid of the party. Now is the time for all good men to come to 11 | 7 to the aid of the party. Now is the time for all good men to come 12 | 8 come to the aid of the party. Now is the time for all good men to 13 | 9 to come to the aid of the party. Now is the time for all good men 14 | 10 men to come to the aid of the party. Now is the time for all good 15 | 11 good men to come to the aid of the party. Now is the time for all 16 | 12 all good men to come to the aid of the party. Now is the time for 17 | 13 for all good men to come to the aid of the party. Now is the time 18 | 14 time for all good men to come to the aid of the party. Now is the 19 | 15 the time for all good men to come to the aid of the party. Now is 20 | 16 is the time for all good men to come to the aid of the party. Now 21 | ##Output 22 | xxx xxx Now is the time for all good men to come to the aid of the party. 23 | xxx xxx party. Now is the time for all good men to come to the aid of the 24 | xxx xxx the party. Now is the time for all good men to come to the aid of 25 | xxx xxx of the party. Now is the time for all good men to come to the aid 26 | xxx xxx aid of the party. Now is the time for all good men to come to the 27 | xxx xxx the aid of the party. Now is the time for all good men to come to 28 | xxx xxx to the aid of the party. Now is the time for all good men to come 29 | xxx xxx come to the aid of the party. Now is the time for all good men to 30 | xxx xxx to come to the aid of the party. Now is the time for all good men 31 | xxx xxx men to come to the aid of the party. Now is the time for all good 32 | xxx xxx good men to come to the aid of the party. Now is the time for all 33 | xxx xxx all good men to come to the aid of the party. Now is the time for 34 | xxx xxx for all good men to come to the aid of the party. Now is the time 35 | xxx xxx time for all good men to come to the aid of the party. Now is the 36 | xxx xxx the time for all good men to come to the aid of the party. Now is 37 | xxx xxx is the time for all good men to come to the aid of the party. Now 38 | ##END -------------------------------------------------------------------------------- /libtest/tests/12_regexp_pattern.tst: -------------------------------------------------------------------------------- 1 | /a|b|c/ { 2 | i = $1 3 | print 4 | while (i >= 1) { 5 | print " ", i 6 | i = i / 10 7 | } 8 | } 9 | 10 | ##Input 11 | 17379 mel 12 | 16693 bwk me 13 | 16116 ken him someone else 14 | 15713 srb 15 | 11895 lem 16 | 10409 scj 17 | 10252 rhm 18 | 9853 shen 19 | 9748 a68 20 | 9492 sif 21 | 9190 pjw 22 | 8912 nls 23 | 8895 dmr 24 | 8491 cda 25 | 8372 bs 26 | 8252 llc 27 | 7450 mb 28 | 7360 ava 29 | 7273 jrv 30 | 7080 bin 31 | 7063 greg 32 | 6567 dict 33 | 6462 lck 34 | 6291 rje 35 | 6211 lwf 36 | 5671 dave 37 | 5373 jhc 38 | 5220 agf 39 | 5167 doug 40 | 5007 valerie 41 | 3963 jca 42 | 3895 bbs 43 | 3796 moh 44 | 3481 xchar 45 | 3200 tbl 46 | 2845 s 47 | 2774 tgs 48 | 2641 met 49 | 2566 jck 50 | 2511 port 51 | 2479 sue 52 | 2127 root 53 | 1989 bsb 54 | 1989 jeg 55 | 1933 eag 56 | ##Output 57 | 16693 bwk me 58 | 16693 59 | 1669.3 60 | 166.93 61 | 16.693 62 | 1.6693 63 | 15713 srb 64 | 15713 65 | 1571.3 66 | 157.13 67 | 15.713 68 | 1.5713 69 | 10409 scj 70 | 10409 71 | 1040.9 72 | 104.09 73 | 10.409 74 | 1.0409 75 | 9748 a68 76 | 9748 77 | 974.8 78 | 97.48 79 | 9.748 80 | 8491 cda 81 | 8491 82 | 849.1 83 | 84.91 84 | 8.491 85 | 8372 bs 86 | 8372 87 | 837.2 88 | 83.72 89 | 8.372 90 | 8252 llc 91 | 8252 92 | 825.2 93 | 82.52 94 | 8.252 95 | 7450 mb 96 | 7450 97 | 745 98 | 74.5 99 | 7.45 100 | 7360 ava 101 | 7360 102 | 736 103 | 73.6 104 | 7.36 105 | 7080 bin 106 | 7080 107 | 708 108 | 70.8 109 | 7.08 110 | 6567 dict 111 | 6567 112 | 656.7 113 | 65.67 114 | 6.567 115 | 6462 lck 116 | 6462 117 | 646.2 118 | 64.62 119 | 6.462 120 | 5671 dave 121 | 5671 122 | 567.1 123 | 56.71 124 | 5.671 125 | 5373 jhc 126 | 5373 127 | 537.3 128 | 53.73 129 | 5.373 130 | 5220 agf 131 | 5220 132 | 522 133 | 52.2 134 | 5.22 135 | 5007 valerie 136 | 5007 137 | 500.7 138 | 50.07 139 | 5.007 140 | 3963 jca 141 | 3963 142 | 396.3 143 | 39.63 144 | 3.963 145 | 3895 bbs 146 | 3895 147 | 389.5 148 | 38.95 149 | 3.895 150 | 3481 xchar 151 | 3481 152 | 348.1 153 | 34.81 154 | 3.481 155 | 3200 tbl 156 | 3200 157 | 320 158 | 32 159 | 3.2 160 | 2566 jck 161 | 2566 162 | 256.6 163 | 25.66 164 | 2.566 165 | 1989 bsb 166 | 1989 167 | 198.9 168 | 19.89 169 | 1.989 170 | 1933 eag 171 | 1933 172 | 193.3 173 | 19.33 174 | 1.933 175 | ##END 176 | -------------------------------------------------------------------------------- /libtest/tests/13_nf.tst: -------------------------------------------------------------------------------- 1 | # Field counter NF 2 | {print NF,$0} 3 | 4 | ##Input 5 | The quick brown fox jumps over lazy dog 6 | The quick brown fox jumps over lazy 7 | The quick brown fox jumps over 8 | The quick brown fox jumps 9 | The quick brown fox 10 | The quick brown 11 | The quick 12 | The 13 | 14 | ##Output 15 | 8 The quick brown fox jumps over lazy dog 16 | 7 The quick brown fox jumps over lazy 17 | 6 The quick brown fox jumps over 18 | 5 The quick brown fox jumps 19 | 4 The quick brown fox 20 | 3 The quick brown 21 | 2 The quick 22 | 1 The 23 | 0 24 | ##END -------------------------------------------------------------------------------- /libtest/tests/14_forloop.tst: -------------------------------------------------------------------------------- 1 | # FOR loop 2 | /a|b|c/ { 3 | print 4 | for (i = $1; i >= 1; ) 5 | print " ", i /= 10 6 | } 7 | 8 | ##Input 9 | 17379 mel 10 | 16693 bwk me 11 | 16116 ken him someone else 12 | 15713 srb 13 | 11895 lem 14 | 10409 scj 15 | 10252 rhm 16 | 9853 shen 17 | 9748 a68 18 | 9492 sif 19 | 9190 pjw 20 | 8912 nls 21 | 8895 dmr 22 | 8491 cda 23 | 8372 bs 24 | 8252 llc 25 | 7450 mb 26 | 7360 ava 27 | 7273 jrv 28 | 7080 bin 29 | 7063 greg 30 | 6567 dict 31 | 6462 lck 32 | 6291 rje 33 | 6211 lwf 34 | 5671 dave 35 | 5373 jhc 36 | 5220 agf 37 | 5167 doug 38 | 5007 valerie 39 | 3963 jca 40 | 3895 bbs 41 | 3796 moh 42 | 3481 xchar 43 | 3200 tbl 44 | 2845 s 45 | 2774 tgs 46 | 2641 met 47 | 2566 jck 48 | 2511 port 49 | 2479 sue 50 | 2127 root 51 | 1989 bsb 52 | 1989 jeg 53 | 1933 eag 54 | ##Output 55 | 16693 bwk me 56 | 1669.3 57 | 166.93 58 | 16.693 59 | 1.6693 60 | 0.16693 61 | 15713 srb 62 | 1571.3 63 | 157.13 64 | 15.713 65 | 1.5713 66 | 0.15713 67 | 10409 scj 68 | 1040.9 69 | 104.09 70 | 10.409 71 | 1.0409 72 | 0.10409 73 | 9748 a68 74 | 974.8 75 | 97.48 76 | 9.748 77 | 0.9748 78 | 8491 cda 79 | 849.1 80 | 84.91 81 | 8.491 82 | 0.8491 83 | 8372 bs 84 | 837.2 85 | 83.72 86 | 8.372 87 | 0.8372 88 | 8252 llc 89 | 825.2 90 | 82.52 91 | 8.252 92 | 0.8252 93 | 7450 mb 94 | 745 95 | 74.5 96 | 7.45 97 | 0.745 98 | 7360 ava 99 | 736 100 | 73.6 101 | 7.36 102 | 0.736 103 | 7080 bin 104 | 708 105 | 70.8 106 | 7.08 107 | 0.708 108 | 6567 dict 109 | 656.7 110 | 65.67 111 | 6.567 112 | 0.6567 113 | 6462 lck 114 | 646.2 115 | 64.62 116 | 6.462 117 | 0.6462 118 | 5671 dave 119 | 567.1 120 | 56.71 121 | 5.671 122 | 0.5671 123 | 5373 jhc 124 | 537.3 125 | 53.73 126 | 5.373 127 | 0.5373 128 | 5220 agf 129 | 522 130 | 52.2 131 | 5.22 132 | 0.522 133 | 5007 valerie 134 | 500.7 135 | 50.07 136 | 5.007 137 | 0.5007 138 | 3963 jca 139 | 396.3 140 | 39.63 141 | 3.963 142 | 0.3963 143 | 3895 bbs 144 | 389.5 145 | 38.95 146 | 3.895 147 | 0.3895 148 | 3481 xchar 149 | 348.1 150 | 34.81 151 | 3.481 152 | 0.3481 153 | 3200 tbl 154 | 320 155 | 32 156 | 3.2 157 | 0.32 158 | 2566 jck 159 | 256.6 160 | 25.66 161 | 2.566 162 | 0.2566 163 | 1989 bsb 164 | 198.9 165 | 19.89 166 | 1.989 167 | 0.1989 168 | 1933 eag 169 | 193.3 170 | 19.33 171 | 1.933 172 | 0.1933 173 | ##END -------------------------------------------------------------------------------- /libtest/tests/15_diveq.tst: -------------------------------------------------------------------------------- 1 | # /= operator gives same result as / 2 | /a|b|c/ { 3 | print 4 | for (i = $1; (i /= 10)>= 1; ) 5 | print " ", i 6 | } 7 | 8 | 9 | ##Input 10 | 17379 mel 11 | 16693 bwk me 12 | 16116 ken him someone else 13 | 15713 srb 14 | 11895 lem 15 | 10409 scj 16 | 10252 rhm 17 | 9853 shen 18 | 9748 a68 19 | 9492 sif 20 | 9190 pjw 21 | 8912 nls 22 | 8895 dmr 23 | 8491 cda 24 | 8372 bs 25 | 8252 llc 26 | 7450 mb 27 | 7360 ava 28 | 7273 jrv 29 | 7080 bin 30 | 7063 greg 31 | 6567 dict 32 | 6462 lck 33 | 6291 rje 34 | 6211 lwf 35 | 5671 dave 36 | 5373 jhc 37 | 5220 agf 38 | 5167 doug 39 | 5007 valerie 40 | 3963 jca 41 | 3895 bbs 42 | 3796 moh 43 | 3481 xchar 44 | 3200 tbl 45 | 2845 s 46 | 2774 tgs 47 | 2641 met 48 | 2566 jck 49 | 2511 port 50 | 2479 sue 51 | 2127 root 52 | 1989 bsb 53 | 1989 jeg 54 | 1933 eag 55 | ##Output 56 | 16693 bwk me 57 | 1669.3 58 | 166.93 59 | 16.693 60 | 1.6693 61 | 15713 srb 62 | 1571.3 63 | 157.13 64 | 15.713 65 | 1.5713 66 | 10409 scj 67 | 1040.9 68 | 104.09 69 | 10.409 70 | 1.0409 71 | 9748 a68 72 | 974.8 73 | 97.48 74 | 9.748 75 | 8491 cda 76 | 849.1 77 | 84.91 78 | 8.491 79 | 8372 bs 80 | 837.2 81 | 83.72 82 | 8.372 83 | 8252 llc 84 | 825.2 85 | 82.52 86 | 8.252 87 | 7450 mb 88 | 745 89 | 74.5 90 | 7.45 91 | 7360 ava 92 | 736 93 | 73.6 94 | 7.36 95 | 7080 bin 96 | 708 97 | 70.8 98 | 7.08 99 | 6567 dict 100 | 656.7 101 | 65.67 102 | 6.567 103 | 6462 lck 104 | 646.2 105 | 64.62 106 | 6.462 107 | 5671 dave 108 | 567.1 109 | 56.71 110 | 5.671 111 | 5373 jhc 112 | 537.3 113 | 53.73 114 | 5.373 115 | 5220 agf 116 | 522 117 | 52.2 118 | 5.22 119 | 5007 valerie 120 | 500.7 121 | 50.07 122 | 5.007 123 | 3963 jca 124 | 396.3 125 | 39.63 126 | 3.963 127 | 3895 bbs 128 | 389.5 129 | 38.95 130 | 3.895 131 | 3481 xchar 132 | 348.1 133 | 34.81 134 | 3.481 135 | 3200 tbl 136 | 320 137 | 32 138 | 3.2 139 | 2566 jck 140 | 256.6 141 | 25.66 142 | 2.566 143 | 1989 bsb 144 | 198.9 145 | 19.89 146 | 1.989 147 | 1933 eag 148 | 193.3 149 | 19.33 150 | 1.933 151 | ##END -------------------------------------------------------------------------------- /libtest/tests/16_field_change1.tst: -------------------------------------------------------------------------------- 1 | {$2=$1; print} 2 | 3 | # this should produce a blank for an empty input line 4 | # since it has created fields 1 and 2. 5 | 6 | ##Input 7 | 17379 mel 8 | 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | 9492 sif 18 | 9190 pjw 19 | 8912 nls 20 | 8895 dmr 21 | 8491 cda 22 | 8372 bs 23 | 8252 llc 24 | 7450 mb 25 | 7360 ava 26 | 7273 jrv 27 | 7080 bin 28 | 7063 greg 29 | 6567 dict 30 | 6462 lck 31 | 6291 rje 32 | 6211 lwf 33 | 5671 dave 34 | 5373 jhc 35 | 5220 agf 36 | 5167 doug 37 | 5007 valerie 38 | 3963 jca 39 | 3895 bbs 40 | 3796 moh 41 | 3481 xchar 42 | 3200 tbl 43 | 2845 s 44 | 2774 tgs 45 | 2641 met 46 | 2566 jck 47 | 2511 port 48 | 2479 sue 49 | 2127 root 50 | 1989 bsb 51 | 1989 jeg 52 | 1933 eag 53 | ##Output 54 | 17379 17379 55 | 56 | 16693 16693 me 57 | 16116 16116 him someone else 58 | 15713 15713 59 | 11895 11895 60 | 10409 10409 61 | 10252 10252 62 | 9853 9853 63 | 9748 9748 64 | 9492 9492 65 | 9190 9190 66 | 8912 8912 67 | 8895 8895 68 | 8491 8491 69 | 8372 8372 70 | 8252 8252 71 | 7450 7450 72 | 7360 7360 73 | 7273 7273 74 | 7080 7080 75 | 7063 7063 76 | 6567 6567 77 | 6462 6462 78 | 6291 6291 79 | 6211 6211 80 | 5671 5671 81 | 5373 5373 82 | 5220 5220 83 | 5167 5167 84 | 5007 5007 85 | 3963 3963 86 | 3895 3895 87 | 3796 3796 88 | 3481 3481 89 | 3200 3200 90 | 2845 2845 91 | 2774 2774 92 | 2641 2641 93 | 2566 2566 94 | 2511 2511 95 | 2479 2479 96 | 2127 2127 97 | 1989 1989 98 | 1989 1989 99 | 1933 1933 100 | ##END -------------------------------------------------------------------------------- /libtest/tests/17_field_change2.tst: -------------------------------------------------------------------------------- 1 | {$1=$2; print} 2 | 3 | # this should print nothing for an empty input line 4 | # since it has only referred to $2, not created it, 5 | # and thus only $1 exists (and it's null). 6 | 7 | # is this right??? 8 | # Mircea - no it is not. It prints a blank line 9 | 10 | ##Input 11 | 17379 mel 12 | 13 | 16693 bwk me 14 | 16116 ken him someone else 15 | 15713 srb 16 | 11895 lem 17 | 10409 scj 18 | 10252 rhm 19 | 9853 shen 20 | 9748 a68 21 | 9492 sif 22 | 9190 pjw 23 | 8912 nls 24 | 8895 dmr 25 | 8491 cda 26 | 8372 bs 27 | 8252 llc 28 | 7450 mb 29 | 7360 ava 30 | 7273 jrv 31 | 7080 bin 32 | 7063 greg 33 | 6567 dict 34 | 6462 lck 35 | 6291 rje 36 | 6211 lwf 37 | 5671 dave 38 | 5373 jhc 39 | 5220 agf 40 | 5167 doug 41 | 5007 valerie 42 | 3963 jca 43 | 3895 bbs 44 | 3796 moh 45 | 3481 xchar 46 | 3200 tbl 47 | 2845 s 48 | 2774 tgs 49 | 2641 met 50 | 2566 jck 51 | 2511 port 52 | 2479 sue 53 | 2127 root 54 | 1989 bsb 55 | 1989 jeg 56 | 1933 eag 57 | ##Output 58 | mel mel 59 | 60 | bwk bwk me 61 | ken ken him someone else 62 | srb srb 63 | lem lem 64 | scj scj 65 | rhm rhm 66 | shen shen 67 | a68 a68 68 | sif sif 69 | pjw pjw 70 | nls nls 71 | dmr dmr 72 | cda cda 73 | bs bs 74 | llc llc 75 | mb mb 76 | ava ava 77 | jrv jrv 78 | bin bin 79 | greg greg 80 | dict dict 81 | lck lck 82 | rje rje 83 | lwf lwf 84 | dave dave 85 | jhc jhc 86 | agf agf 87 | doug doug 88 | valerie valerie 89 | jca jca 90 | bbs bbs 91 | moh moh 92 | xchar xchar 93 | tbl tbl 94 | s s 95 | tgs tgs 96 | met met 97 | jck jck 98 | port port 99 | sue sue 100 | root root 101 | bsb bsb 102 | jeg jeg 103 | eag eag 104 | ##END -------------------------------------------------------------------------------- /libtest/tests/18_array.tst: -------------------------------------------------------------------------------- 1 | # Array access 2 | 3 | {if (amount[$2] "" == "") item[++num] = $2; 4 | amount[$2] += $1 5 | } 6 | END {for (i=1; i<=num; i++) 7 | print item[i], amount[item[i]] 8 | } 9 | ##Input 10 | 12.5 carrots 11 | 3.2 apples 12 | 1.2 oranges 13 | 10.2 carrots again 14 | ##Output 15 | carrots 22.7 16 | apples 3.2 17 | oranges 1.2 18 | ##END -------------------------------------------------------------------------------- /libtest/tests/19_array.tst: -------------------------------------------------------------------------------- 1 | { x[NR] = $0 } 2 | 3 | END { 4 | i = 1 5 | while (i <= NR) { 6 | print x[i] 7 | split (x[i], y) 8 | usage = y[1] 9 | name = y[2] 10 | print " ", name, usage 11 | i++ 12 | } 13 | } 14 | 15 | ##Input 16 | cat scratch 17 | dog bite 18 | bird sing 19 | ##Output 20 | cat scratch 21 | scratch cat 22 | dog bite 23 | bite dog 24 | bird sing 25 | sing bird 26 | ##END 27 | -------------------------------------------------------------------------------- /libtest/tests/1_grammar.tst: -------------------------------------------------------------------------------- 1 | # This abomination runs through all grammar rules 2 | 3 | BEGIN { 4 | a = true && # rule 3, 4 5 | false 6 | b = true || # rule 5, 6 7 | false 8 | for (i=0; i < 3 ; i++) # rule 13, 14 9 | a = a+1; 10 | for (i=0; ; i++) #rule 15, 16 11 | if (i == 3) 12 | break 13 | else 14 | v[i] = 1 15 | for (t in v) print t, t+1, t-1, t*t, t^2, t**2, t/2, t%3 16 | i++; i--; 17 | g() 18 | t += ++u; 19 | 20 | t -= --u;; 21 | ; 22 | t *= +2 23 | t /= -2 24 | t ^= 2 25 | t %= 2 26 | t = (!/abc/) 27 | t = (2 >=3)? (!/abc/) : /abc/ 28 | if (t in v) 29 | u = t ~ /abc/ 30 | if ((1,2) in v) 31 | print "a" "b" 32 | else 33 | print 34 | t = /ab/ ~ (/ab/ && /cd/) 35 | atan2(sin(rand()),rand) 36 | index(/ab/, "abc") 37 | index(/cd/, /cd/ && /ef/) 38 | match(/ab/, /cd/) 39 | match(/ab/, /cd/ && /ef/) 40 | split(/ab/, v, /cd/) 41 | split(/ab/, v, /cd/ && /ef/) 42 | split (/ab/, arr) 43 | for (;;) 44 | break; 45 | } 46 | 47 | /Rec/ { gsub (/Record_/, "the record ") } 48 | /1/, /3/ {print $0, (1<2)?"1-3":"4-5", $u} 49 | /4/, /5/ 50 | {print ("Any record", $(1-1))} 51 | 52 | /nada/ 53 | 54 | 5 <= 6 {print /ab/ || (t in v) && a ~ (/abc/ && /def/), (1, 2,3) in v} 55 | 56 | 4 != 4 { 57 | print $1 t in v ~ /ab/ 58 | " " | getline 59 | " " | getline s 60 | getline a < getline 61 | getline < getline a 62 | 63 | next;nextfile; 64 | delete v[1] 65 | delete v 66 | exit 67 | exit 2 68 | print a=b | "cmd" 69 | print !3 > "out" 70 | print 4 >> "out" 71 | };; 72 | 73 | ; 74 | 75 | function f(a, 76 | b, c) 77 | { 78 | sprintf ("%s%s%s", a, b, c) 79 | return a b c; 80 | } 81 | 82 | function g () { 83 | u = 3 84 | s = "a=b=c=" 85 | s1 = sub (/=/, "_", s) 86 | s2 = gsub ((/=/), "_") 87 | s3 = sub ((/=/), "_", s) 88 | substr (s, 1, 3) 89 | substr (s, 1) 90 | return 91 | } 92 | END { 93 | i = 5; 94 | do 95 | i--; 96 | while (i>3) 97 | while (i>=0) { 98 | NF /= 2; 99 | i-- 100 | continue; 101 | } 102 | printf f("a", "b", "c"); 103 | close (t) 104 | } 105 | ## Input 106 | Record 1 107 | Record 2 108 | Record 3 109 | Record 4 110 | ## Output 111 | 2 3 1 4 4 4 1 2 112 | 0 1 -1 0 0 0 0 0 113 | 1 2 0 1 1 1 0.5 1 114 | 115 | Record 1 1-3 Record 1 116 | Any record Record 1 117 | 0 0 118 | Record 2 1-3 Record 2 119 | Any record Record 2 120 | 0 0 121 | Record 3 1-3 Record 3 122 | Any record Record 3 123 | 0 0 124 | Record 4 125 | Any record Record 4 126 | 0 0 127 | abc 128 | -------------------------------------------------------------------------------- /libtest/tests/1_printall.tst: -------------------------------------------------------------------------------- 1 | #output should be identical with input 2 | { print } 3 | 4 | ## Input 5 | /dev/rrp3: 6 | 7 | 17379 mel 8 | 16693 bwk me 9 | 16116 ken him someone else 10 | 15713 srb 11 | 11895 lem 12 | 10409 scj 13 | 10252 rhm 14 | 9853 shen 15 | 9748 a68 16 | ## Output 17 | /dev/rrp3: 18 | 19 | 17379 mel 20 | 16693 bwk me 21 | 16116 ken him someone else 22 | 15713 srb 23 | 11895 lem 24 | 10409 scj 25 | 10252 rhm 26 | 9853 shen 27 | 9748 a68 28 | ## END -------------------------------------------------------------------------------- /libtest/tests/20_array.tst: -------------------------------------------------------------------------------- 1 | #Word frequency counting 2 | { 3 | for(i=1; i<=NF; i++) { 4 | if (x[$i] == "") 5 | y[n++] = $i 6 | x[$i]++ 7 | } 8 | } 9 | END { 10 | for (i=0; i>> assert failed <<<" 5 | } 6 | 7 | function i(x) { return x } 8 | 9 | { print; m = length($1); n = length($2); n = i(n); assert(m > n) } 10 | ##Input 11 | dog bite 12 | bite dog 13 | ##Output 14 | dog bite 15 | >>> assert failed <<< 16 | bite dog 17 | ##END -------------------------------------------------------------------------------- /libtest/tests/25_rgexp_pattern.tst: -------------------------------------------------------------------------------- 1 | #Consonnt(s),a,Consonant(s),e,.... 2 | /^[^aeiouy]*a[^aeiouy]*e[^aeiouy]*i[^aeiouy]*o[^aeiouy]*u[^aeiouy]*y[^aeiouy]*$/ 3 | ##Input 4 | taperilosuys 5 | teperilosuys 6 | ##Output 7 | taperilosuys 8 | ##END 9 | -------------------------------------------------------------------------------- /libtest/tests/26_avg.tst: -------------------------------------------------------------------------------- 1 | # What are we testing here? 2 | {s = s + $1; c = c + 1} 3 | END { 4 | print "sum=", s, " count=", c 5 | print "avg=", s/c 6 | } 7 | ##Input 8 | 17379 mel 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | 9492 sif 18 | 9190 pjw 19 | 8912 nls 20 | 8895 dmr 21 | 8491 cda 22 | 8372 bs 23 | 8252 llc 24 | 7450 mb 25 | 7360 ava 26 | 7273 jrv 27 | 7080 bin 28 | 7063 greg 29 | 6567 dict 30 | 6462 lck 31 | 6291 rje 32 | 6211 lwf 33 | 5671 dave 34 | 5373 jhc 35 | 5220 agf 36 | 5167 doug 37 | 5007 valerie 38 | 3963 jca 39 | 3895 bbs 40 | 1 122sec 41 | 3796 moh 42 | ##Output 43 | sum= 279512 count= 34 44 | avg= 8220.94 45 | ##END -------------------------------------------------------------------------------- /libtest/tests/27_field_change.tst: -------------------------------------------------------------------------------- 1 | #Purpose? 2 | {$6=":::" ; print $6; print NF, $0} 3 | ##Input 4 | first second third fourth fifth sixth seventh 5 | ##Output 6 | ::: 7 | 7 first second third fourth fifth ::: seventh 8 | ##END -------------------------------------------------------------------------------- /libtest/tests/28_filename.tst: -------------------------------------------------------------------------------- 1 | # Per GAWK manual: 2 | # Inside a BEGIN rule, the value of FILENAME is "", because there are no input 3 | # files being processed yet. 4 | # https://www.gnu.org/software/gawk/manual/gawk.html#Auto_002dset 5 | 6 | BEGIN { print FILENAME } 7 | END { print NR } 8 | ##Input 9 | 1 10 | 2 11 | 3 12 | ##Output 13 | 14 | 3 15 | ##END -------------------------------------------------------------------------------- /libtest/tests/29_beginexit.tst: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | while (getline && n++ < 10) 3 | print 4 | exit 5 | } 6 | { print } 7 | ##Input 8 | 17379 mel 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | 9492 sif 18 | 9190 pjw 19 | 8912 nls 20 | 8895 dmr 21 | ##Output 22 | 17379 mel 23 | 16693 bwk me 24 | 16116 ken him someone else 25 | 15713 srb 26 | 11895 lem 27 | 10409 scj 28 | 10252 rhm 29 | 9853 shen 30 | 9748 a68 31 | 9492 sif 32 | ##END -------------------------------------------------------------------------------- /libtest/tests/2_printnr.tst: -------------------------------------------------------------------------------- 1 | #NR should be incremented for each record 2 | {i = i+1; print i, NR} 3 | 4 | ## Input 5 | 1root:EMpNB8Zp56:0:0:Super-User,,,,,,,:/:/bin/sh 6 | 2roottcsh:*:0:0:Super-User running tcsh [cbm]:/:/bin/tcsh 7 | 3sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh 8 | 4diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 9 | 5daemon:*:1:1:daemons:/:/bin/sh 10 | 6bin:*:2:2:System Tools Owner:/bin:/dev/null 11 | 7nuucp:BJnuQbAo:6:10:UUCP.Admin:/usr/spool/uucppublic:/usr/lib/uucp/uucico 12 | 8uucp:*:3:5:UUCP.Admin:/usr/lib/uucp: 13 | 9sys:*:4:0:System Activity Owner:/usr/adm:/bin/sh 14 | 10adm:*:5:3:Accounting Files Owner:/usr/adm:/bin/sh 15 | 11lp:*:9:9:Print Spooler Owner:/var/spool/lp:/bin/sh 16 | 12auditor:*:11:0:Audit Activity Owner:/auditor:/bin/sh 17 | 13dbadmin:*:12:0:Security Database Owner:/dbadmin:/bin/sh 18 | 14bootes:dcon:50:1:Tom Killian (DO NOT REMOVE):/tmp: 19 | 15cdjuke:dcon:51:1:Tom Killian (DO NOT REMOVE):/tmp: 20 | 16rfindd:*:66:1:Rfind Daemon and Fsdump:/var/rfindd:/bin/sh 21 | 17EZsetup:*:992:998:System Setup:/var/sysadmdesktop/EZsetup:/bin/csh 22 | 18demos:*:993:997:Demonstration User:/usr/demos:/bin/csh 23 | 19tutor:*:994:997:Tutorial User:/usr/tutor:/bin/csh 24 | 20tour:*:995:997:IRIS Space Tour:/usr/people/tour:/bin/csh 25 | 21guest:nfP4/Wpvio/Rw:998:998:Guest Account:/usr/people/guest:/bin/csh 26 | 224Dgifts:0nWRTZsOMt.:999:998:4Dgifts Account:/usr/people/4Dgifts:/bin/csh 27 | 23nobody:*:60001:60001:SVR4 nobody uid:/dev/null:/dev/null 28 | 24noaccess:*:60002:60002:uid no access:/dev/null:/dev/null 29 | 25nobody:*:-2:-2:original nobody uid:/dev/null:/dev/null 30 | 26rje:*:8:8:RJE Owner:/usr/spool/rje: 31 | 27changes:*:11:11:system change log:/: 32 | 28dist:sorry:9999:4:file distributions:/v/adm/dist:/v/bin/sh 33 | 29man:*:99:995:On-line Manual Owner:/: 34 | 30phoneca:*:991:991:phone call log [tom]:/v/adm/log:/v/bin/sh 35 | ## Output 36 | 1 1 37 | 2 2 38 | 3 3 39 | 4 4 40 | 5 5 41 | 6 6 42 | 7 7 43 | 8 8 44 | 9 9 45 | 10 10 46 | 11 11 47 | 12 12 48 | 13 13 49 | 14 14 50 | 15 15 51 | 16 16 52 | 17 17 53 | 18 18 54 | 19 19 55 | 20 20 56 | 21 21 57 | 22 22 58 | 23 23 59 | 24 24 60 | 25 25 61 | 26 26 62 | 27 27 63 | 28 28 64 | 29 29 65 | 30 30 66 | ## END 67 | -------------------------------------------------------------------------------- /libtest/tests/30_beginnext.tst: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | while (getline && n++ < 10) 3 | print 4 | print "tenth" 5 | } 6 | { print } 7 | ##Input 8 | 17379 mel 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | 9492 sif 18 | 9190 pjw 19 | 8912 nls 20 | 8895 dmr 21 | ##Output 22 | 17379 mel 23 | 16693 bwk me 24 | 16116 ken him someone else 25 | 15713 srb 26 | 11895 lem 27 | 10409 scj 28 | 10252 rhm 29 | 9853 shen 30 | 9748 a68 31 | 9492 sif 32 | tenth 33 | 8912 nls 34 | 8895 dmr 35 | ##END 36 | 37 | -------------------------------------------------------------------------------- /libtest/tests/31_break.tst: -------------------------------------------------------------------------------- 1 | { 2 | for (i=1; i <= NF; i++) 3 | if ($i ~ /^[a-z|A-Z]+$/) { 4 | print $i " is alphabetic" 5 | break 6 | } 7 | } 8 | ##Input 9 | 1r oot EMpNB8Zp56 0 0 Super-User,,,,,,, / /bin/sh 10 | 2r oottcsh * 0 0 Super-User running tcsh [cbm] / /bin/tcsh 11 | 3s ysadm * 0 0 System V Administration /usr/admin /bin/sh 12 | 4d iag * 0 996 Hardware Diagnostics /usr/diags /bin/csh 13 | 5d aemon * 1 1 daemons / /bin/sh 14 | 6b in * 2 2 System Tools Owner /bin /dev/null 15 | 7n uucp BJnuQbAo 6 10 UUCP.Admin /usr/spool/uucppublic /usr/lib/uucp/uucico 16 | 8u ucp * 3 5 UUCP.Admin /usr/lib/uucp 17 | 9s ys * 4 0 System Activity Owner /usr/adm /bin/sh 18 | 10 adm * 5 3 Accounting Files Owner /usr/adm /bin/sh 19 | 11 lp * 9 9 Print Spooler Owner /var/spool/lp /bin/sh 20 | 12 auditor * 11 0 Audit Activity Owner /auditor /bin/sh 21 | 13 dbadmin * 12 0 Security Database Owner /dbadmin /bin/sh 22 | 14 bootes dcon 50 1 Tom Killian (DO NOT REMOVE) /tmp 23 | 15 cdjuke dcon 51 1 Tom Killian (DO NOT REMOVE) /tmp 24 | 16 rfindd * 66 1 Rfind Daemon and Fsdump /var/rfindd /bin/sh 25 | 17 EZsetup * 992 998 System Setup /var/sysadmdesktop/EZsetup /bin/csh 26 | 18 demos * 993 997 Demonstration User /usr/demos /bin/csh 27 | 19 tutor * 994 997 Tutorial User /usr/tutor /bin/csh 28 | 20 tour * 995 997 IRIS Space Tour /usr/people/tour /bin/csh 29 | 21 guest nfP4/Wpvio/Rw 998 998 Guest Account /usr/people/guest /bin/csh 30 | 22 4Dgifts 0nWRTZsOMt. 999 998 4Dgifts Account /usr/people/4Dgifts /bin/csh 31 | 23 nobody * 60001 60001 SVR4 nobody uid /dev/null /dev/null 32 | 24 noaccess * 60002 60002 uid no access /dev/null /dev/null 33 | ##Output 34 | oot is alphabetic 35 | oottcsh is alphabetic 36 | ysadm is alphabetic 37 | iag is alphabetic 38 | aemon is alphabetic 39 | in is alphabetic 40 | uucp is alphabetic 41 | ucp is alphabetic 42 | ys is alphabetic 43 | adm is alphabetic 44 | lp is alphabetic 45 | auditor is alphabetic 46 | dbadmin is alphabetic 47 | bootes is alphabetic 48 | cdjuke is alphabetic 49 | rfindd is alphabetic 50 | EZsetup is alphabetic 51 | demos is alphabetic 52 | tutor is alphabetic 53 | tour is alphabetic 54 | guest is alphabetic 55 | Account is alphabetic 56 | nobody is alphabetic 57 | noaccess is alphabetic 58 | ##END 59 | 60 | -------------------------------------------------------------------------------- /libtest/tests/32_break.tst: -------------------------------------------------------------------------------- 1 | { x[NR] = $0 } 2 | END { 3 | for (i = 1; i <= NR; i++) { 4 | print i, x[i] 5 | if (x[i] ~ /shen/) 6 | break 7 | } 8 | print "got here" 9 | print i, x[i] 10 | } 11 | ##Input 12 | 17379 mel 13 | 16693 bwk me 14 | 16116 ken him someone else 15 | 15713 srb 16 | 11895 lem 17 | 10409 scj 18 | 10252 rhm 19 | 9853 shen 20 | 9748 a68 21 | 9492 sif 22 | 9190 pjw 23 | 8912 nls 24 | 8895 dmr 25 | 8491 cda 26 | 8372 bs 27 | 8252 llc 28 | ##Output 29 | 1 17379 mel 30 | 2 16693 bwk me 31 | 3 16116 ken him someone else 32 | 4 15713 srb 33 | 5 11895 lem 34 | 6 10409 scj 35 | 7 10252 rhm 36 | 8 9853 shen 37 | got here 38 | 8 9853 shen 39 | ##END 40 | -------------------------------------------------------------------------------- /libtest/tests/33_break.tst: -------------------------------------------------------------------------------- 1 | { for (i = 1; i <= NF; i++) { 2 | for (j = 1; j <= NF; j++) 3 | if (j == 2) 4 | break; 5 | print "inner", i, j 6 | } 7 | print "outer", i, j 8 | } 9 | 10 | ##Input 11 | 17379 mel 12 | 16693 bwk me 13 | 16116 ken him someone else 14 | 15713 srb 15 | 11895 lem 16 | 10409 scj 17 | 10252 rhm 18 | 9853 shen 19 | 9748 a68 20 | 9492 sif 21 | 9190 pjw 22 | 8912 nls 23 | 8895 dmr 24 | 8491 cda 25 | 8372 bs 26 | 8252 llc 27 | ##Output 28 | inner 1 2 29 | inner 2 2 30 | outer 3 2 31 | inner 1 2 32 | inner 2 2 33 | inner 3 2 34 | outer 4 2 35 | inner 1 2 36 | inner 2 2 37 | inner 3 2 38 | inner 4 2 39 | inner 5 2 40 | outer 6 2 41 | inner 1 2 42 | inner 2 2 43 | outer 3 2 44 | inner 1 2 45 | inner 2 2 46 | outer 3 2 47 | inner 1 2 48 | inner 2 2 49 | outer 3 2 50 | inner 1 2 51 | inner 2 2 52 | outer 3 2 53 | inner 1 2 54 | inner 2 2 55 | outer 3 2 56 | inner 1 2 57 | inner 2 2 58 | outer 3 2 59 | inner 1 2 60 | inner 2 2 61 | outer 3 2 62 | inner 1 2 63 | inner 2 2 64 | outer 3 2 65 | inner 1 2 66 | inner 2 2 67 | outer 3 2 68 | inner 1 2 69 | inner 2 2 70 | outer 3 2 71 | inner 1 2 72 | inner 2 2 73 | outer 3 2 74 | inner 1 2 75 | inner 2 2 76 | outer 3 2 77 | inner 1 2 78 | inner 2 2 79 | outer 3 2 80 | ##END -------------------------------------------------------------------------------- /libtest/tests/34_missing_field.tst: -------------------------------------------------------------------------------- 1 | # this program fails if awk is created without separate I&D 2 | # prints garbage if no $3 3 | # Mircea - No, it doesn't. It prints an empty field which is quite sensible 4 | 5 | { print $1, $3 } 6 | 7 | ##Input 8 | 17379 mel 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | 9492 sif 18 | 9190 pjw 19 | 8912 nls 20 | 8895 dmr 21 | 8491 cda 22 | 8372 bs 23 | 8252 llc 24 | ##Output 25 | 17379 26 | 16693 me 27 | 16116 him 28 | 15713 29 | 11895 30 | 10409 31 | 10252 32 | 9853 33 | 9748 34 | 9492 35 | 9190 36 | 8912 37 | 8895 38 | 8491 39 | 8372 40 | 8252 41 | ##END -------------------------------------------------------------------------------- /libtest/tests/35_builtins.tst: -------------------------------------------------------------------------------- 1 | #Some builtin math functions 2 | /^[0-9]/ { print $1, 3 | length($1), 4 | log($1), 5 | sqrt($1), 6 | int(sqrt($1)), 7 | exp($1 % 10) } 8 | ##Input 9 | 16 10 | 25 11 | 100 12 | 30 13 | 4 14 | ##Output 15 | 16 2 2.77259 4 4 403.429 16 | 25 2 3.21888 5 5 148.413 17 | 100 3 4.60517 10 10 1 18 | 30 2 3.4012 5.47723 5 1 19 | 4 1 1.38629 2 2 54.5982 20 | ##END -------------------------------------------------------------------------------- /libtest/tests/36_cat.tst: -------------------------------------------------------------------------------- 1 | {print $2 " " $1} 2 | {print $1 " " "is", $2} 3 | {print $2 FS "is" FS $1} 4 | {print length($1 $2), length($1) + length($2)} 5 | ## Input 6 | cat green 7 | dog blue 8 | bird yellow 9 | ## Output 10 | green cat 11 | cat is green 12 | green is cat 13 | 8 8 14 | blue dog 15 | dog is blue 16 | blue is dog 17 | 7 7 18 | yellow bird 19 | bird is yellow 20 | yellow is bird 21 | 10 10 22 | ##END -------------------------------------------------------------------------------- /libtest/tests/37_cat.tst: -------------------------------------------------------------------------------- 1 | {print x $0} # should precede by zero. Mircea - no, it shouldn't! 2 | # x is an empty string. To force conversion to number read the manual or see below. 3 | {print 0+x $0} 4 | ##Input 5 | alpha 6 | beta 7 | gamma 8 | delta 9 | ##Output 10 | alpha 11 | 0alpha 12 | beta 13 | 0beta 14 | gamma 15 | 0gamma 16 | delta 17 | 0delta 18 | ##END -------------------------------------------------------------------------------- /libtest/tests/38_cat.tst: -------------------------------------------------------------------------------- 1 | {$1 = $1 "*"; print} 2 | 3 | ##Input 4 | alpha 5 | beta 6 | gamma 7 | delta 8 | ## 9 | alpha* 10 | beta* 11 | gamma* 12 | delta* 13 | ## -------------------------------------------------------------------------------- /libtest/tests/39_cmp.tst: -------------------------------------------------------------------------------- 1 | $2 > $1 2 | ##Input 3 | 1 2 4 | 2 1 5 | 2 3 6 | 3 2 7 | 4 3 8 | 3 4 9 | ## Output 10 | 1 2 11 | 2 3 12 | 3 4 13 | ##END -------------------------------------------------------------------------------- /libtest/tests/3_changefs.tst: -------------------------------------------------------------------------------- 1 | #change field separator character 2 | BEGIN {FS=":"} 3 | {print $1, $2, $3} 4 | 5 | ##Input 6 | 1root:EMpNB8Zp56:0:0:Super-User,,,,,,,:/:/bin/sh 7 | 2roottcsh:*:0:0:Super-User running tcsh [cbm]:/:/bin/tcsh 8 | 3sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh 9 | 4diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 10 | 5daemon:*:1:1:daemons:/:/bin/sh 11 | 6bin:*:2:2:System Tools Owner:/bin:/dev/null 12 | 7nuucp:BJnuQbAo:6:10:UUCP.Admin:/usr/spool/uucppublic:/usr/lib/uucp/uucico 13 | 8uucp:*:3:5:UUCP.Admin:/usr/lib/uucp: 14 | 9sys:*:4:0:System Activity Owner:/usr/adm:/bin/sh 15 | 10adm:*:5:3:Accounting Files Owner:/usr/adm:/bin/sh 16 | 11lp:*:9:9:Print Spooler Owner:/var/spool/lp:/bin/sh 17 | 12auditor:*:11:0:Audit Activity Owner:/auditor:/bin/sh 18 | 13dbadmin:*:12:0:Security Database Owner:/dbadmin:/bin/sh 19 | 14bootes:dcon:50:1:Tom Killian (DO NOT REMOVE):/tmp: 20 | 15cdjuke:dcon:51:1:Tom Killian (DO NOT REMOVE):/tmp: 21 | 16rfindd:*:66:1:Rfind Daemon and Fsdump:/var/rfindd:/bin/sh 22 | 17EZsetup:*:992:998:System Setup:/var/sysadmdesktop/EZsetup:/bin/csh 23 | 18demos:*:993:997:Demonstration User:/usr/demos:/bin/csh 24 | 19tutor:*:994:997:Tutorial User:/usr/tutor:/bin/csh 25 | 20tour:*:995:997:IRIS Space Tour:/usr/people/tour:/bin/csh 26 | 21guest:nfP4/Wpvio/Rw:998:998:Guest Account:/usr/people/guest:/bin/csh 27 | 224Dgifts:0nWRTZsOMt.:999:998:4Dgifts Account:/usr/people/4Dgifts:/bin/csh 28 | 23nobody:*:60001:60001:SVR4 nobody uid:/dev/null:/dev/null 29 | 24noaccess:*:60002:60002:uid no access:/dev/null:/dev/null 30 | 25nobody:*:-2:-2:original nobody uid:/dev/null:/dev/null 31 | 26rje:*:8:8:RJE Owner:/usr/spool/rje: 32 | 27changes:*:11:11:system change log:/: 33 | 28dist:sorry:9999:4:file distributions:/v/adm/dist:/v/bin/sh 34 | 29man:*:99:995:On-line Manual Owner:/: 35 | 30phoneca:*:991:991:phone call log [tom]:/v/adm/log:/v/bin/sh 36 | ##Output 37 | 1root EMpNB8Zp56 0 38 | 2roottcsh * 0 39 | 3sysadm * 0 40 | 4diag * 0 41 | 5daemon * 1 42 | 6bin * 2 43 | 7nuucp BJnuQbAo 6 44 | 8uucp * 3 45 | 9sys * 4 46 | 10adm * 5 47 | 11lp * 9 48 | 12auditor * 11 49 | 13dbadmin * 12 50 | 14bootes dcon 50 51 | 15cdjuke dcon 51 52 | 16rfindd * 66 53 | 17EZsetup * 992 54 | 18demos * 993 55 | 19tutor * 994 56 | 20tour * 995 57 | 21guest nfP4/Wpvio/Rw 998 58 | 224Dgifts 0nWRTZsOMt. 999 59 | 23nobody * 60001 60 | 24noaccess * 60002 61 | 25nobody * -2 62 | 26rje * 8 63 | 27changes * 11 64 | 28dist sorry 9999 65 | 29man * 99 66 | 30phoneca * 991 67 | ## END 68 | -------------------------------------------------------------------------------- /libtest/tests/40_coerce.tst: -------------------------------------------------------------------------------- 1 | #What are we testing here? 2 | END { print i, NR 3 | if (i < NR) 4 | print i, NR 5 | } 6 | ##Input 7 | Rec 8 | ##Output 9 | 1 10 | 1 11 | ##END -------------------------------------------------------------------------------- /libtest/tests/41_coerce.tst: -------------------------------------------------------------------------------- 1 | { 2 | print index(1, $1) #Seriously? 3 | print substr(123456789, 1, 3) 4 | print 1 in x 5 | print 1 23 456 6 | print 123456789 ~ 123, 123456789 ~ "abc" 7 | } 8 | ## Input 9 | 1 10 | aaa 11 | ##Output 12 | 1 13 | 123 14 | 0 15 | 123456 16 | 1 0 17 | 0 18 | 123 19 | 0 20 | 123456 21 | 1 0 22 | ##END 23 | -------------------------------------------------------------------------------- /libtest/tests/42_comment.tst: -------------------------------------------------------------------------------- 1 | # this is a comment line 2 | # so is this 3 | /#/ { print "this one has a # in it: " $0 # comment 4 | print "again:" $0 5 | } 6 | ##Input 7 | alpha 8 | #beta 9 | gamma 10 | ## Output 11 | this one has a # in it: #beta 12 | again:#beta 13 | ##END -------------------------------------------------------------------------------- /libtest/tests/43_comment.tst: -------------------------------------------------------------------------------- 1 | #comment 2 | # 3 | BEGIN { x = 1 } 4 | /abc/ { print $0 } 5 | #comment 6 | END { print NR } 7 | #comment 8 | 9 | ## Input 10 | 123 11 | 456 12 | abcdef 13 | ghijkl 14 | ##Output 15 | abcdef 16 | 4 17 | ##END 18 | 19 | -------------------------------------------------------------------------------- /libtest/tests/44_concat.tst: -------------------------------------------------------------------------------- 1 | { x = $1; print x (++i) } 2 | 3 | ## Input 4 | alpha 5 | beta 6 | gamma 7 | delta 8 | ## Output 9 | alpha1 10 | beta2 11 | gamma3 12 | delta4 13 | ## END -------------------------------------------------------------------------------- /libtest/tests/45_cond.tst: -------------------------------------------------------------------------------- 1 | { print (substr($2,1,1) > substr($2,2,1)) ? $1 : $2 } 2 | { x = substr($1, 1, 1); y = substr($1, 2, 1); z = substr($1, 3, 1) 3 | print (x > y ? (x > z ? x : z) : y > z ? y : z) } 4 | 5 | ##Input 6 | 17379 mel 7 | 16693 bwk me 8 | 16116 ken him someone else 9 | 15713 srb 10 | 11895 lem 11 | 10409 scj 12 | 10252 rhm 13 | 9853 shen 14 | 9748 a68 15 | 9492 sif 16 | 9190 pjw 17 | 8912 nls 18 | 8895 dmr 19 | 8491 cda 20 | 8372 bs 21 | 8252 llc 22 | ##Output 23 | 17379 24 | 7 25 | bwk 26 | 6 27 | 16116 28 | 6 29 | 15713 30 | 7 31 | 11895 32 | 8 33 | 10409 34 | 4 35 | 10252 36 | 2 37 | 9853 38 | 9 39 | 9748 40 | 9 41 | 9492 42 | 9 43 | 9190 44 | 9 45 | 8912 46 | 9 47 | dmr 48 | 9 49 | cda 50 | 9 51 | bs 52 | 8 53 | llc 54 | 8 55 | ## END -------------------------------------------------------------------------------- /libtest/tests/46_contin.tst: -------------------------------------------------------------------------------- 1 | { 2 | for (i = 1; i <= NF; i++) { 3 | if ($i ~ /^[0-9]+$/) 4 | continue; 5 | print $i, " is non-numeric" 6 | next 7 | } 8 | print $0, "is all numeric" 9 | } 10 | ## Input 11 | abc 456 789 12 | 123 def 789 13 | 123 456 ghi 14 | 123 456 789 15 | ## Output 16 | abc is non-numeric 17 | def is non-numeric 18 | ghi is non-numeric 19 | 123 456 789 is all numeric 20 | ## 21 | -------------------------------------------------------------------------------- /libtest/tests/47_count.tst: -------------------------------------------------------------------------------- 1 | END { print NR } 2 | 3 | ##Input 4 | abc 5 | def 6 | ghi 7 | 123 8 | 456 9 | 789 10 | ##Output 11 | 6 12 | ##END -------------------------------------------------------------------------------- /libtest/tests/48_crlf.tst: -------------------------------------------------------------------------------- 1 | # checks whether lines with crlf are parsed ok 2 | 3 | {print \ 4 | } 5 | 6 | ## Input 7 | abc 8 | def 9 | ## Output 10 | abc 11 | def 12 | ##END -------------------------------------------------------------------------------- /libtest/tests/49_acum.tst: -------------------------------------------------------------------------------- 1 | # Accumulator? 2 | {i = i + $1; print i} 3 | END { 4 | print i 5 | } 6 | 7 | ##Input 8 | 1 9 | 2 10 | 3 11 | 4 12 | 5 13 | 6 14 | 7 15 | 8 16 | 9 17 | 10 18 | ##Output 19 | 1 20 | 3 21 | 6 22 | 10 23 | 15 24 | 21 25 | 28 26 | 36 27 | 45 28 | 55 29 | 55 30 | ##END 31 | -------------------------------------------------------------------------------- /libtest/tests/4_changeofs.tst: -------------------------------------------------------------------------------- 1 | #changes OFS character 2 | BEGIN {FS=":"; OFS="==="} 3 | {print $1, $2, $3} 4 | 5 | ##Input 6 | 1root:EMpNB8Zp56:0:0:Super-User,,,,,,,:/:/bin/sh 7 | 2roottcsh:*:0:0:Super-User running tcsh [cbm]:/:/bin/tcsh 8 | 3sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh 9 | 4diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 10 | 5daemon:*:1:1:daemons:/:/bin/sh 11 | 6bin:*:2:2:System Tools Owner:/bin:/dev/null 12 | 7nuucp:BJnuQbAo:6:10:UUCP.Admin:/usr/spool/uucppublic:/usr/lib/uucp/uucico 13 | 8uucp:*:3:5:UUCP.Admin:/usr/lib/uucp: 14 | 9sys:*:4:0:System Activity Owner:/usr/adm:/bin/sh 15 | 10adm:*:5:3:Accounting Files Owner:/usr/adm:/bin/sh 16 | 11lp:*:9:9:Print Spooler Owner:/var/spool/lp:/bin/sh 17 | 12auditor:*:11:0:Audit Activity Owner:/auditor:/bin/sh 18 | 13dbadmin:*:12:0:Security Database Owner:/dbadmin:/bin/sh 19 | 14bootes:dcon:50:1:Tom Killian (DO NOT REMOVE):/tmp: 20 | 15cdjuke:dcon:51:1:Tom Killian (DO NOT REMOVE):/tmp: 21 | 16rfindd:*:66:1:Rfind Daemon and Fsdump:/var/rfindd:/bin/sh 22 | 17EZsetup:*:992:998:System Setup:/var/sysadmdesktop/EZsetup:/bin/csh 23 | 18demos:*:993:997:Demonstration User:/usr/demos:/bin/csh 24 | 19tutor:*:994:997:Tutorial User:/usr/tutor:/bin/csh 25 | 20tour:*:995:997:IRIS Space Tour:/usr/people/tour:/bin/csh 26 | 21guest:nfP4/Wpvio/Rw:998:998:Guest Account:/usr/people/guest:/bin/csh 27 | 224Dgifts:0nWRTZsOMt.:999:998:4Dgifts Account:/usr/people/4Dgifts:/bin/csh 28 | 23nobody:*:60001:60001:SVR4 nobody uid:/dev/null:/dev/null 29 | 24noaccess:*:60002:60002:uid no access:/dev/null:/dev/null 30 | 25nobody:*:-2:-2:original nobody uid:/dev/null:/dev/null 31 | 26rje:*:8:8:RJE Owner:/usr/spool/rje: 32 | 27changes:*:11:11:system change log:/: 33 | 28dist:sorry:9999:4:file distributions:/v/adm/dist:/v/bin/sh 34 | 29man:*:99:995:On-line Manual Owner:/: 35 | 30phoneca:*:991:991:phone call log [tom]:/v/adm/log:/v/bin/sh 36 | ##Output 37 | 1root===EMpNB8Zp56===0 38 | 2roottcsh===*===0 39 | 3sysadm===*===0 40 | 4diag===*===0 41 | 5daemon===*===1 42 | 6bin===*===2 43 | 7nuucp===BJnuQbAo===6 44 | 8uucp===*===3 45 | 9sys===*===4 46 | 10adm===*===5 47 | 11lp===*===9 48 | 12auditor===*===11 49 | 13dbadmin===*===12 50 | 14bootes===dcon===50 51 | 15cdjuke===dcon===51 52 | 16rfindd===*===66 53 | 17EZsetup===*===992 54 | 18demos===*===993 55 | 19tutor===*===994 56 | 20tour===*===995 57 | 21guest===nfP4/Wpvio/Rw===998 58 | 224Dgifts===0nWRTZsOMt.===999 59 | 23nobody===*===60001 60 | 24noaccess===*===60002 61 | 25nobody===*===-2 62 | 26rje===*===8 63 | 27changes===*===11 64 | 28dist===sorry===9999 65 | 29man===*===99 66 | 30phoneca===*===991 67 | ##END -------------------------------------------------------------------------------- /libtest/tests/50_fsofs.tst: -------------------------------------------------------------------------------- 1 | BEGIN {FS=":" ; OFS=":"} 2 | {print NF " ",$0} 3 | 4 | ##Input 5 | 1root:EMpNB8Zp56:0:0:Super-User,,,,,,,:/:/bin/sh 6 | 2roottcsh:*:0:0:Super-User running tcsh [cbm]:/:/bin/tcsh 7 | 3sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh 8 | 4diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 9 | 5daemon:*:1:1:daemons:/:/bin/sh 10 | 6bin:*:2:2:System Tools Owner:/bin:/dev/null 11 | 7nuucp:BJnuQbAo:6:10:UUCP.Admin:/usr/spool/uucppublic:/usr/lib/uucp/uucico 12 | 8uucp:*:3:5:UUCP.Admin:/usr/lib/uucp: 13 | 9sys:*:4:0:System Activity Owner:/usr/adm:/bin/sh 14 | 10adm:*:5:3:Accounting Files Owner:/usr/adm:/bin/sh 15 | ##Output 16 | 7 :1root:EMpNB8Zp56:0:0:Super-User,,,,,,,:/:/bin/sh 17 | 7 :2roottcsh:*:0:0:Super-User running tcsh [cbm]:/:/bin/tcsh 18 | 7 :3sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh 19 | 7 :4diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh 20 | 7 :5daemon:*:1:1:daemons:/:/bin/sh 21 | 7 :6bin:*:2:2:System Tools Owner:/bin:/dev/null 22 | 7 :7nuucp:BJnuQbAo:6:10:UUCP.Admin:/usr/spool/uucppublic:/usr/lib/uucp/uucico 23 | 7 :8uucp:*:3:5:UUCP.Admin:/usr/lib/uucp: 24 | 7 :9sys:*:4:0:System Activity Owner:/usr/adm:/bin/sh 25 | 7 :10adm:*:5:3:Accounting Files Owner:/usr/adm:/bin/sh 26 | ##End 27 | -------------------------------------------------------------------------------- /libtest/tests/51_delete.tst: -------------------------------------------------------------------------------- 1 | NF > 0 { 2 | n = split($0, x) 3 | if (n != NF) 4 | printf("split screwed up %d %d\n", n, NF) 5 | delete x[1] 6 | k = 0 7 | for (i in x) 8 | k++ 9 | if (k != NF-1) 10 | printf "delete miscount %d elems should be %d at line %d\n", k, NF-1, NR 11 | } 12 | 13 | ##Input 14 | Now 15 | Now is 16 | Now is the 17 | Now is the time 18 | Now is the time for 19 | Now is the time for all 20 | Now is the time for all good 21 | Now is the time for all good men 22 | Now is the time for all good men to 23 | Now is the time for all good men to come 24 | Now is the time for all good men to come to 25 | Now is the time for all good men to come to the 26 | Now is the time for all good men to come to the aid 27 | Now is the time for all good men to come to the aid of 28 | Now is the time for all good men to come to the aid of the 29 | Now is the time for all good men to come to the aid of the party. 30 | ## 31 | ##END 32 | -------------------------------------------------------------------------------- /libtest/tests/52_delete.tst: -------------------------------------------------------------------------------- 1 | { split("1 1.2 abc", x) 2 | x[$1]++ 3 | delete x[1] 4 | delete x[1.2] 5 | delete x["abc"] 6 | delete x[$1] 7 | delete x[0] 8 | } 9 | ##Input 10 | 3 11 | 4 12 | 5 13 | ##Output 14 | ##END 15 | -------------------------------------------------------------------------------- /libtest/tests/53_delete.tst: -------------------------------------------------------------------------------- 1 | NR < 50 { 2 | n = split($0, x) 3 | for (i = 1; i <= n; i++) 4 | for (j = 1; j <= n; j++) 5 | y[i,j] = n * i + j 6 | 7 | for (i = 1; i <= n; i++) 8 | delete y[i,i] 9 | k = 0 10 | for (i in y) 11 | k++ 12 | if (k != int(n^2-n)) 13 | printf "delete2 miscount %d vs %d at %d\n", k, n^2-n, NR 14 | } 15 | ## Input 16 | Now 17 | Now is 18 | Now is the 19 | Now is the time 20 | Now is the time for 21 | Now is the time for all 22 | Now is the time for all good 23 | Now is the time for all good men 24 | Now is the time for all good men to 25 | Now is the time for all good men to come 26 | Now is the time for all good men to come to 27 | Now is the time for all good men to come to the 28 | Now is the time for all good men to come to the aid 29 | Now is the time for all good men to come to the aid of 30 | Now is the time for all good men to come to the aid of the 31 | Now is the time for all good men to come to the aid of the party. 32 | ## 33 | ##END 34 | -------------------------------------------------------------------------------- /libtest/tests/54_delete.tst: -------------------------------------------------------------------------------- 1 | { x[$1] = $1 2 | delete x[$1] 3 | n = 0 4 | for (i in x) n++ 5 | if (n != 0) 6 | print "error", n, "at", NR 7 | } 8 | ##Input 9 | Now 10 | Now is 11 | Now is the 12 | Now is the time 13 | Now is the time for 14 | Now is the time for all 15 | Now is the time for all good 16 | Now is the time for all good men 17 | Now is the time for all good men to 18 | Now is the time for all good men to come 19 | Now is the time for all good men to come to 20 | Now is the time for all good men to come to the 21 | Now is the time for all good men to come to the aid 22 | Now is the time for all good men to come to the aid of 23 | Now is the time for all good men to come to the aid of the 24 | Now is the time for all good men to come to the aid of the party. 25 | ## 26 | ##END 27 | 28 | -------------------------------------------------------------------------------- /libtest/tests/55_do.tst: -------------------------------------------------------------------------------- 1 | NF > 0 { 2 | t = $0 3 | gsub(/[ \t]+/, "", t) 4 | n = split($0, y) 5 | if (n > 0) { 6 | i = 1 7 | s = "" 8 | do { 9 | s = s $i 10 | } while (i++ < NF) 11 | } 12 | if (s != t) 13 | print "bad at", NR 14 | } 15 | ##Input 16 | Now 17 | Now is 18 | Now is the 19 | Now is the time 20 | Now is the time for 21 | Now is the time for all 22 | Now is the time for all good 23 | Now is the time for all good men 24 | Now is the time for all good men to 25 | Now is the time for all good men to come 26 | Now is the time for all good men to come to 27 | Now is the time for all good men to come to the 28 | Now is the time for all good men to come to the aid 29 | Now is the time for all good men to come to the aid of 30 | Now is the time for all good men to come to the aid of the 31 | Now is the time for all good men to come to the aid of the party. 32 | ## 33 | ##END 34 | -------------------------------------------------------------------------------- /libtest/tests/56_or_expr.tst: -------------------------------------------------------------------------------- 1 | $1 < 10 || $2 ~ /bwk/ 2 | ##Input 3 | 17379 mel 4 | 16693 bwk me 5 | 16116 ken him someone else 6 | 15713 srb 7 | 11895 lem 8 | 10409 scj 9 | 10252 rhm 10 | 9853 shen 11 | 9748 a68 12 | 9492 sif 13 | 9190 pjw 14 | 8912 nls 15 | 8895 dmr 16 | 8491 cda 17 | 8372 bs 18 | 8252 llc 19 | 7450 mb 20 | 7360 ava 21 | 7273 jrv 22 | 7080 bin 23 | 7063 greg 24 | 6567 dict 25 | 6462 lck 26 | 6291 rje 27 | 6211 lwf 28 | 5671 dave 29 | 5373 jhc 30 | 5220 agf 31 | 5167 doug 32 | 5007 valerie 33 | 3963 jca 34 | 3895 bbs 35 | 3796 moh 36 | 3481 xchar 37 | 3200 tbl 38 | 2845 s 39 | 2774 tgs 40 | 2641 met 41 | 2566 jck 42 | 2511 port 43 | 2479 sue 44 | 2127 root 45 | 1989 bsb 46 | 1989 jeg 47 | 1933 eag 48 | 1801 pdj 49 | 1590 tpc 50 | 1385 cvw 51 | 1370 rwm 52 | 1316 avg 53 | 1205 eg 54 | 1194 jam 55 | 1153 dl 56 | 1150 lgm 57 | 1031 cmb 58 | 1018 jwr 59 | 950 gdb 60 | 931 marc 61 | 898 usg 62 | 865 ggr 63 | 822 daemon 64 | 803 mihalis 65 | 700 honey 66 | 624 tad 67 | 559 acs 68 | 541 uucp 69 | 523 raf 70 | 495 adh 71 | 456 kec 72 | 414 craig 73 | 386 donmac 74 | 375 jj 75 | 348 ravi 76 | 344 drw 77 | 327 stars 78 | 288 mrg 79 | 272 jcb 80 | 263 ralph 81 | 253 tom 82 | 251 sjb 83 | 248 haight 84 | 224 sharon 85 | 222 chuck 86 | 213 dsj 87 | 201 bill 88 | 184 god 89 | 176 sys 90 | 166 meh 91 | 163 jon 92 | 144 dan 93 | 143 fox 94 | 123 dale 95 | 116 kab 96 | 95 buz 97 | 80 asc 98 | 79 jas 99 | 79 trt 100 | 64 wsb 101 | 62 dwh 102 | 56 ktf 103 | 54 lr 104 | 47 dlc 105 | 45 dls 106 | 45 jwf 107 | 44 mash 108 | 43 ars 109 | 43 vgl 110 | 37 jfo 111 | 32 rab 112 | 31 pd 113 | 29 jns 114 | 25 spm 115 | 22 rob 116 | 15 egb 117 | 10 hm 118 | 10 mhb 119 | 6 aed 120 | 6 cpb 121 | 5 evp 122 | 4 ber 123 | 4 men 124 | 4 mitch 125 | 3 ast 126 | 3 jfr 127 | 3 lax 128 | 3 nel 129 | 2 blue 130 | 2 jfk 131 | 2 njas 132 | 1 122sec 133 | 1 ddwar 134 | 1 gopi 135 | 1 jk 136 | 1 learn 137 | 1 low 138 | 1 nac 139 | 1 sidor 140 | ##Output 141 | 16693 bwk me 142 | 6 aed 143 | 6 cpb 144 | 5 evp 145 | 4 ber 146 | 4 men 147 | 4 mitch 148 | 3 ast 149 | 3 jfr 150 | 3 lax 151 | 3 nel 152 | 2 blue 153 | 2 jfk 154 | 2 njas 155 | 1 122sec 156 | 1 ddwar 157 | 1 gopi 158 | 1 jk 159 | 1 learn 160 | 1 low 161 | 1 nac 162 | 1 sidor 163 | ##END -------------------------------------------------------------------------------- /libtest/tests/57_else.tst: -------------------------------------------------------------------------------- 1 | { if($1>1000) print $1,"yes" 2 | else print $1,"no" 3 | } 4 | ##Input 5 | 1 mel 6 | 2000 bwk me 7 | 3000 ken him someone else 8 | 2 srb 9 | ##Output 10 | 1 no 11 | 2000 yes 12 | 3000 yes 13 | 2 no 14 | ## END 15 | -------------------------------------------------------------------------------- /libtest/tests/58_exit.tst: -------------------------------------------------------------------------------- 1 | { print } 2 | $1 > 5000 { exit NR } 3 | 4 | ## Input 5 | 1 6 | 5 7 | 10 8 | 50 9 | 100 10 | 500 11 | 1000 12 | 5000 13 | 10000 14 | 50000 15 | 100000 16 | 500000 17 | ## Output 18 | 1 19 | 5 20 | 10 21 | 50 22 | 100 23 | 500 24 | 1000 25 | 5000 26 | 10000 27 | ## end -------------------------------------------------------------------------------- /libtest/tests/59_exit.tst: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "this is before calling myabort" 3 | myabort(1) 4 | print "this is after calling myabort" 5 | } 6 | function myabort(n) { 7 | print "in myabort - before exit", n 8 | exit 2 9 | print "in myabort - after exit" 10 | } 11 | END { 12 | print "into END" 13 | myabort(2) 14 | print "should not see this" 15 | } 16 | ##Input 17 | ##Output 18 | this is before calling myabort 19 | in myabort - before exit 1 20 | into END 21 | in myabort - before exit 2 22 | ## end 23 | -------------------------------------------------------------------------------- /libtest/tests/5_concat.tst: -------------------------------------------------------------------------------- 1 | #string concatenation 2 | {i="count" $1 $2; print i , $0} 3 | 4 | ##Input 5 | 17379 mel 6 | 16693 bwk me 7 | 16116 ken him someone else 8 | 15713 srb 9 | 11895 lem 10 | 10409 scj 11 | 10252 rhm 12 | 9853 shen 13 | 9748 a68 14 | 9492 sif 15 | 9190 pjw 16 | 8912 nls 17 | 8895 dmr 18 | 8491 cda 19 | 8372 bs 20 | 8252 llc 21 | ##Output 22 | count17379mel 17379 mel 23 | count16693bwk 16693 bwk me 24 | count16116ken 16116 ken him someone else 25 | count15713srb 15713 srb 26 | count11895lem 11895 lem 27 | count10409scj 10409 scj 28 | count10252rhm 10252 rhm 29 | count9853shen 9853 shen 30 | count9748a68 9748 a68 31 | count9492sif 9492 sif 32 | count9190pjw 9190 pjw 33 | count8912nls 8912 nls 34 | count8895dmr 8895 dmr 35 | count8491cda 8491 cda 36 | count8372bs 8372 bs 37 | count8252llc 8252 llc 38 | ##END -------------------------------------------------------------------------------- /libtest/tests/60_diveq_pattern.tst: -------------------------------------------------------------------------------- 1 | $0 ~ /\=AB/ {print "pat1", $0} 2 | $0 ~ /= AB/ {print "pat2", $0} 3 | 4 | ## Input 5 | =ABBA 6 | ==AB=BA 7 | AB=CD 8 | = ABBA 9 | ## Output 10 | pat1 =ABBA 11 | pat1 ==AB=BA 12 | pat2 = ABBA 13 | ##END -------------------------------------------------------------------------------- /libtest/tests/61_multiple_begin.tst: -------------------------------------------------------------------------------- 1 | BEGIN {print "Begin 1"} 2 | {print $0} 3 | BEGIN {print "Begin 2"} 4 | 5 | ## Input 6 | 17379 mel 7 | 16693 bwk me 8 | 16116 ken him someone else 9 | 15713 srb 10 | 11895 lem 11 | 10409 scj 12 | 10252 rhm 13 | ## Output 14 | Begin 1 15 | Begin 2 16 | 17379 mel 17 | 16693 bwk me 18 | 16116 ken him someone else 19 | 15713 srb 20 | 11895 lem 21 | 10409 scj 22 | 10252 rhm 23 | -------------------------------------------------------------------------------- /libtest/tests/62_nflvar.tst: -------------------------------------------------------------------------------- 1 | # Test if NF can be used on left side of assignment 2 | { 3 | print "NF=",NF 4 | NF += 2 5 | print "New NF=", NF 6 | $0 = "rec 1 modified" 7 | print "Modified NF=", NF 8 | } 9 | 10 | ## 11 | rec 1 12 | ## 13 | NF= 2 14 | New NF= 4 15 | Modified NF= 3 16 | ##END 17 | -------------------------------------------------------------------------------- /libtest/tests/63_fun.tst: -------------------------------------------------------------------------------- 1 | # function call 2 | function g() { return "{" f() "}" } 3 | function f() { return $1 } 4 | { print "<" g() ">" } 5 | ##Input 6 | /dev/rrp3: 7 | 8 | 17379 mel 9 | 16693 bwk me 10 | 16116 ken him someone else 11 | 15713 srb 12 | 11895 lem 13 | 10409 scj 14 | 10252 rhm 15 | 9853 shen 16 | 9748 a68 17 | ## Output 18 | <{/dev/rrp3:}> 19 | <{}> 20 | <{17379}> 21 | <{16693}> 22 | <{16116}> 23 | <{15713}> 24 | <{11895}> 25 | <{10409}> 26 | <{10252}> 27 | <{9853}> 28 | <{9748}> 29 | -------------------------------------------------------------------------------- /libtest/tests/64_funarg.tst: -------------------------------------------------------------------------------- 1 | # Function with argument 2 | function f(a) { print "hello"; return a } 3 | { print "<" f($1) ">" } 4 | ## Input 5 | rec1 6 | rec2 7 | rec3 8 | ## Output 9 | hello 10 | 11 | hello 12 | 13 | hello 14 | 15 | ## -------------------------------------------------------------------------------- /libtest/tests/64_recursive.tst: -------------------------------------------------------------------------------- 1 | # Factorial function 2 | function fact(n) { 3 | k++ 4 | if (n == 1) return 1 5 | return n * fact(n-1) 6 | } 7 | { k = 0; print fact($1), "(" k " calls)" } 8 | ## Input 9 | 1 10 | 2 11 | 3 12 | 5 13 | 10 14 | ## Output 15 | 1 (1 calls) 16 | 2 (2 calls) 17 | 6 (3 calls) 18 | 120 (5 calls) 19 | 3628800 (10 calls) 20 | ## end 21 | -------------------------------------------------------------------------------- /libtest/tests/65_funackermann.tst: -------------------------------------------------------------------------------- 1 | # Ackermann function 2 | function ack(m,n) { 3 | k = k+1 4 | if (m == 0) return n+1 5 | if (n == 0) return ack(m-1, 1) 6 | return ack(m-1, ack(m, n-1)) 7 | } 8 | { k = 0; print ack($1,$2), "(" k " calls)" } 9 | ## Input 10 | 0 0 11 | 1 1 12 | 2 2 13 | 3 3 14 | 3 4 15 | ## Output 16 | 1 (1 calls) 17 | 3 (4 calls) 18 | 7 (27 calls) 19 | 61 (2432 calls) 20 | 125 (10307 calls) 21 | ## end 22 | -------------------------------------------------------------------------------- /libtest/tests/66_expconv.tst: -------------------------------------------------------------------------------- 1 | # check conversion of expr to number 2 | BEGIN { x = (1 > 0); print x 3 | x = (1 < 0); print x 4 | x = (1 == 1); print x 5 | print ("a" >= "b") 6 | print ("b" >= "a") 7 | print (0 == 0.0) 8 | # x = ((1 == 1e0) && (1 == 10e-1) && (1 == .1e2)); print x 9 | exit 10 | } 11 | ## Input 12 | ## Output 13 | 1 14 | 0 15 | 1 16 | 0 17 | 1 18 | 1 19 | ##End -------------------------------------------------------------------------------- /libtest/tests/67_for.tst: -------------------------------------------------------------------------------- 1 | { for (i=1; i<=NF; i++) 2 | print i, $i 3 | } 4 | ## Input 5 | Now 6 | Now is 7 | Now is the 8 | Now is the time 9 | Now is the time for 10 | Now is the time for all 11 | Now is the time for all good 12 | Now is the time for all good men 13 | Now is the time for all good men to 14 | Now is the time for all good men to come 15 | Now is the time for all good men to come to 16 | Now is the time for all good men to come to the 17 | Now is the time for all good men to come to the aid 18 | Now is the time for all good men to come to the aid of 19 | Now is the time for all good men to come to the aid of the 20 | Now is the time for all good men to come to the aid of the party. 21 | ##Output 22 | 1 Now 23 | 1 Now 24 | 2 is 25 | 1 Now 26 | 2 is 27 | 3 the 28 | 1 Now 29 | 2 is 30 | 3 the 31 | 4 time 32 | 1 Now 33 | 2 is 34 | 3 the 35 | 4 time 36 | 5 for 37 | 1 Now 38 | 2 is 39 | 3 the 40 | 4 time 41 | 5 for 42 | 6 all 43 | 1 Now 44 | 2 is 45 | 3 the 46 | 4 time 47 | 5 for 48 | 6 all 49 | 7 good 50 | 1 Now 51 | 2 is 52 | 3 the 53 | 4 time 54 | 5 for 55 | 6 all 56 | 7 good 57 | 8 men 58 | 1 Now 59 | 2 is 60 | 3 the 61 | 4 time 62 | 5 for 63 | 6 all 64 | 7 good 65 | 8 men 66 | 9 to 67 | 1 Now 68 | 2 is 69 | 3 the 70 | 4 time 71 | 5 for 72 | 6 all 73 | 7 good 74 | 8 men 75 | 9 to 76 | 10 come 77 | 1 Now 78 | 2 is 79 | 3 the 80 | 4 time 81 | 5 for 82 | 6 all 83 | 7 good 84 | 8 men 85 | 9 to 86 | 10 come 87 | 11 to 88 | 1 Now 89 | 2 is 90 | 3 the 91 | 4 time 92 | 5 for 93 | 6 all 94 | 7 good 95 | 8 men 96 | 9 to 97 | 10 come 98 | 11 to 99 | 12 the 100 | 1 Now 101 | 2 is 102 | 3 the 103 | 4 time 104 | 5 for 105 | 6 all 106 | 7 good 107 | 8 men 108 | 9 to 109 | 10 come 110 | 11 to 111 | 12 the 112 | 13 aid 113 | 1 Now 114 | 2 is 115 | 3 the 116 | 4 time 117 | 5 for 118 | 6 all 119 | 7 good 120 | 8 men 121 | 9 to 122 | 10 come 123 | 11 to 124 | 12 the 125 | 13 aid 126 | 14 of 127 | 1 Now 128 | 2 is 129 | 3 the 130 | 4 time 131 | 5 for 132 | 6 all 133 | 7 good 134 | 8 men 135 | 9 to 136 | 10 come 137 | 11 to 138 | 12 the 139 | 13 aid 140 | 14 of 141 | 15 the 142 | 1 Now 143 | 2 is 144 | 3 the 145 | 4 time 146 | 5 for 147 | 6 all 148 | 7 good 149 | 8 men 150 | 9 to 151 | 10 come 152 | 11 to 153 | 12 the 154 | 13 aid 155 | 14 of 156 | 15 the 157 | 16 party. 158 | ## 159 | -------------------------------------------------------------------------------- /libtest/tests/68_for.tst: -------------------------------------------------------------------------------- 1 | { 2 | i = 1 3 | for (;;) { 4 | if (i > NF) 5 | next 6 | print i, $i 7 | i++ 8 | } 9 | } 10 | ## Input 11 | Now 12 | Now is 13 | Now is the 14 | Now is the time 15 | Now is the time for 16 | Now is the time for all 17 | Now is the time for all good 18 | Now is the time for all good men 19 | Now is the time for all good men to 20 | Now is the time for all good men to come 21 | Now is the time for all good men to come to 22 | Now is the time for all good men to come to the 23 | Now is the time for all good men to come to the aid 24 | Now is the time for all good men to come to the aid of 25 | Now is the time for all good men to come to the aid of the 26 | Now is the time for all good men to come to the aid of the party. 27 | ##Output 28 | 1 Now 29 | 1 Now 30 | 2 is 31 | 1 Now 32 | 2 is 33 | 3 the 34 | 1 Now 35 | 2 is 36 | 3 the 37 | 4 time 38 | 1 Now 39 | 2 is 40 | 3 the 41 | 4 time 42 | 5 for 43 | 1 Now 44 | 2 is 45 | 3 the 46 | 4 time 47 | 5 for 48 | 6 all 49 | 1 Now 50 | 2 is 51 | 3 the 52 | 4 time 53 | 5 for 54 | 6 all 55 | 7 good 56 | 1 Now 57 | 2 is 58 | 3 the 59 | 4 time 60 | 5 for 61 | 6 all 62 | 7 good 63 | 8 men 64 | 1 Now 65 | 2 is 66 | 3 the 67 | 4 time 68 | 5 for 69 | 6 all 70 | 7 good 71 | 8 men 72 | 9 to 73 | 1 Now 74 | 2 is 75 | 3 the 76 | 4 time 77 | 5 for 78 | 6 all 79 | 7 good 80 | 8 men 81 | 9 to 82 | 10 come 83 | 1 Now 84 | 2 is 85 | 3 the 86 | 4 time 87 | 5 for 88 | 6 all 89 | 7 good 90 | 8 men 91 | 9 to 92 | 10 come 93 | 11 to 94 | 1 Now 95 | 2 is 96 | 3 the 97 | 4 time 98 | 5 for 99 | 6 all 100 | 7 good 101 | 8 men 102 | 9 to 103 | 10 come 104 | 11 to 105 | 12 the 106 | 1 Now 107 | 2 is 108 | 3 the 109 | 4 time 110 | 5 for 111 | 6 all 112 | 7 good 113 | 8 men 114 | 9 to 115 | 10 come 116 | 11 to 117 | 12 the 118 | 13 aid 119 | 1 Now 120 | 2 is 121 | 3 the 122 | 4 time 123 | 5 for 124 | 6 all 125 | 7 good 126 | 8 men 127 | 9 to 128 | 10 come 129 | 11 to 130 | 12 the 131 | 13 aid 132 | 14 of 133 | 1 Now 134 | 2 is 135 | 3 the 136 | 4 time 137 | 5 for 138 | 6 all 139 | 7 good 140 | 8 men 141 | 9 to 142 | 10 come 143 | 11 to 144 | 12 the 145 | 13 aid 146 | 14 of 147 | 15 the 148 | 1 Now 149 | 2 is 150 | 3 the 151 | 4 time 152 | 5 for 153 | 6 all 154 | 7 good 155 | 8 men 156 | 9 to 157 | 10 come 158 | 11 to 159 | 12 the 160 | 13 aid 161 | 14 of 162 | 15 the 163 | 16 party. 164 | ## 165 | 166 | -------------------------------------------------------------------------------- /libtest/tests/69_for.tst: -------------------------------------------------------------------------------- 1 | { 2 | for (i=1;;i++) { 3 | if (i > NF) 4 | next 5 | print i, $i 6 | } 7 | } 8 | ## Input 9 | Now 10 | Now is 11 | Now is the 12 | Now is the time 13 | Now is the time for 14 | Now is the time for all 15 | Now is the time for all good 16 | Now is the time for all good men 17 | Now is the time for all good men to 18 | Now is the time for all good men to come 19 | Now is the time for all good men to come to 20 | Now is the time for all good men to come to the 21 | Now is the time for all good men to come to the aid 22 | Now is the time for all good men to come to the aid of 23 | Now is the time for all good men to come to the aid of the 24 | Now is the time for all good men to come to the aid of the party. 25 | ##Output 26 | 1 Now 27 | 1 Now 28 | 2 is 29 | 1 Now 30 | 2 is 31 | 3 the 32 | 1 Now 33 | 2 is 34 | 3 the 35 | 4 time 36 | 1 Now 37 | 2 is 38 | 3 the 39 | 4 time 40 | 5 for 41 | 1 Now 42 | 2 is 43 | 3 the 44 | 4 time 45 | 5 for 46 | 6 all 47 | 1 Now 48 | 2 is 49 | 3 the 50 | 4 time 51 | 5 for 52 | 6 all 53 | 7 good 54 | 1 Now 55 | 2 is 56 | 3 the 57 | 4 time 58 | 5 for 59 | 6 all 60 | 7 good 61 | 8 men 62 | 1 Now 63 | 2 is 64 | 3 the 65 | 4 time 66 | 5 for 67 | 6 all 68 | 7 good 69 | 8 men 70 | 9 to 71 | 1 Now 72 | 2 is 73 | 3 the 74 | 4 time 75 | 5 for 76 | 6 all 77 | 7 good 78 | 8 men 79 | 9 to 80 | 10 come 81 | 1 Now 82 | 2 is 83 | 3 the 84 | 4 time 85 | 5 for 86 | 6 all 87 | 7 good 88 | 8 men 89 | 9 to 90 | 10 come 91 | 11 to 92 | 1 Now 93 | 2 is 94 | 3 the 95 | 4 time 96 | 5 for 97 | 6 all 98 | 7 good 99 | 8 men 100 | 9 to 101 | 10 come 102 | 11 to 103 | 12 the 104 | 1 Now 105 | 2 is 106 | 3 the 107 | 4 time 108 | 5 for 109 | 6 all 110 | 7 good 111 | 8 men 112 | 9 to 113 | 10 come 114 | 11 to 115 | 12 the 116 | 13 aid 117 | 1 Now 118 | 2 is 119 | 3 the 120 | 4 time 121 | 5 for 122 | 6 all 123 | 7 good 124 | 8 men 125 | 9 to 126 | 10 come 127 | 11 to 128 | 12 the 129 | 13 aid 130 | 14 of 131 | 1 Now 132 | 2 is 133 | 3 the 134 | 4 time 135 | 5 for 136 | 6 all 137 | 7 good 138 | 8 men 139 | 9 to 140 | 10 come 141 | 11 to 142 | 12 the 143 | 13 aid 144 | 14 of 145 | 15 the 146 | 1 Now 147 | 2 is 148 | 3 the 149 | 4 time 150 | 5 for 151 | 6 all 152 | 7 good 153 | 8 men 154 | 9 to 155 | 10 come 156 | 11 to 157 | 12 the 158 | 13 aid 159 | 14 of 160 | 15 the 161 | 16 party. 162 | ## 163 | -------------------------------------------------------------------------------- /libtest/tests/6_fieldassign.tst: -------------------------------------------------------------------------------- 1 | # assignment to/from fields 2 | {i=2; j=$2; $1=i;print i,j,$1} 3 | 4 | ##Input 5 | 17379 mel 6 | 16693 bwk me 7 | 16116 ken him someone else 8 | 15713 srb 9 | 11895 lem 10 | 10409 scj 11 | 10252 rhm 12 | 9853 shen 13 | 9748 a68 14 | 9492 sif 15 | 9190 pjw 16 | 8912 nls 17 | 8895 dmr 18 | 8491 cda 19 | 8372 bs 20 | 8252 llc 21 | ##Output 22 | 2 mel 2 23 | 2 bwk 2 24 | 2 ken 2 25 | 2 srb 2 26 | 2 lem 2 27 | 2 scj 2 28 | 2 rhm 2 29 | 2 shen 2 30 | 2 a68 2 31 | 2 sif 2 32 | 2 pjw 2 33 | 2 nls 2 34 | 2 dmr 2 35 | 2 cda 2 36 | 2 bs 2 37 | 2 llc 2 38 | ##END -------------------------------------------------------------------------------- /libtest/tests/70_for.tst: -------------------------------------------------------------------------------- 1 | { for (i = 1; length($i) > 0; i++) 2 | print i, $i 3 | } 4 | { for (i = 1; 5 | length($i) > 0; 6 | i++) 7 | print $i 8 | } 9 | ## Input 10 | Now 11 | Now is 12 | Now is the 13 | ## 14 | 1 Now 15 | Now 16 | 1 Now 17 | 2 is 18 | Now 19 | is 20 | 1 Now 21 | 2 is 22 | 3 the 23 | Now 24 | is 25 | the 26 | ## 27 | -------------------------------------------------------------------------------- /libtest/tests/71_sqrt.tst: -------------------------------------------------------------------------------- 1 | $1>0 {print $1, sqrt($1)} 2 | ## Input 3 | 17379 mel 4 | 16693 bwk me 5 | 16116 ken him someone else 6 | 15713 srb 7 | 11895 lem 8 | 10409 scj 9 | 10252 rhm 10 | 9853 shen 11 | 9748 a68 12 | ## Output 13 | 17379 131.829 14 | 16693 129.201 15 | 16116 126.949 16 | 15713 125.352 17 | 11895 109.064 18 | 10409 102.025 19 | 10252 101.252 20 | 9853 99.2623 21 | 9748 98.732 22 | ## -------------------------------------------------------------------------------- /libtest/tests/72_expr.tst: -------------------------------------------------------------------------------- 1 | # A line with a '#' separates input and output for different sub-tests 2 | 3 | BEGIN {test = 1} 4 | END {print "Last test ", test >"/dev/stderr"} 5 | $1 == "#" {test++; print $0; next} 6 | 7 | test == 1 { print ($1 == 1) ? "yes" : "no"} 8 | test == 2 && $1 > 0 9 | test == 3 {print NF} 10 | test == 4 { print NF, $NF } 11 | test == 5 { i=1; print ($++$++i) } # this horror prints $($2+1) 12 | test == 6 { x = $1++++$2; print $1, x } # concatenate $1 and ++$2; print new $1 and concatenated value 13 | test == 7 { print ($1~/abc/ !$2) } 14 | test == 8 { print $1 ~ $2 } 15 | test == 9 { print $1 || $2 } 16 | test == 10 { print $1 && $2 } 17 | test == 11 { $1 = $2; $1 = $1; print $1 } 18 | test == 12 { f = 1; $f++; print f, $f } # $f++ => ($f)++ 19 | test == 13 { g[1]=1; g[2]=2; print $g[1], $g[1]++, $g[2], g[1], g[2] } 20 | test == 14 { print $1, +$1, -$1, - -$1 } 21 | test == 15 { printf("a%*sb\n", $1, $2) } 22 | test == 16 { printf("a%-*sb\n", $1, $2) } 23 | test == 17 { printf("a%*.*sb\n", $1, $2, "hello") } 24 | test == 18 { printf("a%-*.*sb\n", $1, $2, "hello") } 25 | test == 19 { printf("%d %ld\n", $1, $1) } 26 | test == 20 { printf("%x %lx\n", $1, $1) } 27 | ##Input 28 | 1 29 | 1.0 30 | 1E0 31 | 0.1E1 32 | 10E-1 33 | 01 34 | 10 35 | 10E-2 36 | # test 2 37 | 1 38 | 2 39 | 0 40 | -1 41 | 1e0 42 | 0e1 43 | -2e64 44 | 3.1e4 45 | # test 3 46 | 47 | x 48 | x y 49 | # test 4 50 | 51 | x 52 | x y 53 | x yy zzz 54 | # test 5 55 | 1 56 | 1 2 3 57 | abc 58 | # test 6 59 | 1 3 60 | # test 7 61 | 0 0 62 | 0 1 63 | abc 0 64 | xabcd 1 65 | # test 8 66 | a \141 67 | a \142 68 | a \x61 69 | a \x061 70 | a \x62 71 | 0 \060 72 | 0 \60 73 | 0 \0060 74 | Z \x5a 75 | Z \x5A 76 | # test 9 77 | 78 | 1 79 | 0 0 80 | 1 0 81 | 0 1 82 | 1 1 83 | a b 84 | # test 10 85 | 86 | 1 87 | 0 0 88 | 1 0 89 | 0 1 90 | 1 1 91 | a b 92 | # test 11 93 | abc def 94 | abc def ghi 95 | # test 12 96 | 11 22 33 97 | # test 13 98 | 111 222 333 99 | # test 14 100 | 1 101 | -1 102 | 0 103 | x 104 | # test 15 105 | 1 x 106 | 2 x 107 | 3 x 108 | # test 16 109 | 1 x 110 | 2 x 111 | 3 x 112 | # test 17 113 | 1 1 114 | 2 1 115 | 3 1 116 | # test 18 117 | 1 1 118 | 2 1 119 | 3 1 120 | # test 19 121 | 1 122 | 10 123 | 10000 124 | # test 20 125 | 1 126 | 10 127 | 10000 128 | ##Output 129 | yes 130 | yes 131 | yes 132 | yes 133 | yes 134 | yes 135 | no 136 | no 137 | # test 2 138 | 1 139 | 2 140 | 1e0 141 | 3.1e4 142 | # test 3 143 | 0 144 | 1 145 | 2 146 | # test 4 147 | 0 148 | 1 x 149 | 2 y 150 | 3 zzz 151 | # test 5 152 | 1 153 | 3 154 | abc 155 | # test 6 156 | 2 14 157 | # test 7 158 | 01 159 | 00 160 | 11 161 | 10 162 | # test 8 163 | 1 164 | 0 165 | 1 166 | 0 167 | 0 168 | 1 169 | 1 170 | 0 171 | 1 172 | 1 173 | # test 9 174 | 0 175 | 1 176 | 0 177 | 1 178 | 1 179 | 1 180 | 1 181 | # test 10 182 | 0 183 | 0 184 | 0 185 | 0 186 | 0 187 | 1 188 | 1 189 | # test 11 190 | def 191 | def 192 | # test 12 193 | 1 12 194 | # test 13 195 | 111 111 222 2 2 196 | # test 14 197 | 1 1 -1 1 198 | -1 -1 1 -1 199 | 0 0 0 0 200 | x 0 0 0 201 | # test 15 202 | axb 203 | a xb 204 | a xb 205 | # test 16 206 | axb 207 | ax b 208 | ax b 209 | # test 17 210 | ahb 211 | a hb 212 | a hb 213 | # test 18 214 | ahb 215 | ah b 216 | ah b 217 | # test 19 218 | 1 1 219 | 10 10 220 | 10000 10000 221 | # test 20 222 | 1 1 223 | a a 224 | 2710 2710 225 | ## -------------------------------------------------------------------------------- /libtest/tests/73_match.tst: -------------------------------------------------------------------------------- 1 | $2 ~ /x/ {print $0} 2 | ## 3 | 5007 valerie 4 | 3963 jca 5 | 3895 bbs 6 | 3796 moh 7 | 3481 xchar 8 | 3200 tbl 9 | ## 10 | 3481 xchar 11 | ## -------------------------------------------------------------------------------- /libtest/tests/74_func.tst: -------------------------------------------------------------------------------- 1 | function f(a,b,c) { print "hello" } 2 | NR < 3 { f(1,2,3) } 3 | ## 4 | Now 5 | Now is 6 | Now is the 7 | Now is the time 8 | ## 9 | hello 10 | hello 11 | ## -------------------------------------------------------------------------------- /libtest/tests/75_func.tst: -------------------------------------------------------------------------------- 1 | function f(n) { 2 | while (n < 10) { 3 | print n 4 | n = n + 1 5 | } 6 | } 7 | function g(n) { 8 | print "g", n 9 | } 10 | { f($1); g($1); print n } 11 | 12 | ## Input 13 | 6 14 | 8 15 | 9 16 | ## Output 17 | 6 18 | 7 19 | 8 20 | 9 21 | g 6 22 | 23 | 8 24 | 9 25 | g 8 26 | 27 | 9 28 | g 9 29 | 30 | ## -------------------------------------------------------------------------------- /libtest/tests/76_func.tst: -------------------------------------------------------------------------------- 1 | function f(n) { while ((n /= 10) > 1) print n } 2 | function g(n) { print "g", n } 3 | { f($1); g($1) } 4 | ## 5 | 4000 6 | 300 7 | 20 8 | 1 9 | ## 10 | 400 11 | 40 12 | 4 13 | g 4000 14 | 30 15 | 3 16 | g 300 17 | 2 18 | g 20 19 | g 1 20 | ## -------------------------------------------------------------------------------- /libtest/tests/77_func.tst: -------------------------------------------------------------------------------- 1 | function f(a, n) { 2 | for (i=1; i <= n; i++) 3 | print " " a[i] 4 | } 5 | 6 | { print 7 | n = split($0, x) 8 | f(x, n) 9 | } 10 | ## 11 | Now is the time for all good men 12 | ## 13 | Now is the time for all good men 14 | Now 15 | is 16 | the 17 | time 18 | for 19 | all 20 | good 21 | men 22 | ## -------------------------------------------------------------------------------- /libtest/tests/78_func.tst: -------------------------------------------------------------------------------- 1 | function f(a) { 2 | return split($0, a) 3 | } 4 | { 5 | print 6 | n = f(x) 7 | for (i = 1; i <= n; i++) 8 | print " " x[i] 9 | } 10 | ## 11 | Now is the time for all good men 12 | ## 13 | Now is the time for all good men 14 | Now 15 | is 16 | the 17 | time 18 | for 19 | all 20 | good 21 | men 22 | ## -------------------------------------------------------------------------------- /libtest/tests/7_select.tst: -------------------------------------------------------------------------------- 1 | #Record selection 2 | $1 == "5" || $1 == "4" 3 | 4 | ## Input 5 | 43 ars 6 | 43 vgl 7 | 37 jfo 8 | 32 rab 9 | 31 pd 10 | 29 jns 11 | 25 spm 12 | 22 rob 13 | 15 egb 14 | 10 hm 15 | 10 mhb 16 | 6 aed 17 | 6 cpb 18 | 5 evp 19 | 4 ber 20 | 4 men 21 | 4 mitch 22 | 3 ast 23 | 3 jfr 24 | 3 lax 25 | 3 nel 26 | 2 blue 27 | 2 jfk 28 | 2 njas 29 | 1 122sec 30 | 1 ddwar 31 | 1 gopi 32 | 1 jk 33 | 1 learn 34 | 1 low 35 | 1 nac 36 | 1 sidor 37 | ## Output 38 | 5 evp 39 | 4 ber 40 | 4 men 41 | 4 mitch 42 | ## End 43 | -------------------------------------------------------------------------------- /libtest/tests/80_format4.tst: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | text=sprintf ("%125s", "x") 3 | print length (text) 4 | print text 5 | xxx=substr (text,1,105) 6 | print length (xxx) 7 | print xxx 8 | exit 9 | } 10 | ## 11 | ## 12 | 125 13 | x 14 | 105 15 | 16 | ## -------------------------------------------------------------------------------- /libtest/tests/81_func.tst: -------------------------------------------------------------------------------- 1 | #tests whether function returns sensible type bits 2 | 3 | function assert(cond) { # assertion 4 | if (cond) print 1; else print 0 5 | } 6 | 7 | function i(x) { return x } 8 | 9 | { m=$1; n=i($2); assert(m>n) } 10 | ## 11 | 10 2 12 | 2 10 13 | 10 10 14 | 10 1e1 15 | 1e1 9 16 | ## 17 | 1 18 | 0 19 | 0 20 | 0 21 | 1 22 | ## -------------------------------------------------------------------------------- /libtest/tests/82_func.tst: -------------------------------------------------------------------------------- 1 | function test1(array) { array["test"] = "data" } 2 | function test2(array) { return(array["test"]) } 3 | BEGIN { test1(foo); print "data: " test2(foo) } 4 | ## 5 | ## 6 | data: data 7 | ## -------------------------------------------------------------------------------- /libtest/tests/83_func.tst: -------------------------------------------------------------------------------- 1 | BEGIN { code() } 2 | END { codeout("x") } 3 | function code() { ; } 4 | function codeout(ex) { print ex } 5 | ## 6 | ## 7 | x 8 | -------------------------------------------------------------------------------- /libtest/tests/84_func.tst: -------------------------------------------------------------------------------- 1 | BEGIN { unireghf() } 2 | 3 | function unireghf(hfeed) { 4 | hfeed[1]=0 5 | rcell("foo",hfeed) 6 | hfeed[1]=0 7 | rcell("bar",hfeed) 8 | } 9 | 10 | function rcell(cellname,hfeed) { 11 | print cellname 12 | } 13 | ## 14 | ## 15 | foo 16 | bar 17 | -------------------------------------------------------------------------------- /libtest/tests/85_func.tst: -------------------------------------------------------------------------------- 1 | # this exercises multiple free of temp cells 2 | BEGIN { eprocess("eqn", "x", contig) 3 | process("tbl" ) 4 | eprocess("eqn" "2", "x", contig) 5 | } 6 | function eprocess(file, first, contig) { 7 | print file 8 | } 9 | function process(file) { 10 | close(file) 11 | } 12 | ## 13 | ## 14 | eqn 15 | eqn2 16 | ## -------------------------------------------------------------------------------- /libtest/tests/86_factorial.tst: -------------------------------------------------------------------------------- 1 | # Factorial function 2 | function f(n) { 3 | if (n <= 1) 4 | return 1 5 | else 6 | return n * f(n-1) 7 | } 8 | { print f($1) } 9 | ## 10 | 0 11 | 1 12 | 2 13 | 3 14 | 4 15 | 5 16 | 6 17 | 7 18 | 8 19 | 9 20 | ## 21 | 1 22 | 1 23 | 2 24 | 6 25 | 24 26 | 120 27 | 720 28 | 5040 29 | 40320 30 | 362880 31 | -------------------------------------------------------------------------------- /libtest/tests/87_fibbo.tst: -------------------------------------------------------------------------------- 1 | # Fibbonacci function 2 | END { print "end" } 3 | { print fib($1) } 4 | function fib(n) { 5 | if (n <= 1) return 1 6 | else return add(fib(n-1), fib(n-2)) 7 | } 8 | function add(m,n) { return m+n } 9 | BEGIN { print "begin" } 10 | ## 11 | 1 12 | 3 13 | 5 14 | 10 15 | ## 16 | begin 17 | 1 18 | 3 19 | 8 20 | 89 21 | end 22 | ## -------------------------------------------------------------------------------- /libtest/tests/88_multidim.tst: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | n = 10 3 | for (i = 1; i <= n; i++) 4 | for (j = 1; j <= n; j++) 5 | x[i,j] = n * i + j 6 | for (i = 1; i <= n; i++) 7 | for (j = 1; j <= n; j++) 8 | if ((i,j) in x) 9 | k++ 10 | print (k == n^2) 11 | } 12 | ## 13 | ## 14 | 1 15 | -------------------------------------------------------------------------------- /libtest/tests/89_func.tst: -------------------------------------------------------------------------------- 1 | # exit in function 2 | function f() { n = 1; exit } 3 | BEGIN { n = 0; f(); n = 2 } 4 | END { print n} 5 | ## 6 | ## 7 | 1 8 | ## -------------------------------------------------------------------------------- /libtest/tests/8_while.tst: -------------------------------------------------------------------------------- 1 | #while loop and different number formats 2 | { 3 | x = $1 4 | print x 5 | while (x > 1) { 6 | x = x / 10 7 | print x 8 | } 9 | print "==" 10 | } 11 | ##Input 12 | 123 13 | 234e2 14 | 425.6e-1 15 | 567.123 16 | 678abcd 17 | 789efgf 18 | -89.0 19 | ##Output 20 | 123 21 | 12.3 22 | 1.23 23 | 0.123 24 | == 25 | 234e2 26 | 2340 27 | 234 28 | 23.4 29 | 2.34 30 | 0.234 31 | == 32 | 425.6e-1 33 | 4.256 34 | 0.4256 35 | == 36 | 567.123 37 | 56.7123 38 | 5.67123 39 | 0.567123 40 | == 41 | 678abcd 42 | 67.8 43 | 6.78 44 | 0.678 45 | == 46 | 789efgf 47 | 78.9 48 | 7.89 49 | 0.789 50 | == 51 | -89.0 52 | == 53 | ##END -------------------------------------------------------------------------------- /libtest/tests/90_func.tst: -------------------------------------------------------------------------------- 1 | # Code after return 2 | function foo() { 3 | for (i = 1; i <= 2; i++) 4 | return 3 5 | print "should not see this" 6 | } 7 | BEGIN { foo(); exit } 8 | ## 9 | ## 10 | ## -------------------------------------------------------------------------------- /libtest/tests/91_func.tst: -------------------------------------------------------------------------------- 1 | # Function without return 2 | function foo() { i = 0 } 3 | BEGIN { x = foo(); printf "<%s> %d\n", x, x } 4 | ## 5 | ## 6 | <> 0 7 | ## -------------------------------------------------------------------------------- /libtest/tests/92_func.tst: -------------------------------------------------------------------------------- 1 | # Local variables 2 | { 3 | fld = 1 4 | C = A( $fld, NR ) 5 | print C; 6 | } 7 | 8 | function A(par1, par2, str) { 9 | str = par2 ":" par1 "+" par1 10 | return str; 11 | } 12 | ## 13 | line1 14 | line2 15 | ## 16 | 1:line1+line1 17 | 2:line2+line2 18 | ## -------------------------------------------------------------------------------- /libtest/tests/93_vf.tst: -------------------------------------------------------------------------------- 1 | BEGIN { i = 1 } 2 | {print $(i+i); i++} 3 | {print $(0)} 4 | ## 5 | The quick brown fox jumps over the lazy dog 6 | The quick brown fox jumps over the lazy dog 7 | The quick brown fox jumps over the lazy dog 8 | The quick brown fox jumps over the lazy dog 9 | ## 10 | quick 11 | The quick brown fox jumps over the lazy dog 12 | fox 13 | The quick brown fox jumps over the lazy dog 14 | over 15 | The quick brown fox jumps over the lazy dog 16 | lazy 17 | The quick brown fox jumps over the lazy dog 18 | ## 19 | -------------------------------------------------------------------------------- /libtest/tests/94_vf.tst: -------------------------------------------------------------------------------- 1 | { print 2 | i = 1 3 | while (i <= NF) { 4 | print " " $i 5 | i = i + 1 6 | } 7 | } 8 | ## 9 | The quick brown fox jumps over the lazy dog 10 | Now is the time for all good men 11 | ## 12 | The quick brown fox jumps over the lazy dog 13 | The 14 | quick 15 | brown 16 | fox 17 | jumps 18 | over 19 | the 20 | lazy 21 | dog 22 | Now is the time for all good men 23 | Now 24 | is 25 | the 26 | time 27 | for 28 | all 29 | good 30 | men 31 | -------------------------------------------------------------------------------- /libtest/tests/95_vf.tst: -------------------------------------------------------------------------------- 1 | { print $NF++; print $NF } 2 | ## 3 | The quick brown fox jumps over the lazy dog 4 | Now is the time for all good men 5 | ## 6 | 0 7 | 1 8 | 0 9 | 1 10 | -------------------------------------------------------------------------------- /libtest/tests/96_vf.tst: -------------------------------------------------------------------------------- 1 | BEGIN { i=1; j=2 } 2 | {$i = $j; print} 3 | ## 4 | The quick brown fox jumps over the lazy dog 5 | Now is the time for all good men 6 | ## 7 | quick quick brown fox jumps over the lazy dog 8 | is is the time for all good men 9 | -------------------------------------------------------------------------------- /libtest/tests/97_set.tst: -------------------------------------------------------------------------------- 1 | function f(x) { x = 1; print x } 2 | { f($0) 3 | f($1) } 4 | ## 5 | The quick brown fox jumps over lazy dog 6 | Now is the time for all good men 7 | ## 8 | 1 9 | 1 10 | 1 11 | 1 12 | -------------------------------------------------------------------------------- /libtest/tests/98_set.tst: -------------------------------------------------------------------------------- 1 | {$0 = $1; print; print NF, $0; print $2} 2 | {$(0) = $1; print; print NF, $0; print $2} 3 | { i = 1; $(i) = $i+1; print } 4 | ## 5 | The quick brown fox jumps over lazy dog 6 | Now is the time for all good men 7 | ## 8 | The 9 | 1 The 10 | 11 | The 12 | 1 The 13 | 14 | 1 15 | Now 16 | 1 Now 17 | 18 | Now 19 | 1 Now 20 | 21 | 1 22 | -------------------------------------------------------------------------------- /libtest/tests/99_set.tst: -------------------------------------------------------------------------------- 1 | {$0 = $2; print; print NF, $0; print $1} 2 | ## 3 | The quick brown fox jumps over lazy dog 4 | Now is the time for all good men 5 | ## 6 | quick 7 | 1 quick 8 | quick 9 | is 10 | 1 is 11 | is 12 | -------------------------------------------------------------------------------- /libtest/tests/9_patmatch.tst: -------------------------------------------------------------------------------- 1 | #pattern matching 2 | $1 ~ /5/ || $1 ~ /4/ 3 | 4 | ##Input 5 | 43 ars 6 | 43 vgl 7 | 37 jfo 8 | 32 rab 9 | 31 pd 10 | 29 jns 11 | 25 spm 12 | 22 rob 13 | 15 egb 14 | 10 hm 15 | 10 mhb 16 | 6 aed 17 | 6 cpb 18 | 5 evp 19 | 4 ber 20 | 4 men 21 | 4 mitch 22 | 3 ast 23 | 3 jfr 24 | 3 lax 25 | 3 nel 26 | 2 blue 27 | 2 jfk 28 | 2 njas 29 | 1 122sec 30 | 1 ddwar 31 | 1 gopi 32 | 1 jk 33 | 1 learn 34 | 1 low 35 | 1 nac 36 | 1 sidor 37 | ## Output 38 | 43 ars 39 | 43 vgl 40 | 25 spm 41 | 15 egb 42 | 5 evp 43 | 4 ber 44 | 4 men 45 | 4 mitch 46 | ## End 47 | -------------------------------------------------------------------------------- /make_release.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem 3 | rem setup environment for Visual Studio 2017 and later 4 | rem 5 | 6 | rem VS2017U2 contains vswhere.exe 7 | if "%VSWHERE%"=="" set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" 8 | if not exist "%VSWHERE%" ( 9 | echo Not found VSWHERE.exe! 10 | echo Cannot setup environment. 11 | goto :EOF 12 | ) 13 | 14 | for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do ( 15 | set VSInstallDir=%%i 16 | ) 17 | echo Visual studio installation folder is: %VSInstallDir% 18 | rem "%VSInstallDir%\common7\tools\vsdevcmd.bat" 19 | call "%VSInstallDir%\common7\tools\vsmsbuildcmd.bat" 20 | 21 | rem Make GitHub release 22 | msbuild make_release.proj -------------------------------------------------------------------------------- /make_release.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0.0-alpha 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 16 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /mklinks.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem 3 | rem Create symbolic links for included projects and output directories. 4 | rem 5 | 6 | if not defined DEV_ROOT ( 7 | echo Environment variable DEV_ROOT is not set! 8 | echo Cannot create symlinks. 9 | goto :EOF 10 | ) 11 | if not exist lib\nul mklink /d lib %DEV_ROOT%\lib 12 | 13 | pushd "%~dp0include" 14 | 15 | if not exist utpp\nul ( 16 | pushd %DEV_ROOT% 17 | if not exist utpp\nul git clone https://github.com/neacsum/utpp 18 | popd 19 | mklink /d utpp %DEV_ROOT%\utpp\include\utpp 20 | ) 21 | popd -------------------------------------------------------------------------------- /samples/interp/interp.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file interp.cpp 3 | \brief Simple AWK interpreter using embedded AWK library 4 | 5 | (c) Mircea Neacsu 2019 6 | See README file for full copyright information. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | const char *version = "AWKLIB Interpreter " __DATE__ "\n"; 14 | 15 | int main (int argc, char **argv) 16 | { 17 | const char **vars = (const char**)calloc (argc, sizeof (char*)); 18 | const char **progs = (const char **)calloc (argc, sizeof (char*)); 19 | const char **args = (const char **)calloc (argc, sizeof (char*)); 20 | int nv = 0; 21 | int np = 0; 22 | int na = 0; 23 | char *fs = 0; 24 | int ret; 25 | 26 | //parse command line 27 | for (int i = 1; i < argc; i++) 28 | { 29 | if (*argv[i] == '-' && *(argv[i]+1) == 'v') 30 | { 31 | if (strlen (argv[i]) > 2) 32 | vars[nv] = argv[i] + 2; 33 | else if (i + 1 < argc) 34 | vars[nv] = argv[++i]; 35 | else 36 | { 37 | fprintf (stderr, "Invalid last command line argument (-v)\n"); 38 | exit (1); 39 | } 40 | nv++; 41 | } 42 | else if (*argv[i] == '-' && *(argv[i] + 1) == 'f') 43 | { 44 | if (strlen (argv[i]) > 2) 45 | progs[np] = argv[i] + 2; 46 | else if (i + 1 < argc) 47 | progs[np] = argv[++i]; 48 | else 49 | { 50 | fprintf (stderr, "Invalid last command line argument (-f)\n"); 51 | exit (1); 52 | } 53 | np++; 54 | } 55 | else if (*argv[i] == '-' && *(argv[i] + 1) == 'F') 56 | { 57 | if (strlen (argv[i]) > 2) 58 | fs = argv[i] + 2; 59 | else if (i + 1 < argc) 60 | fs = argv[++i]; 61 | else 62 | { 63 | fprintf (stderr, "Invalid last command line argument (-F)\n"); 64 | exit (1); 65 | } 66 | } 67 | else if (*argv[i] == '-' && *(argv[i] + 1) == '-') 68 | { 69 | if (!strcmp (argv[i] + 2, "version")) 70 | { 71 | fprintf (stderr, version); 72 | exit (0); 73 | } 74 | 75 | } 76 | else 77 | args[na++] = argv[i]; 78 | } 79 | 80 | awk_setdebug (1); 81 | // initialize interpreter 82 | AWKINTERP* interp = awk_init (vars); 83 | 84 | // add all programs 85 | for (int i = 0; i < np; i++) 86 | awk_addprogfile (interp, progs[i]); 87 | 88 | // add all arguments 89 | for (int i = 0; i < na; i++) 90 | awk_addarg (interp, args[i]); 91 | 92 | // compile programs 93 | if (!awk_compile (interp)) 94 | { 95 | const char *msg; 96 | int err = awk_err (interp, &msg); 97 | fprintf (stderr, "Error %d - %s\n", err, msg); 98 | exit (1); 99 | } 100 | 101 | // run program 102 | if ((ret = awk_exec (interp)) < 0 ) 103 | { 104 | const char *msg; 105 | int err = awk_err (interp, &msg); 106 | fprintf (stderr, "Error %d - %s\n", err, msg); 107 | exit (ret); 108 | } 109 | 110 | // cleanup 111 | awk_end (interp); 112 | 113 | return 0; 114 | } -------------------------------------------------------------------------------- /samples/interp/interp.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {398F290F-49A7-498A-9DD2-AE6235E37995} 24 | Win32Proj 25 | interp 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 76 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 77 | awk 78 | 79 | 80 | true 81 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 82 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 83 | awk 84 | 85 | 86 | false 87 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 88 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 89 | awk 90 | 91 | 92 | false 93 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 94 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 95 | awk 96 | 97 | 98 | 99 | Level3 100 | Disabled 101 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 102 | true 103 | $(SolutionDir)include 104 | 105 | 106 | true 107 | Console 108 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 109 | 110 | 111 | 112 | 113 | Level3 114 | Disabled 115 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 116 | true 117 | $(SolutionDir)include 118 | 119 | 120 | true 121 | Console 122 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 123 | 124 | 125 | 126 | 127 | Level3 128 | MaxSpeed 129 | true 130 | true 131 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | $(SolutionDir)include 134 | 135 | 136 | true 137 | true 138 | true 139 | Console 140 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 141 | 142 | 143 | 144 | 145 | Level3 146 | MaxSpeed 147 | true 148 | true 149 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 150 | true 151 | $(SolutionDir)include 152 | 153 | 154 | true 155 | true 156 | true 157 | Console 158 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /samples/interp/interp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/wc/wc.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | \file wc.cpp 3 | \brief Sample word counting program using embedded AWK library 4 | 5 | (c) Mircea Neacsu 2019 6 | See README file for full copyright information. 7 | */ 8 | 9 | #include 10 | 11 | int main (int argc, char **argv) 12 | { 13 | AWKINTERP* interp = awk_init (NULL); 14 | awk_setprog (interp, 15 | "{wc += NF; bc += length($0)}\n" 16 | "END {print NR, wc, bc, ARGV[1]}"); 17 | awk_compile (interp); 18 | if (argc > 1) 19 | awk_addarg (interp, argv[1]); 20 | awk_exec (interp); 21 | awk_end (interp); 22 | } 23 | -------------------------------------------------------------------------------- /samples/wc/wc.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {E615F757-7F86-4A97-AB3C-4D9E23EBC02C} 24 | Win32Proj 25 | wc 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 76 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 77 | 78 | 79 | true 80 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 81 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 82 | 83 | 84 | false 85 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 86 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 87 | 88 | 89 | false 90 | $(SolutionDir)exe\$(PlatformShortName)\$(Configuration)\ 91 | $(SolutionDir)o\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ 92 | 93 | 94 | 95 | Level3 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 98 | true 99 | $(SolutionDir)include 100 | 101 | 102 | true 103 | Console 104 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 105 | 106 | 107 | 108 | 109 | Level3 110 | Disabled 111 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | true 113 | $(SolutionDir)include 114 | 115 | 116 | true 117 | Console 118 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 119 | 120 | 121 | 122 | 123 | Level3 124 | MaxSpeed 125 | true 126 | true 127 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | true 129 | $(SolutionDir)include 130 | 131 | 132 | true 133 | true 134 | true 135 | Console 136 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 137 | 138 | 139 | 140 | 141 | Level3 142 | MaxSpeed 143 | true 144 | true 145 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 146 | true 147 | $(SolutionDir)include 148 | 149 | 150 | true 151 | true 152 | true 153 | Console 154 | $(SolutionDir)lib\$(PlatformShortName)\$(Configuration)\ 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /samples/wc/wc.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "awk.h" 6 | #include "proto.h" 7 | 8 | #define FULLTAB 2 /* rehash when table gets this x full */ 9 | #define GROWTAB 4 /* grow table by this factor */ 10 | 11 | static int hash (const char*, int); 12 | extern Interpreter* interp; 13 | 14 | /// Make a new symbol table 15 | Array::Array (int n) 16 | : nelem (0) 17 | , sz (n) 18 | , tab{ (Cell**)calloc (n, sizeof (Cell*)) } 19 | { 20 | if (tab == NULL) 21 | FATAL (AWK_ERR_NOMEM, "out of space in makearray"); 22 | } 23 | 24 | /// Free a hash table 25 | Array::~Array () 26 | { 27 | Cell* cp, * temp; 28 | int i; 29 | 30 | for (i = 0; i < sz; i++) 31 | { 32 | for (cp = tab[i]; cp != NULL; cp = temp) 33 | { 34 | temp = cp->cnext; /* avoids freeing then using */ 35 | delete cp; 36 | nelem--; 37 | } 38 | tab[i] = 0; 39 | } 40 | if (nelem != 0) 41 | FATAL (AWK_ERR_OTHER, "inconsistent element count freeing array"); 42 | free (tab); 43 | } 44 | 45 | Cell* Array::setsym (const char* n, const char* s, double f, unsigned int t) 46 | { 47 | Cell* p; 48 | assert (n != NULL); 49 | if ((p = lookup (n)) == NULL) 50 | { 51 | p = insert_sym (n); 52 | p->fval = f; 53 | p->flags = t; 54 | if (s) 55 | p->sval = s; 56 | else 57 | p->sval.clear (); 58 | #ifndef NDEBUG 59 | dprintf ("setsym added n=%s t=%s",p->nval.c_str() , flags2str (p->flags)); 60 | if ((p->flags & NUM) != 0) 61 | dprintf (" f=%g", p->fval); 62 | if ((p->flags & STR) != 0) 63 | dprintf (" s=<%s>", quote (p->sval).c_str ()); 64 | dprintf ("\n"); 65 | #endif 66 | } 67 | else 68 | dprintf ("setsym found n=%s t=%s\n", p->nval.c_str(), flags2str (p->flags)); 69 | return p; 70 | } 71 | 72 | /// Add an array as element to this array. 73 | /// n - array name 74 | /// arry - element to be added 75 | /// addl_flags - flags OR'ed to existing ones 76 | Cell* Array::setsym (const char* n, Array* arry, int addl_flags) 77 | { 78 | Cell* p; 79 | if (n != NULL && (p = lookup (n)) != NULL) 80 | dprintf ("setsym found %s", n); 81 | else 82 | { 83 | p = insert_sym (n); 84 | p->flags = ARR; 85 | p->arrval = arry; 86 | } 87 | p->flags |= addl_flags; 88 | return p; 89 | } 90 | 91 | Cell* Array::insert_sym (const char* n) 92 | { 93 | int h; 94 | 95 | dprintf ("Inserting symbol %s\n"); 96 | Cell *p = new Cell (n); 97 | 98 | nelem++; 99 | if (nelem > FULLTAB * sz) 100 | rehash (); 101 | h = hash (n, sz); 102 | p->cnext = tab[h]; 103 | tab[h] = p; 104 | return p; 105 | } 106 | 107 | /// Unchain an element from array 108 | Cell* Array::removesym (const std::string& n) 109 | { 110 | int h = hash (n.c_str(), sz); 111 | Cell* p, * prev = NULL; 112 | for (p = tab[h]; p != NULL; prev = p, p = p->cnext) 113 | { 114 | if (n == p->nval) 115 | { 116 | if (prev == NULL) /* 1st one */ 117 | tab[h] = p->cnext; 118 | else /* middle somewhere */ 119 | prev->cnext = p->cnext; 120 | --nelem; 121 | return p; 122 | } 123 | } 124 | return 0; 125 | } 126 | 127 | /// Delete an element pointed by an iterator 128 | void Array::deletecell (Iterator& p) 129 | { 130 | if (p.owner != this || p.ipos >= sz) 131 | throw awk_exception (*interp, AWK_ERR_OTHER, "Invalid iterator in delete_cell"); 132 | 133 | Cell *cp = tab[p.ipos]; 134 | Cell* prev = 0; 135 | while (cp && cp != p.ptr) 136 | { 137 | prev = cp; 138 | cp = cp->cnext; 139 | } 140 | if (!cp) 141 | throw awk_exception (*interp, AWK_ERR_OTHER, "Invalid iterator in delete_cell"); 142 | 143 | if (prev) 144 | prev->cnext = cp->cnext; 145 | else 146 | tab[p.ipos] = cp->cnext; 147 | 148 | //advance iterator to next valid position 149 | p.ptr = cp->cnext; 150 | while (p.ptr == 0 && p.ipos < sz) 151 | { 152 | p.ipos++; 153 | p.ptr = tab[p.ipos]; 154 | } 155 | 156 | delete cp; 157 | --nelem; 158 | } 159 | 160 | /// Form hash value for string s 161 | int hash (const char* s, int n) 162 | { 163 | unsigned hashval; 164 | 165 | for (hashval = 0; *s != '\0'; s++) 166 | hashval = (*s + 31 * hashval); 167 | return hashval % n; 168 | } 169 | 170 | /// Rehash items in small table into big one 171 | void Array::rehash () 172 | { 173 | int i, nh, nsz; 174 | Cell* cp, * op, ** np; 175 | 176 | nsz = GROWTAB * sz; 177 | np = (Cell**)calloc (nsz, sizeof (Cell*)); 178 | if (np == NULL) /* can't do it, but can keep running. */ 179 | return; /* someone else will run out later. */ 180 | for (i = 0; i < sz; i++) 181 | { 182 | for (cp = tab[i]; cp; cp = op) 183 | { 184 | op = cp->cnext; 185 | nh = hash (cp->nval.c_str(), nsz); 186 | cp->cnext = np[nh]; 187 | np[nh] = cp; 188 | } 189 | } 190 | free (tab); 191 | tab = np; 192 | sz = nsz; 193 | } 194 | 195 | /// Look for s in tp 196 | Cell* Array::lookup (const char* s) 197 | { 198 | Cell* p; 199 | int h; 200 | 201 | h = hash (s, sz); 202 | std::string ss (s); 203 | for (p = tab[h]; p != NULL; p = p->cnext) 204 | if (ss == p->nval) 205 | return p; /* found it */ 206 | return NULL; /* not found */ 207 | } 208 | 209 | #ifndef NDEBUG 210 | void Array::print () 211 | { 212 | for (auto p : *this) 213 | print_cell (p, 0); 214 | } 215 | #endif 216 | 217 | Array::Iterator Array::begin () const 218 | { 219 | Iterator it(this); 220 | while (it.ipos < sz && tab[it.ipos] == 0) 221 | it.ipos++; 222 | if (it.ipos < sz) 223 | it.ptr = tab[it.ipos]; 224 | return it; 225 | } 226 | 227 | Array::Iterator Array::end () const 228 | { 229 | Iterator it (this); 230 | it.ipos = sz; 231 | return it; 232 | } 233 | 234 | 235 | Array::Iterator::Iterator (const Array* a) 236 | : owner{a} 237 | , ipos{ 0 } 238 | , ptr{ 0 } 239 | { 240 | } 241 | 242 | 243 | /// Post-increment operator 244 | Array::Iterator Array::Iterator::operator++ (int) 245 | { 246 | Iterator me = *this; 247 | if (ptr) 248 | ptr = ptr->cnext; 249 | if (!ptr) 250 | { 251 | while (++ipos < owner->sz && owner->tab[ipos] == 0) 252 | ; 253 | if (ipos < owner->sz) 254 | ptr = owner->tab[ipos]; 255 | else 256 | ptr = 0; 257 | } 258 | return me; 259 | } 260 | 261 | /// Pre-increment operator 262 | Array::Iterator& Array::Iterator::operator++ () 263 | { 264 | if (ptr) 265 | ptr = ptr->cnext; 266 | if (!ptr) 267 | { 268 | while (++ipos < owner->sz && owner->tab[ipos] == 0) 269 | ; 270 | if (ipos < owner->sz) 271 | ptr = owner->tab[ipos]; 272 | else 273 | ptr = 0; 274 | } 275 | return *this; 276 | } 277 | 278 | Cell* Array::Iterator::operator* () 279 | { 280 | if (ptr) 281 | return ptr; 282 | 283 | FATAL (AWK_ERR_OTHER, "Dereferencing invalid array iterator"); 284 | return 0; 285 | } 286 | 287 | bool Array::Iterator::operator==(const Iterator& other) const 288 | { 289 | return (owner == other.owner) && (ipos == other.ipos) && (ptr == other.ptr); 290 | } 291 | 292 | -------------------------------------------------------------------------------- /src/b.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | 25 | #include 26 | #include "awk.h" 27 | #include "ytab.h" 28 | #include "proto.h" 29 | 30 | #include 31 | 32 | extern Interpreter* interp; 33 | using namespace std; 34 | 35 | int hexdigit (char c) 36 | { 37 | if (isdigit (c)) 38 | return c - '0'; 39 | else if (c >= 'a' && c <= 'f') 40 | return c - 'a' + 10; 41 | else if (c >= 'A' && c <= 'F') 42 | return c - 'A' + 10; 43 | else 44 | return 0; 45 | } 46 | /* 47 | There is no flavor of std::regex that exactly matches GAWK (or One True AWK) 48 | syntax. The std::regex::constants::awk does not accept hex escaping (\xhh) 49 | and std::regex::constants::ECMAScript does not accept octal escaping (\ddd). 50 | 51 | Here we convert a string containing \xhh to \ddd. The number of characters 52 | remains the same. 53 | */ 54 | void requote (string& str) 55 | { 56 | auto s = str.begin (); 57 | while (s != str.end()) 58 | { 59 | if (*s == '\\' && *(s + 1) == 'x' 60 | && isxdigit (*(s + 2)) && isxdigit (*(s + 3))) 61 | { 62 | int n = 0; 63 | *s++ = '\\'; 64 | n = (hexdigit (*(s + 1)) << 4) + hexdigit (*(s + 2)); 65 | *s++ = (n >> 6) + '0'; 66 | *s++ = ((n >> 3) & 0x07) + '0'; 67 | *s++ = (n & 0x07) + '0'; 68 | } 69 | else 70 | s++; 71 | } 72 | } 73 | 74 | 75 | /// Compile a string into a regex and return the node containing that regex 76 | Node* nodedfa (const char *s) 77 | { 78 | Cell* a = interp->makedfa (s); 79 | Node *x = new Node (0, nullproc, 0, (Node*)a); 80 | x->ntype = NVALUE; 81 | 82 | return x; 83 | } 84 | 85 | /// split(a[0], a[1], a[2]); 86 | Cell* split (const Node::Arguments& a, int) 87 | { 88 | Cell* x = 0; 89 | 90 | Cell* y = execute (a[0]); /* source string */ 91 | char *orig_s = tostring (y->getsval ()); 92 | char* s = orig_s; 93 | bool temp_re = false; 94 | 95 | Cell* ap = execute (a[1]); /* array name */ 96 | if (ap->isarr ()) 97 | delete ap->arrval; 98 | ap->makearray (); 99 | 100 | string fs; 101 | regex* re = 0; 102 | if (!a[2]) /* fs string */ 103 | { 104 | fs = FS; 105 | } 106 | else if (a[2]->ntype == NVALUE && a[2]->to_cell ()->isregex ()) 107 | { // precompiled regexp 108 | if (!a[2]->to_cell ()->nval.empty()) 109 | re = a[2]->to_cell ()->re; 110 | } 111 | else 112 | { /* split(str,arr,"string") */ 113 | x = execute (a[2]); 114 | fs = x->getsval (); 115 | if (fs.size() > 1) 116 | { 117 | try { 118 | re = new regex (fs, regex_constants::awk); 119 | } 120 | catch (std::exception& x) { 121 | FATAL (AWK_ERR_SYNTAX, "Invalid regular expression - %s - %s", fs.c_str(), x.what()); 122 | } 123 | temp_re = true; 124 | } 125 | } 126 | 127 | int n = 0; 128 | char num[10], temp; 129 | if (re) 130 | { 131 | cmatch m; 132 | 133 | while (regex_search (s, m, *re)) 134 | { 135 | n++; 136 | sprintf (num, "%d", n); 137 | char* patbeg = s + m.position (); 138 | temp = *patbeg; 139 | *patbeg = '\0'; 140 | if (is_number (s)) 141 | ap->arrval->setsym (num, s, atof (s), STR | NUM); 142 | else 143 | ap->arrval->setsym (num, s, 0.0, STR); 144 | *patbeg = temp; 145 | s = patbeg + m.length (); 146 | } 147 | } 148 | else 149 | { 150 | char sep = fs[0]; 151 | if (sep == ' ') 152 | { 153 | for (n = 0; ; ) 154 | { 155 | while (*s == ' ' || *s == '\t' || *s == '\n') 156 | s++; 157 | if (*s == 0) 158 | break; 159 | n++; 160 | const char* t = s; 161 | do 162 | s++; 163 | while (*s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'); 164 | temp = *s; 165 | *s = '\0'; 166 | sprintf (num, "%d", n); 167 | if (is_number (t)) 168 | ap->arrval->setsym (num, t, atof (t), STR | NUM); 169 | else 170 | ap->arrval->setsym (num, t, 0.0, STR); 171 | *s = temp; 172 | if (*s != 0) 173 | s++; 174 | } 175 | } 176 | else if (sep == 0) 177 | { /* new: split(s, a, "") => 1 char/elem */ 178 | for (n = 0; *s != 0; s++) 179 | { 180 | char buf[2]; 181 | n++; 182 | sprintf (num, "%d", n); 183 | buf[0] = *s; 184 | buf[1] = 0; 185 | if (isdigit (buf[0])) 186 | ap->arrval->setsym (num, buf, atof (buf), STR | NUM); 187 | else 188 | ap->arrval->setsym (num, buf, 0.0, STR); 189 | } 190 | } 191 | else if (*s != 0) 192 | { 193 | for (;;) 194 | { 195 | n++; 196 | const char *t = s; 197 | while (*s != sep && *s != '\n' && *s != '\0') 198 | s++; 199 | temp = *s; 200 | *s = '\0'; 201 | sprintf (num, "%d", n); 202 | if (is_number (t)) 203 | ap->arrval->setsym (num, t, atof (t), STR | NUM); 204 | else 205 | ap->arrval->setsym (num, t, 0.0, STR); 206 | *s = temp; 207 | if (*s++ == 0) 208 | break; 209 | } 210 | } 211 | } 212 | delete orig_s; 213 | 214 | tempfree (ap); 215 | tempfree (y); 216 | 217 | if (temp_re) 218 | delete re; 219 | 220 | x = new Cell (nullptr, Cell::type::CTEMP, NUM, n); 221 | return x; 222 | } 223 | 224 | extern Cell *True, *False; 225 | 226 | /* 227 | Change replacement string for sub and gsub replacing the AWK substitution 228 | operator (&) with std::regex one ($&). 229 | */ 230 | void format_repl (string& s) 231 | { 232 | string out; 233 | for (auto pc = s.begin (); pc != s.end (); pc++) 234 | { 235 | if (*pc == '\\') 236 | { 237 | if (++pc == s.end ()) 238 | break; 239 | } 240 | else if (*pc == '&') 241 | out.push_back ('$'); 242 | out.push_back (*pc); 243 | } 244 | s = out; 245 | } 246 | 247 | /// substitute command 248 | /// a[0] = regexp string 249 | /// a[1] = compiled regexp 250 | /// a[2] = replacement string 251 | /// a[3] = target string 252 | Cell* sub (const Node::Arguments& a, int) 253 | { 254 | Cell* result = False; 255 | Cell* y; 256 | Cell *x = execute (a[3]); /* target string */ 257 | regex* re; 258 | bool temp_re = false; 259 | if (!a[0]) // a[1] is already-compiled regexp 260 | re = a[1]->to_cell ()->re; 261 | else 262 | { 263 | y = execute (a[0]); 264 | try { 265 | re = new regex (y->sval, regex_constants::awk); 266 | } 267 | catch (std::exception& x) { 268 | FATAL (AWK_ERR_SYNTAX, "Invalid regular expression - %s - %s", y->sval.c_str(), x.what()); 269 | } 270 | temp_re = true; 271 | tempfree (y); 272 | } 273 | y = execute (a[2]); /* replacement string */ 274 | string repl (y->sval); 275 | string target (x->getsval ()); 276 | format_repl (repl); 277 | smatch m; 278 | if (regex_search (target, m, *re)) 279 | { 280 | target = regex_replace (target, *re, repl, regex_constants::format_first_only); 281 | x->setsval (target.c_str ()); 282 | result = True; 283 | } 284 | tempfree (x); 285 | tempfree (y); 286 | return result; 287 | } 288 | 289 | /// global substitute 290 | /// a[0] = regexp string 291 | /// a[1] = compiled regexp 292 | /// a[2] = replacement string 293 | /// a[3] = target string 294 | Cell* gsub (const Node::Arguments& a, int) 295 | { 296 | int num = 0; 297 | 298 | Cell* y; 299 | Cell* x = execute (a[3]); /* target string */ 300 | regex* re; 301 | bool temp_re = false; 302 | if (!a[0]) // a[1] is already-compiled regexp 303 | re = a[1]->to_cell ()->re; 304 | else 305 | { 306 | y = execute (a[0]); 307 | try { 308 | re = new regex (y->sval, regex_constants::awk); 309 | } 310 | catch (std::exception& x) { 311 | FATAL (AWK_ERR_SYNTAX, "Invalid regular expression - %s - %s", y->sval.c_str(), x.what()); 312 | } 313 | temp_re = true; 314 | tempfree (y); 315 | } 316 | y = execute (a[2]); /* replacement string */ 317 | string repl (y->sval); 318 | string target (x->getsval ()); 319 | format_repl (repl); 320 | smatch m; 321 | string::const_iterator i = target.begin (); 322 | string result; 323 | while (regex_search (i, target.cend (), m, *re)) 324 | { 325 | result += m.prefix (); 326 | result += m.format (repl); 327 | i += m.position () + m.length(); 328 | num++; 329 | } 330 | result.append (i, target.cend ()); 331 | x->setsval (result.c_str ()); 332 | tempfree (x); 333 | tempfree (y); 334 | 335 | x = new Cell (nullptr, Cell::type::CTEMP, NUM, num); 336 | return x; 337 | } 338 | -------------------------------------------------------------------------------- /src/cell.cpp: -------------------------------------------------------------------------------- 1 | #include "awk.h" 2 | #include "proto.h" 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | extern Interpreter* interp; 9 | 10 | #ifndef NDEBUG 11 | int cell_count = 0; 12 | std::vector all_cells; 13 | #endif 14 | 15 | 16 | Cell::Cell (const char* n, type t, unsigned char flags, Awkfloat f) 17 | : ctype{ t } 18 | , nval{ n? n : string() } 19 | , flags{ flags } 20 | , funptr{ nullptr } 21 | , fval{ f } 22 | , fmt{ 0 } 23 | , cnext{ 0 } 24 | { 25 | #ifndef NDEBUG 26 | dprintf ("Allocated cells = %d\n", id = ++cell_count); 27 | all_cells.push_back (this); 28 | #endif 29 | } 30 | 31 | /// Free a symbol table entry 32 | Cell::~Cell () 33 | { 34 | #ifndef NDEBUG 35 | dprintf ("Deleting %s(%d)...", nval.c_str(), id); 36 | print_cell (this, 1); 37 | for (auto p = all_cells.begin(); p != all_cells.end(); ++p) 38 | { 39 | if (*p == this) 40 | { 41 | all_cells.erase (p); 42 | break; 43 | } 44 | } 45 | #endif 46 | if (isarr ()) 47 | { 48 | dprintf (" array\n"); 49 | delete arrval; 50 | } 51 | else if (isregex ()) 52 | { 53 | dprintf ("regex\n"); 54 | delete re; 55 | } 56 | #ifndef NDEBUG 57 | dprintf ("Remaining cells = %d\n", --cell_count); 58 | #endif 59 | } 60 | 61 | // Assignment operator copies the value from another cell 62 | Cell& Cell::operator= (const Cell& rhs) 63 | { 64 | assert (!isarr () && !isfcn ()); 65 | 66 | flags &= ~(NUM | STR); 67 | sval.clear (); 68 | fval = 0; 69 | 70 | switch (rhs.flags & (STR | NUM)) 71 | { 72 | case (NUM | STR): 73 | sval = rhs.sval; 74 | fval = rhs.fval; 75 | flags |= NUM | STR; 76 | break; 77 | case NUM: 78 | fval = rhs.fval; 79 | flags |= NUM; 80 | break; 81 | case STR: 82 | sval = rhs.sval; 83 | // FALL THROUGH 84 | case 0: 85 | flags |= STR; 86 | break; 87 | } 88 | return *this; 89 | } 90 | 91 | /// Set string val of a Cell 92 | void Cell::setsval (const char* s) 93 | { 94 | int fldno; 95 | Awkfloat f; 96 | 97 | dprintf ("starting setsval %s = <%s>, t=%s, r,f=%d,%d\n", 98 | nval.c_str(), s, flags2str (flags), interp->donerec, interp->donefld); 99 | if (isarr() || isfcn ()) 100 | funnyvar (this, "assign to"); 101 | if (isfld()) 102 | { 103 | interp->donefld = false; /* mark $1... invalid */ 104 | fldno = stoi (nval); 105 | if (fldno > NF) 106 | interp->setlastfld (fldno); 107 | dprintf ("setting $%d to %s\n", fldno, s); 108 | } 109 | else if (isrec()) 110 | { 111 | interp->donefld = false; /* mark $1... invalid */ 112 | interp->donerec = true; 113 | } 114 | else if (this == interp->CELL_OFS) 115 | { 116 | if (!interp->donerec) 117 | interp->recbld (); 118 | } 119 | flags &= ~(NUM | CONVC); 120 | flags |= STR; 121 | fmt.clear(); 122 | sval = s; 123 | if (is_number (s)) 124 | { 125 | fval = atof (s); 126 | flags |= NUM; 127 | } 128 | else 129 | fval = 0.; 130 | 131 | if (isnf()) 132 | { 133 | interp->donerec = false; /* mark $0 invalid */ 134 | f = getfval (); 135 | interp->setlastfld ((int)f); 136 | dprintf ("setting NF to %g\n", f); 137 | } 138 | 139 | dprintf ("setsval %c%s = <%s>, t=%s r,f=%d,%d\n", 140 | (isfld () || isrec ()) ? '$' : ' ', nval.c_str (), sval.c_str (), flags2str (flags), interp->donerec, interp->donefld); 141 | } 142 | 143 | /// Set float val of a Cell 144 | void Cell::setfval (Awkfloat f) 145 | { 146 | int fldno; 147 | 148 | f += 0.0; /* normalize negative zero to positive zero */ 149 | if (isarr() || isfcn()) 150 | funnyvar (this, "assign to"); 151 | sval.clear (); /* free any previous string */ 152 | flags &= ~(STR | CONVC); /* mark string invalid */ 153 | fmt.clear (); 154 | flags |= NUM; /* mark number ok */ 155 | if (isfld ()) 156 | { 157 | interp->donerec = false; /* mark $0 invalid */ 158 | fldno = stoi (nval); 159 | if (fldno > NF) 160 | interp->setlastfld (fldno); 161 | } 162 | else if (isnf ()) 163 | { 164 | interp->donerec = false; /* mark $0 invalid */ 165 | interp->setlastfld ((int)f); 166 | dprintf ("setting NF to %g\n", f); 167 | } 168 | else if (isrec ()) 169 | { 170 | interp->donefld = false; /* mark $1... invalid */ 171 | interp->donerec = true; 172 | } 173 | fval = f; 174 | if (isrec () || isfld ()) 175 | { 176 | //fields have always a string value 177 | fmt = CONVFMT; 178 | update_str_val (); 179 | } 180 | else 181 | dprintf ("setfval %c%s = %g, t=%s\n", 182 | (isfld () || isrec ()) ? '$' : ' ', nval.c_str(), f, flags2str (flags)); 183 | } 184 | 185 | /// Get float val of a Cell 186 | Awkfloat Cell::getfval () 187 | { 188 | if ((flags & (NUM | STR)) == 0) 189 | funnyvar (this, "read float value of"); 190 | 191 | if ((isfld () || isnf ()) && !interp->donefld) 192 | interp->fldbld (); 193 | else if (isrec () && !interp->donerec) 194 | interp->recbld (); 195 | 196 | if (!(flags & NUM)) /* no numeric value */ 197 | fval = sval.empty() ? 0. : atof (sval.c_str()); /* best guess */ 198 | 199 | dprintf ("getfval %c%s = %g, t=%s\n", 200 | (isfld () || isrec ()) ? '$' : ' ', nval.c_str (), fval, flags2str (flags)); 201 | return fval; 202 | } 203 | 204 | /// Get string value of a Cell 205 | const char* Cell::getsval () 206 | { 207 | if ((flags & (NUM | STR)) == 0) 208 | funnyvar (this, "read string value of"); 209 | 210 | if ((isfld () || isnf ()) && !interp->donefld) 211 | interp->fldbld (); 212 | else if (isrec () && !interp->donerec) 213 | interp->recbld (); 214 | 215 | if ((flags & STR) == 0) 216 | { 217 | // don't have a string value but can make one 218 | fmt = CONVFMT; 219 | update_str_val (); 220 | flags |= CONVC; 221 | } 222 | 223 | dprintf ("getsval %c%s = <%s>, t=%s\n", 224 | (isfld () || isrec ()) ? '$' : ' ', nval.c_str (), sval.c_str (), flags2str (flags)); 225 | return sval.c_str(); 226 | } 227 | 228 | /// Get string val of a Cell for print */ 229 | const char* Cell::getpssval () 230 | { 231 | if ((flags & (NUM | STR)) == 0) 232 | funnyvar (this, "print string value of"); 233 | 234 | if ((isfld () || isnf()) && !interp->donefld) 235 | interp->fldbld (); 236 | else if (isrec () && !interp->donerec) 237 | interp->recbld (); 238 | 239 | if ((flags & STR) == 0) 240 | { 241 | fmt = OFMT; 242 | update_str_val (); 243 | flags &= ~CONVC; 244 | } 245 | 246 | dprintf ("getpsval %c%s = <%s>, t=%s\n", 247 | (isfld () || isrec ()) ? '$' : ' ', nval.c_str (), sval.c_str (), flags2str (flags)); 248 | return sval.c_str(); 249 | } 250 | 251 | /// Clear cell content 252 | void Cell::clear () 253 | { 254 | sval.clear (); 255 | flags = STR; 256 | fval = 0.; 257 | fmt.clear (); 258 | } 259 | 260 | ///Turn cell into an array discarding any previous content 261 | void Cell::makearray (size_t sz) 262 | { 263 | sval.clear (); 264 | fmt.clear (); 265 | fval = 0.; 266 | flags = ARR; 267 | arrval = new Array (NSYMTAB); 268 | } 269 | 270 | 271 | /// Check if string matches regular expression of this cell 272 | bool Cell::match (const char* str, bool anchored) 273 | { 274 | assert (isregex ()); 275 | regex_constants::match_flag_type flags = regex_constants::match_default; 276 | if (anchored) 277 | flags |= (regex_constants::match_not_bol | regex_constants::match_not_eol); 278 | 279 | bool result = regex_search (str, *re, flags); 280 | return result; 281 | } 282 | 283 | /// pattern match, for sub 284 | bool Cell::pmatch (const char* p0, size_t& start, size_t& len, bool anchored) 285 | { 286 | assert (isregex ()); 287 | regex_constants::match_flag_type flags = regex_constants::match_default; 288 | if (anchored) 289 | flags |= (regex_constants::match_not_bol | regex_constants::match_not_eol); 290 | 291 | cmatch m; 292 | if (regex_search (p0, m, *re, flags)) 293 | { 294 | start = m.position (); 295 | len = m.length (); 296 | return true; 297 | } 298 | return false; 299 | } 300 | 301 | 302 | 303 | /* Don't duplicate the code for actually updating the value */ 304 | void Cell::update_str_val () 305 | { 306 | char s[100]; 307 | double dtemp; 308 | if (modf (fval, &dtemp) == 0) /* it's integral */ 309 | sprintf (s, "%.30g", fval); 310 | else 311 | sprintf (s, fmt.c_str(), fval); 312 | sval = s; 313 | } 314 | 315 | -------------------------------------------------------------------------------- /src/lib.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "awk.h" 32 | #include "ytab.h" 33 | #include 34 | #include "proto.h" 35 | 36 | static int refldbld (const char *, const char *); 37 | 38 | 39 | #ifndef NDEBUG 40 | /// Quick and dirty character quoting can quote a few short character strings 41 | std::string quote (const std::string& in) 42 | { 43 | if (in.empty()) 44 | return "(null)"; 45 | 46 | std::string out; 47 | for (auto p : in) 48 | { 49 | switch (p) 50 | { 51 | case '\n': 52 | out += "\\n"; 53 | break; 54 | case '\r': 55 | out += "\\r"; 56 | break; 57 | case '\t': 58 | out += "\\t"; 59 | break; 60 | default: 61 | out.push_back(p); 62 | } 63 | if (out.size() > 100) 64 | { 65 | out += "..."; 66 | break; 67 | } 68 | } 69 | return out; 70 | } 71 | #endif 72 | 73 | double errcheck (double x, const char *s) 74 | { 75 | if (errno == EDOM) 76 | { 77 | errno = 0; 78 | WARNING ("%s argument out of domain", s); 79 | x = 1; 80 | } 81 | else if (errno == ERANGE) 82 | { 83 | errno = 0; 84 | WARNING ("%s result out of range", s); 85 | x = 1; 86 | } 87 | return x; 88 | } 89 | 90 | /*! 91 | Checks if s is a command line variable assignment 92 | of the form var=something 93 | */ 94 | int isclvar (const char *s) 95 | { 96 | const char *os = s; 97 | 98 | if (!isalpha (*s) && *s != '_') 99 | return 0; 100 | for (; *s; s++) 101 | if (!(isalnum (*s) || *s == '_')) 102 | break; 103 | return *s == '=' && s > os && *(s + 1) != '='; 104 | } 105 | 106 | /* strtod is supposed to be a proper test of what's a valid number */ 107 | /* appears to be broken in gcc on linux: thinks 0x123 is a valid FP number */ 108 | /* wrong: violates 4.10.1.4 of ansi C standard */ 109 | 110 | #include 111 | bool is_number (const char *s) 112 | { 113 | double r; 114 | char *ep; 115 | 116 | if (!s) 117 | return 0; 118 | 119 | errno = 0; 120 | r = strtod (s, &ep); 121 | if (ep == s || r == HUGE_VAL || errno == ERANGE) 122 | return 0; 123 | while (*ep == ' ' || *ep == '\t' || *ep == '\n') 124 | ep++; 125 | if (*ep == '\0') 126 | return 1; 127 | else 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /src/parse.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "awk.h" 32 | #include "ytab.h" 33 | #include "proto.h" 34 | 35 | using namespace std; 36 | 37 | extern Interpreter* interp; 38 | extern Cell* literal0; 39 | extern Cell* literal_null; 40 | 41 | #ifndef NDEBUG 42 | const char *tokname (int tok); 43 | int node_count = 0; 44 | #endif 45 | 46 | 47 | Node::Node () 48 | : nnext {0} 49 | , lineno {0} 50 | , ntype {NVALUE} 51 | , tokid {0} 52 | , iarg {0} 53 | { 54 | #ifndef NDEBUG 55 | dprintf ("Allocated nodes = %d\n", (id = ++node_count)); 56 | #endif 57 | } 58 | 59 | /// Create a node with one descendant 60 | Node::Node (int id, pfun fn, int i, Node* arg1) 61 | : Node () 62 | { 63 | tokid = id; 64 | proc = fn; 65 | arg.push_back (unique_ptr (arg1)); 66 | iarg = i; 67 | } 68 | 69 | /// Create a node with two descendants 70 | Node::Node (int id, pfun fn, int i, Node* arg1, Node* arg2) 71 | : Node () 72 | { 73 | tokid = id; 74 | proc = fn; 75 | arg.push_back (unique_ptr (arg1)); 76 | arg.push_back (unique_ptr (arg2)); 77 | iarg = i; 78 | } 79 | 80 | /// Create a node with three descendants 81 | Node::Node (int id, pfun fn, int i, Node* arg1, Node* arg2, Node* arg3) 82 | : Node () 83 | { 84 | tokid = id; 85 | proc = fn; 86 | arg.push_back (unique_ptr (arg1)); 87 | arg.push_back (unique_ptr (arg2)); 88 | arg.push_back (unique_ptr (arg3)); 89 | iarg = i; 90 | } 91 | 92 | Node::~Node () 93 | { 94 | #ifndef NDEBUG 95 | dprintf ("%Deleting node 0x%p %s with %d arguments (line %d)", 96 | this, tokname (tokid), arg.size (), lineno); 97 | dprintf (" type %s\n", ntype == NVALUE ? "value" : ntype == NSTAT ? "statement" : "expression"); 98 | #endif 99 | if (ntype == NVALUE) 100 | { 101 | Cell* x = (Cell*)arg[0].release(); 102 | // Do not delete cell. It belongs to symtab... 103 | if (x->isregex ()) //...unless it's a regex 104 | delete x; //regular expressions are not part of symtab (for now) 105 | } 106 | else 107 | { 108 | for (size_t i = 0; i < arg.size (); i++) 109 | arg[i].reset (); 110 | } 111 | delete nnext; 112 | #ifndef NDEBUG 113 | dprintf ("Remaining nodes = %d\n", --node_count); 114 | #endif 115 | } 116 | 117 | /// Create a node with four descendants 118 | Node::Node (int id, pfun fn, int i, Node* arg1, Node* arg2, Node* arg3, Node* arg4) 119 | : Node () 120 | { 121 | tokid = id; 122 | proc = fn; 123 | arg.push_back (unique_ptr (arg1)); 124 | arg.push_back (unique_ptr (arg2)); 125 | arg.push_back (unique_ptr (arg3)); 126 | arg.push_back (unique_ptr (arg4)); 127 | iarg = i; 128 | } 129 | 130 | /// Convert node to a statement node (presumably from an expression node) 131 | Node *exptostat (Node *a) 132 | { 133 | a->ntype = NSTAT; 134 | return a; 135 | } 136 | 137 | /// Create a statement node with 1 descendant 138 | Node *stat1 (int tokid, pfun fn, Node *arg1, int iarg) 139 | { 140 | Node *x; 141 | 142 | x = new Node (tokid, fn, iarg, arg1); 143 | x->ntype = NSTAT; 144 | return x; 145 | } 146 | 147 | /// Create a statement node with 2 descendants 148 | Node *stat2 (int tokid, pfun fn, Node *arg1, Node *arg2, int iarg) 149 | { 150 | Node *x; 151 | 152 | x = new Node (tokid, fn, iarg, arg1, arg2); 153 | x->ntype = NSTAT; 154 | return x; 155 | } 156 | 157 | /// Create a statement node with 3 descendants 158 | Node *stat3 (int tokid, pfun fn, Node *arg1, Node *arg2, Node *arg3, int iarg) 159 | { 160 | Node *x; 161 | 162 | x = new Node (tokid, fn, iarg, arg1, arg2, arg3); 163 | x->ntype = NSTAT; 164 | return x; 165 | } 166 | 167 | /// Create a statement node with 4 descendants 168 | Node *stat4 (int tokid, pfun fn, Node *arg1, Node *arg2, Node *arg3, Node *arg4, int iarg) 169 | { 170 | Node *x; 171 | 172 | x = new Node (tokid, fn, iarg, arg1, arg2, arg3, arg4); 173 | x->ntype = NSTAT; 174 | return x; 175 | } 176 | 177 | /// Create an expression node with 1 descendant 178 | Node *op1 (int tokid, pfun fn, Node *arg1, int iarg) 179 | { 180 | Node *x; 181 | 182 | x = new Node (tokid, fn, iarg, arg1); 183 | x->ntype = NEXPR; 184 | return x; 185 | } 186 | 187 | /// Create an expression node with 2 descendants 188 | Node *op2 (int tokid, pfun fn, Node *arg1, Node *arg2, int iarg) 189 | { 190 | Node *x; 191 | 192 | x = new Node (tokid, fn, iarg, arg1, arg2); 193 | x->ntype = NEXPR; 194 | return x; 195 | } 196 | 197 | /// Create an expression node with 3 descendants 198 | Node *op3 (int tokid, pfun fn, Node *arg1, Node *arg2, Node *arg3, int iarg) 199 | { 200 | Node *x; 201 | 202 | x = new Node (tokid, fn, iarg, arg1, arg2, arg3); 203 | x->ntype = NEXPR; 204 | return x; 205 | } 206 | 207 | /// Create an expression node with 4 descendants 208 | Node *op4 (int tokid, pfun fn, Node *arg1, Node *arg2, Node *arg3, Node *arg4, int iarg) 209 | { 210 | Node *x; 211 | 212 | x = new Node (tokid, fn, iarg, arg1, arg2, arg3, arg4); 213 | x->ntype = NEXPR; 214 | return x; 215 | } 216 | 217 | Node *celltonode (Cell *a, Cell::type t, int flags) 218 | { 219 | Node *x; 220 | 221 | a->ctype = t; 222 | a->flags |= flags; 223 | x = new Node (0, nullproc, 0, (Node *)a); 224 | x->ntype = NVALUE; 225 | return x; 226 | } 227 | 228 | Node *rectonode () /* make $0 into a Node */ 229 | { 230 | // MN - Is this really needed? Can't we use fldtab[0]? 231 | return op1 (INDIRECT, indirect, celltonode (literal0)); 232 | } 233 | 234 | Node* nullnode () /* zero&null, converted into a node for comparisons */ 235 | { 236 | return celltonode (literal_null); 237 | } 238 | 239 | /*TODO: Check if could use NF as an array. That would be bad!! */ 240 | 241 | Node* makearr (Node* p) 242 | { 243 | if (p->isvalue ()) 244 | { 245 | Cell* cp = p->to_cell (); 246 | if (cp->isfcn ()) 247 | SYNTAX ("%s is a function, not an array", cp->nval); 248 | else if (!cp->isarr ()) 249 | { 250 | cp->makearray(); 251 | dprintf ("%s is now an array\n", cp->nval); 252 | } 253 | } 254 | return p; 255 | } 256 | 257 | #define PA2NUM 50 /* max number of pat,pat patterns allowed */ 258 | int paircnt; /* number of them in use */ 259 | int pairstack[PA2NUM]; /* state of each pat,pat */ 260 | 261 | Node *pa2stat (Node *a, Node *b, Node *c) /* pat, pat {...} */ 262 | { 263 | Node *x; 264 | 265 | x = new Node (PASTAT2, dopa2, paircnt, a, b, c); 266 | if (paircnt++ >= PA2NUM) 267 | SYNTAX ("limited to %d pat,pat statements", PA2NUM); 268 | x->ntype = NSTAT; 269 | return x; 270 | } 271 | 272 | Node *linkum (Node *a, Node *b) 273 | { 274 | Node *c; 275 | 276 | if (interp->err) /* don't link things that are wrong */ 277 | return a; 278 | if (a == NULL) 279 | return b; 280 | else if (b == NULL) 281 | return a; 282 | for (c = a; c->nnext != NULL; c = c->nnext) 283 | ; 284 | c->nnext = b; 285 | return a; 286 | } 287 | 288 | void defn (Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */ 289 | { /* body of function, arglist */ 290 | Node *p; 291 | int n; 292 | 293 | if (v->isarr ()) 294 | { 295 | SYNTAX ("`%s' is an array name and a function name", v->nval.c_str()); 296 | return; 297 | } 298 | if (isarg (v->nval.c_str()) != -1) 299 | { 300 | SYNTAX ("`%s' is both function name and argument name", v->nval.c_str()); 301 | return; 302 | } 303 | 304 | v->ctype = Cell::type::CFUNC; 305 | v->funptr = st; 306 | n = 0; /* count arguments */ 307 | for (p = vl; p; p = p->nnext) 308 | n++; 309 | v->fval = n; 310 | dprintf ("defining func %s (%d args)\n", v->nval, n); 311 | } 312 | 313 | int isarg (const char *s) /* is s in argument list for current function? */ 314 | { /* return -1 if not, otherwise arg # */ 315 | extern Node *arglist; 316 | Node *p = arglist; 317 | int n; 318 | 319 | for (n = 0; p != 0; p = p->nnext, n++) 320 | if (strcmp (((Cell *)(p->arg[0].get()))->nval.c_str(), s) == 0) 321 | return n; 322 | return -1; 323 | } 324 | -------------------------------------------------------------------------------- /src/tran.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Copyright (C) Lucent Technologies 1997 3 | All Rights Reserved 4 | 5 | Permission to use, copy, modify, and distribute this software and 6 | its documentation for any purpose and without fee is hereby 7 | granted, provided that the above copyright notice appear in all 8 | copies and that both that the copyright notice and this 9 | permission notice and warranty disclaimer appear in supporting 10 | documentation, and that the name Lucent Technologies or any of 11 | its entities not be used in advertising or publicity pertaining 12 | to distribution of the software without specific, written prior 13 | permission. 14 | 15 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 | THIS SOFTWARE. 23 | ****************************************************************/ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "awk.h" 31 | #include "ytab.h" 32 | #include 33 | #include "proto.h" 34 | 35 | #ifndef _MSC_VER 36 | #include 37 | #endif 38 | 39 | 40 | #ifdef __APPLE__ 41 | extern char **environ; 42 | #endif 43 | 44 | 45 | /// Free elem s from ap (i.e., ap["s"]) 46 | void freeelem (Cell *ap, const char *s) 47 | { 48 | Cell *p = ap->arrval->removesym (s); 49 | delete p; 50 | } 51 | 52 | 53 | void funnyvar (const Cell *vp, const char *rw) 54 | { 55 | if (vp->isarr ()) 56 | FATAL (AWK_ERR_ARG, "can't %s %s; it's an array name.", rw, vp->nval); 57 | if (vp->isfcn()) 58 | FATAL (AWK_ERR_ARG, "can't %s %s; it's a function.", rw, vp->nval); 59 | WARNING ("funny variable %s %p: n=%s s=\"%s\" f=%g t=0x%x", 60 | rw, vp, vp->nval, vp->sval.c_str(), vp->fval, vp->flags); 61 | } 62 | 63 | /// Make a copy of string s 64 | char *tostring (const char *s) 65 | { 66 | char* p = new char[(s ? strlen (s) : 0) + 1]; 67 | strcpy (p, s ? s : ""); 68 | return p; 69 | } 70 | 71 | /// Collect string up to next delim 72 | char *qstring (const char *is, int delim) 73 | { 74 | const char *os = is; 75 | const char *pd; 76 | int c, n; 77 | 78 | const char *s = is; 79 | char *buf, *bp; 80 | 81 | if (!(pd = strchr (is, delim))) 82 | FATAL (AWK_ERR_ARG, "invalid delimiter for qstring"); 83 | 84 | buf = new char[pd - is + 3]; 85 | for (bp = buf; (c = *s) != delim; s++) 86 | { 87 | if (c == '\n') 88 | SYNTAX ("newline in string %.20s...", os); 89 | else if (c != '\\') 90 | *bp++ = c; 91 | else /* \something */ 92 | { 93 | c = *++s; 94 | if (c == 0) /* \ at end */ 95 | { 96 | *bp++ = '\\'; 97 | break; /* for loop */ 98 | } 99 | switch (c) 100 | { 101 | case '\\': *bp++ = '\\'; break; 102 | case 'n': *bp++ = '\n'; break; 103 | case 't': *bp++ = '\t'; break; 104 | case 'b': *bp++ = '\b'; break; 105 | case 'f': *bp++ = '\f'; break; 106 | case 'r': *bp++ = '\r'; break; 107 | default: 108 | if (!isdigit (c)) 109 | { 110 | *bp++ = c; 111 | break; 112 | } 113 | n = c - '0'; 114 | if (isdigit (s[1])) 115 | { 116 | n = 8 * n + *++s - '0'; 117 | if (isdigit (s[1])) 118 | n = 8 * n + *++s - '0'; 119 | } 120 | *bp++ = n; 121 | break; 122 | } 123 | } 124 | } 125 | *bp++ = 0; 126 | return buf; 127 | } 128 | 129 | #ifndef NDEBUG 130 | const char *flags2str (int flags) 131 | { 132 | static const struct ftab { 133 | const char *name; 134 | int value; 135 | } flagtab[] = { 136 | { "NUM", NUM }, 137 | { "STR", STR }, 138 | { "CONVC", CONVC }, 139 | { "PREDEF", PREDEF}, 140 | { "CONST", CONST}, 141 | { "ARR", ARR}, 142 | { "REGEX", REGEX}, 143 | { NULL, 0 } 144 | }; 145 | static char buf[100]; 146 | int i; 147 | char *cp = buf; 148 | 149 | for (i = 0; flagtab[i].name != NULL; i++) 150 | { 151 | if ((flags & flagtab[i].value) != 0) 152 | { 153 | if (cp > buf) 154 | *cp++ = '|'; 155 | strcpy (cp, flagtab[i].name); 156 | cp += strlen (cp); 157 | } 158 | } 159 | 160 | return buf; 161 | } 162 | #endif 163 | -------------------------------------------------------------------------------- /yacc_compile.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd src 3 | del /q ytab.h 4 | yacc -d -o ytab.cpp awkgram.y 5 | REM Different versions of YACC give different naems to .H file 6 | REM It can be y.tab.h or ytab.h 7 | if exist ytab.h goto :EOF 8 | ren ytab.tab.h ytab.h 9 | --------------------------------------------------------------------------------