├── ACKNOWLEDGMENT ├── CHANGES ├── COPYING ├── INSTALL ├── MANIFEST ├── Makefile.in ├── README ├── aclocal.m4 ├── array.c ├── array.h ├── bi_funct.c ├── bi_funct.h ├── bi_vars.c ├── bi_vars.h ├── cast.c ├── code.c ├── code.h ├── config.guess ├── config.sub ├── config_h.in ├── configure ├── configure.in ├── da.c ├── error.c ├── examples ├── ct_length.awk ├── decl.awk ├── deps.awk ├── eatc.awk ├── gdecl.awk ├── hcal ├── hical ├── nocomment.awk ├── primes.awk └── qsort.awk ├── execute.c ├── fcall.c ├── field.c ├── field.h ├── files.c ├── files.h ├── fin.c ├── fin.h ├── fpe_check.c ├── hash.c ├── icons ├── mawk144.png ├── mawk48.png └── mawk48.svg ├── init.c ├── init.h ├── install-sh ├── jmp.c ├── jmp.h ├── kw.c ├── main.c ├── makebits.c ├── makedeps.sh ├── makescan.c ├── man ├── Makefile.in ├── TODO ├── mawk-arrays.7 ├── mawk-code.7 ├── mawk-externs.dat ├── mawk.1 ├── mawk.doc └── mawk.txt ├── matherr.c ├── mawk.h ├── memory.c ├── memory.h ├── msdos ├── dosexec.c ├── examples │ ├── add_cr.awk │ ├── doslist.awk │ ├── objstat.awk │ ├── shell.awk │ ├── srcstat.awk │ ├── srcstat2.awk │ ├── texttest.awk │ ├── winexe.awk │ └── winobj.awk ├── vs2008.h └── vs2008.mak ├── nstd.h ├── package ├── debian │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── docs │ ├── postinst │ ├── postrm │ ├── preinst │ ├── prerm │ ├── rules │ ├── source │ │ └── format │ └── watch ├── freebsd │ ├── Makefile │ ├── distinfo │ └── pkg-descr └── mawk.spec ├── parse.c ├── parse.h ├── parse.y ├── patchlev.h ├── print.c ├── re_cmpl.c ├── regexp.c ├── regexp.h ├── regexp_system.c ├── repl.h ├── rexp.c ├── rexp.h ├── rexp0.c ├── rexp1.c ├── rexp2.c ├── rexp3.c ├── rexp4.c ├── rexpdb.c ├── scan.c ├── scan.h ├── scancode.h ├── sizes.h ├── split.c ├── split.h ├── symtype.h ├── test ├── cclass.awk ├── cclass.out ├── decl-awk.out ├── fpe_test ├── fpe_test.bat ├── fpetest1.awk ├── fpetest2.awk ├── fpetest3.awk ├── full-awk.dat ├── hashbang-S.sh ├── interval0.awk ├── interval0.out ├── longline.out ├── longline.sh ├── mawkerrs ├── mawknull.dat ├── mawktest ├── mawktest.bat ├── mawktest.dat ├── nextfile.awk ├── nextfile.out ├── noloop.awk ├── null-rs.awk ├── null-rs.dat ├── null-rs.out ├── nulls.out ├── nulls0.awk ├── reg-awk.out ├── reg0.awk ├── reg1.awk ├── reg2.awk ├── reg3.awk ├── reg4.awk ├── reg5.awk ├── reg6.awk ├── reg7.awk ├── repetitions.awk ├── repetitions.dat ├── repetitions.out ├── wc-awk.out ├── wc.awk ├── wfrq-awk.out └── wfrq0.awk ├── trace.c ├── types.h ├── version.c ├── vs6.mak ├── zmalloc.c └── zmalloc.h /ACKNOWLEDGMENT: -------------------------------------------------------------------------------- 1 | Version 1.2 2 | =========== 3 | 4 | Thanks for help with beta test to Bill Davidsen, Tom Dickey, Ed 5 | Ferguson, Jack Fitts, Onno van der Linden, Carl Mascott, Jean-Pierre 6 | Radley, John Roll, Ian Searle, Bob Stockler. 7 | 8 | The calendar program examples/hical was written by Bob Stockler. 9 | 10 | Darrel Hankerson ported versions 1.2.x to DOS/OS2. 11 | 12 | Version 1.0 and 1.1 13 | =================== 14 | 15 | Carl Mascott ported mawk to V7 and in the process rooted out 16 | some subtle (and not so subtle) bugs. 17 | 18 | Ian Searle ported mawk to System V and put up with my insane 19 | attempts to get fpe exception trapping off. 20 | 21 | An anonymous reviewer for comp.sources.reviewed did the 22 | MSC and Mac ports and wrote .bat files for the tests. 23 | Another or maybe the same reviewer did the Dynix port. 24 | 25 | Ports to new systems: 26 | Ed Ferguson MIPS M2000 C2.20 OS4.52 27 | Jwahar R. Bammi Atari ST 28 | Berry Kercheval SGI IRIX 4.0.1 29 | Andy Newman Next 2.1 30 | Mike Carlton Next 2.1 31 | Elliot Jaffe AIX 3.1 32 | Jeremy Martin Convex 9.1 33 | Scott Hunziker Coherent 4.0 34 | Ken Poulton Hpux 35 | Onno van der Linden 386bsd 0.1 36 | Bob Hutchinson Linux 0.98p14 37 | 38 | The DOS version is a lot better thanks to suggestions and testing 39 | from Ed Ferguson, Jack Fitts, Nadav Horesh, Michael Golan and 40 | Conny Ohstrom. The DOS additions for 1.1.2d are all ideas of 41 | Ben Myers; much of the code is his too. 42 | 43 | Arnold Robbins kept me current on POSIX standards for AWK, and 44 | explained some of the "dark corners". 45 | 46 | Thank you to everyone who reported bugs or offered encouragement, 47 | suggestions or criticism. (At least the bugs got fixed). 48 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | -- $MawkId: README,v 1.7 2023/02/16 00:19:21 tom Exp $ 2 | -- vile:txtmode fc=78 3 | 4 | mawk -- an implementation of new/posix awk 5 | version 1.3.4 6 | 7 | Generic installation instructions are in file INSTALL. 8 | This file gives more specific information. 9 | 10 | Send bug reports, comments, questions, etc. to 11 | 12 | Thomas E. Dickey 13 | https://invisible-island.net/mawk/ 14 | 15 | ------------------------------------------------------------------------------- 16 | 17 | Portability: 18 | ----------- 19 | 20 | This program builds/runs on several POSIX-style platforms. 21 | It has been recently tested for these: 22 | 23 | AIX (5.1 and 5.3, using cc and gcc) 24 | Cygwin (1.5.21 on Windows/XP) 25 | FreeBSD (6.0) 26 | HPUX (10.20, 11.00, 11.11 and 11.23, using cc and gcc) 27 | IRIX64 (using cc and gcc) 28 | Linux (several flavors, using gcc and icc) 29 | MinGW/MSYS (on Windows/XP) 30 | OpenBSD (4.1) 31 | Solaris (2.6 to 10, using cc and gcc) 32 | Tru64 (4.0D and 5.1, using cc and gcc) 33 | 34 | Options: 35 | ------- 36 | 37 | The configure script has these application-specific options: 38 | 39 | --disable-echo display "compiling" commands 40 | 41 | Show "compiling foo.c" rather than the full compiler and 42 | options. Those are clutter useful only to a developer. 43 | Developers focus on compiler warnings anyway. 44 | 45 | --enable-warnings test: turn on gcc compiler warnings 46 | 47 | This turns on the usual gcc compiler warnings needed to 48 | do useful development. If you happen to be using the 49 | Intel compiler icc, it does the right thing for that. 50 | 51 | --with-builtin-regex use mawk's own regular-expressions engine 52 | 53 | Normally mawk's configure script uses the built-in regular 54 | expressions. The choice of default is based on where the 55 | greatest lossage occurs. More scripts use gawk's 56 | null-character extension than use POSIX brace expressions. If 57 | your needs are different, build mawk using an external library. 58 | 59 | Limitations: 60 | ----------- 61 | 62 | mawk 1.3.3 was developed to correspond with a POSIX draft. POSIX 63 | continued, and incorporated some of mawk's extensions as features. 64 | The 1.3.4 release fills in the major areas in which POSIX grew past 65 | the mawk 1.3.3 implementation. 66 | 67 | mawk's built-in regular expression engine does not yet support brace 68 | expressions, e.g., 69 | 70 | /a{,4}/ 71 | 72 | Use an external regular expression library if you require brace 73 | expressions. Aside from that, mawk's built-in regular expressions 74 | provide POSIX functionality. 75 | 76 | Using an external regular expression library means that mawk cannot 77 | match expressions containing the null character. That is a 78 | nonstandard feature provided by gawk. Using mawk's built-in regular 79 | expressions, there is some support for this feature. 80 | 81 | Aside from supporting nulls, using an external regular expression 82 | library is usually advantageous. 83 | 84 | The Cygwin math library has some problems (which are also visible in 85 | the gawk port). For instance, its log() function returns Inf 86 | (infinity) for log(-8) rather than NaN (not a number) as all of the 87 | Unix and similar platforms would do. 88 | 89 | The MSYS package for regular expressions is unusable as an external 90 | library for mawk because it generates a runtime error when asked to 91 | compile a newline, e.g., "\n". mawk does this during initialization. 92 | 93 | The MinGW/MSYS port does not currently support pipes. There is 94 | source-code from the obsolete MS-DOS port which can be reused for this 95 | purpose; however that is not the focus of the 1.3.4 release. 96 | -------------------------------------------------------------------------------- /array.h: -------------------------------------------------------------------------------- 1 | /* array.h */ 2 | /* 3 | $MawkId: array.h,v 1.24 2024/12/14 12:49:15 tom Exp $ 4 | 5 | copyright 2009-2020,2024 Thomas E. Dickey 6 | copyright 1991-1996,2014 Michael D. Brennan 7 | 8 | This is a source file for mawk, an implementation of 9 | the AWK programming language. 10 | 11 | Mawk is distributed without warranty under the terms of 12 | the GNU General Public License, version 2, 1991. 13 | 14 | array.c and array.h were originally generated with the commands 15 | 16 | notangle -R'"array.c"' array.w > array.c 17 | notangle -R'"array.h"' array.w > array.h 18 | 19 | Notangle is part of Norman Ramsey's noweb literate programming package 20 | available from CTAN(ftp.shsu.edu). 21 | */ 22 | 23 | #ifndef ARRAY_H 24 | #define ARRAY_H 1 25 | 26 | #include 27 | #include 28 | 29 | typedef struct _array 30 | #ifdef Visible_ARRAY 31 | { 32 | PTR ptr; /* What this points to depends on the type */ 33 | size_t size; /* number of elts in the table */ 34 | size_t limit; /* Meaning depends on type */ 35 | unsigned hmask; /* bitwise and with hash value to get table index */ 36 | short type; /* values in AY_NULL .. AY_SPLIT */ 37 | } 38 | #endif 39 | *ARRAY; 40 | 41 | #define AY_NULL 0 42 | #define AY_INT 1 43 | #define AY_STR 2 44 | #define AY_SPLIT 4 45 | 46 | #define NO_CREATE 0 47 | #define CREATE 1 48 | #define new_ARRAY() ((ARRAY)memset(ZMALLOC(struct _array),0,sizeof(struct _array))) 49 | CELL *array_find(ARRAY, CELL *, int); 50 | void array_delete(ARRAY, CELL *); 51 | void array_load(ARRAY, size_t); 52 | void array_clear(ARRAY); 53 | STRING **array_loop_vector(ARRAY, size_t *); 54 | CELL *array_cat(CELL *, int); 55 | 56 | #endif /* ARRAY_H */ 57 | -------------------------------------------------------------------------------- /bi_funct.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | bi_funct.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: bi_funct.h,v 1.8 2024/08/25 17:17:31 tom Exp $ 15 | */ 16 | 17 | #ifndef BI_FUNCT_H 18 | #define BI_FUNCT_H 1 19 | 20 | #include 21 | 22 | extern const BI_REC bi_funct[]; 23 | 24 | void bi_init(void); 25 | 26 | /* builtin string functions */ 27 | CELL *bi_print(CELL *); 28 | CELL *bi_printf(CELL *); 29 | CELL *bi_length(CELL *); 30 | CELL *bi_alength(CELL *); /* length/size of an array */ 31 | CELL *bi_index(CELL *); 32 | CELL *bi_substr(CELL *); 33 | CELL *bi_sprintf(CELL *); 34 | CELL *bi_split(CELL *); 35 | CELL *bi_match(CELL *); 36 | CELL *bi_getline(CELL *); 37 | CELL *bi_sub(CELL *); 38 | CELL *bi_gsub(CELL *); 39 | CELL *bi_toupper(CELL *); 40 | CELL *bi_tolower(CELL *); 41 | 42 | /* builtin arith functions */ 43 | CELL *bi_sin(CELL *); 44 | CELL *bi_cos(CELL *); 45 | CELL *bi_atan2(CELL *); 46 | CELL *bi_log(CELL *); 47 | CELL *bi_exp(CELL *); 48 | CELL *bi_int(CELL *); 49 | CELL *bi_sqrt(CELL *); 50 | CELL *bi_srand(CELL *); 51 | CELL *bi_rand(CELL *); 52 | 53 | /* time functions */ 54 | CELL *bi_mktime(CELL *); 55 | CELL *bi_strftime(CELL *); 56 | CELL *bi_systime(CELL *); 57 | 58 | /* other builtins */ 59 | CELL *bi_close(CELL *); 60 | CELL *bi_system(CELL *); 61 | CELL *bi_fflush(CELL *); 62 | 63 | #endif /* BI_FUNCT_H */ 64 | -------------------------------------------------------------------------------- /bi_vars.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | bi_vars.c 3 | copyright 2009-2013,2024, Thomas E. Dickey 4 | copyright 1991-1992,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: bi_vars.c,v 1.13 2024/08/25 17:47:59 tom Exp $ 15 | */ 16 | 17 | #define Visible_CELL 18 | #define Visible_STRING 19 | #define Visible_SYMTAB 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | /* the builtin variables */ 29 | CELL bi_vars[NUM_BI_VAR]; 30 | 31 | /* the order here must match the order in bi_vars.h */ 32 | 33 | static const char *bi_var_names[NUM_BI_VAR] = 34 | { 35 | "NR", 36 | "FNR", 37 | "ARGC", 38 | "FILENAME", 39 | "OFS", 40 | "ORS", 41 | "RLENGTH", 42 | "RSTART", 43 | "SUBSEP" 44 | #if USE_BINMODE 45 | ,"BINMODE" 46 | #endif 47 | }; 48 | 49 | /* insert the builtin vars in the hash table */ 50 | 51 | void 52 | bi_vars_init(void) 53 | { 54 | register int i; 55 | register SYMTAB *s; 56 | 57 | for (i = 0; i < NUM_BI_VAR; i++) { 58 | s = insert(bi_var_names[i]); 59 | s->type = (char) ((i <= 1) ? ST_NR : ST_VAR); 60 | s->stval.cp = bi_vars + i; 61 | /* bi_vars[i].type = 0 which is C_NOINIT */ 62 | } 63 | 64 | s = insert("ENVIRON"); 65 | s->type = ST_ENV; 66 | 67 | /* set defaults */ 68 | 69 | FILENAME->type = C_STRING; 70 | FILENAME->ptr = (PTR) new_STRING(""); 71 | 72 | OFS->type = C_STRING; 73 | OFS->ptr = (PTR) new_STRING(" "); 74 | 75 | ORS->type = C_STRING; 76 | ORS->ptr = (PTR) new_STRING("\n"); 77 | 78 | SUBSEP->type = C_STRING; 79 | SUBSEP->ptr = (PTR) new_STRING("\034"); 80 | 81 | NR->type = FNR->type = C_DOUBLE; 82 | /* dval is already 0.0 */ 83 | 84 | #if USE_BINMODE 85 | BINMODE->type = C_DOUBLE; 86 | #endif 87 | } 88 | 89 | #ifdef NO_LEAKS 90 | void 91 | bi_vars_leaks(void) 92 | { 93 | int n; 94 | 95 | for (n = 0; n < NUM_BI_VAR; ++n) { 96 | switch (bi_vars[n].type) { 97 | case C_STRING: 98 | case C_STRNUM: 99 | case C_MBSTRN: 100 | free_STRING(string(&bi_vars[n])); 101 | break; 102 | } 103 | } 104 | } 105 | #endif 106 | -------------------------------------------------------------------------------- /bi_vars.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | bi_vars.h 3 | copyright 2010-2023,2024 Thomas E. Dickey 4 | copyright 1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: bi_vars.h,v 1.10 2024/08/25 17:17:31 tom Exp $ 15 | */ 16 | 17 | /* bi_vars.h */ 18 | 19 | #ifndef BI_VARS_H 20 | #define BI_VARS_H 1 21 | 22 | #include 23 | 24 | /* builtin variables NF, RS, FS, OFMT are stored 25 | internally in field[], so side effects of assignment can 26 | be handled 27 | */ 28 | 29 | /* NR and FNR must be next to each other */ 30 | #define NR bi_vars 31 | #define FNR (bi_vars+1) 32 | #define ARGC (bi_vars+2) 33 | #define FILENAME (bi_vars+3) 34 | #define OFS (bi_vars+4) 35 | #define ORS (bi_vars+5) 36 | #define RLENGTH (bi_vars+6) 37 | #define RSTART (bi_vars+7) 38 | #define SUBSEP (bi_vars+8) 39 | 40 | #if USE_BINMODE 41 | #define BINMODE (bi_vars+9) 42 | #define NUM_BI_VAR 10 43 | #else 44 | #define NUM_BI_VAR 9 45 | #endif 46 | 47 | extern CELL bi_vars[NUM_BI_VAR]; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /code.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | code.h 3 | copyright 2009-2023,2024, Thomas E. Dickey 4 | copyright 1991-1994,1995, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: code.h,v 1.16 2024/08/25 19:46:17 tom Exp $ 15 | */ 16 | 17 | /* code.h */ 18 | 19 | #ifndef MAWK_CODE_H 20 | #define MAWK_CODE_H 21 | 22 | #include 23 | 24 | #define PAGESZ 512 25 | /* number of code instructions allocated at one time */ 26 | #define CODEWARN 16 27 | 28 | /* coding scope */ 29 | #define SCOPE_MAIN 0 30 | #define SCOPE_BEGIN 1 31 | #define SCOPE_END 2 32 | #define SCOPE_FUNCT 3 33 | 34 | typedef struct _codeblock 35 | #ifdef Visible_CODEBLOCK 36 | { 37 | INST *base, *limit, *warn, *ptr; 38 | } 39 | #endif 40 | CODEBLOCK; 41 | 42 | extern CODEBLOCK active_code; 43 | extern CODEBLOCK *main_code_p, *begin_code_p, *end_code_p; 44 | 45 | extern INST *main_start, *begin_start, *end_start; 46 | extern size_t main_size, begin_size; 47 | extern INST *execution_start; 48 | extern INST *next_label; /* next statements jump to here */ 49 | extern int dump_code_flag; 50 | 51 | #define CodeOffset(base) (int)(code_ptr - (base)) 52 | 53 | #define code_ptr active_code.ptr 54 | #define code_base active_code.base 55 | #define code_warn active_code.warn 56 | #define code_limit active_code.limit 57 | #define code_offset CodeOffset(code_base) 58 | 59 | #define INST_BYTES(x) (sizeof(INST)*(unsigned)(x)) 60 | 61 | extern CELL eval_stack[]; 62 | extern int exit_code; 63 | 64 | #define code1(x) code_ptr++ -> op = (x) 65 | /* shutup picky compilers */ 66 | #define code2(x,p) xcode2(x,(PTR)(p)) 67 | #define func2(x,p) xfunc2(x,(p)) 68 | 69 | void xcode2(int, PTR); 70 | void xfunc2(int, PF_CP); 71 | void code2op(int, int); 72 | INST *code_shrink(CODEBLOCK *, size_t *); 73 | void code_grow(void); 74 | void set_code(void); 75 | void be_setup(int); 76 | void dump_code(void); 77 | 78 | /* the machine opcodes */ 79 | /* to avoid confusion with a ptr FE_PUSHA must have op code 0 */ 80 | 81 | typedef enum { 82 | FE_PUSHA = 0 83 | ,FE_PUSHI 84 | ,F_PUSHA 85 | ,F_PUSHI 86 | ,NF_PUSHI 87 | ,_HALT 88 | ,_STOP 89 | ,_PUSHC 90 | ,_PUSHD 91 | ,_PUSHS 92 | ,_PUSHINT 93 | ,_PUSHA 94 | ,_PUSHI 95 | ,L_PUSHA 96 | ,L_PUSHI 97 | ,AE_PUSHA 98 | ,AE_PUSHI 99 | ,A_PUSHA 100 | ,LAE_PUSHA 101 | ,LAE_PUSHI 102 | ,LA_PUSHA 103 | ,_POP 104 | ,_ADD 105 | ,_SUB 106 | ,_MUL 107 | ,_DIV 108 | ,_MOD 109 | ,_POW 110 | ,_NOT 111 | ,_TEST 112 | ,A_TEST 113 | ,_LENGTH 114 | ,A_LENGTH 115 | ,A_DEL 116 | ,ALOOP 117 | ,A_CAT 118 | ,_UMINUS 119 | ,_UPLUS 120 | ,_ASSIGN 121 | ,_ADD_ASG 122 | ,_SUB_ASG 123 | ,_MUL_ASG 124 | ,_DIV_ASG 125 | ,_MOD_ASG 126 | ,_POW_ASG 127 | ,F_ASSIGN 128 | ,F_ADD_ASG 129 | ,F_SUB_ASG 130 | ,F_MUL_ASG 131 | ,F_DIV_ASG 132 | ,F_MOD_ASG 133 | ,F_POW_ASG 134 | ,_CAT 135 | ,_BUILTIN 136 | ,_PRINT 137 | ,_POST_INC 138 | ,_POST_DEC 139 | ,_PRE_INC 140 | ,_PRE_DEC 141 | ,F_POST_INC 142 | ,F_POST_DEC 143 | ,F_PRE_INC 144 | ,F_PRE_DEC 145 | ,_JMP 146 | ,_JNZ 147 | ,_JZ 148 | ,_LJZ 149 | ,_LJNZ 150 | ,_EQ 151 | ,_NEQ 152 | ,_LT 153 | ,_LTE 154 | ,_GT 155 | ,_GTE 156 | ,_MATCH0 157 | ,_MATCH1 158 | ,_MATCH2 159 | ,_EXIT 160 | ,_EXIT0 161 | ,_NEXT 162 | ,_NEXTFILE 163 | ,_RANGE 164 | ,_CALL 165 | ,_CALLX 166 | ,_RET 167 | ,_RET0 168 | ,SET_ALOOP 169 | ,POP_AL 170 | ,OL_GL 171 | ,OL_GL_NR 172 | ,_OMAIN 173 | ,_JMAIN 174 | ,DEL_A 175 | } MAWK_OPCODES; 176 | 177 | #endif /* MAWK_CODE_H */ 178 | -------------------------------------------------------------------------------- /config_h.in: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | config_h.in 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | vile:cmode 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: config_h.in,v 1.43 2024/12/14 01:12:07 tom Exp $ 15 | * template for config.h 16 | */ 17 | 18 | #undef DECL_ENVIRON 19 | #undef FPE_TRAPS_ON 20 | #undef GCC_NORETURN 21 | #undef GCC_PRINTFLIKE 22 | #undef GCC_SCANFLIKE 23 | #undef GCC_UNUSED 24 | #undef HAVE_BSD_STDLIB_H 25 | #undef HAVE_CLOCK_GETTIME 26 | #undef HAVE_ENVIRON 27 | #undef HAVE_ERRNO_H 28 | #undef HAVE_FCNTL_H 29 | #undef HAVE_FORK 30 | #undef HAVE_FSEEKO 31 | #undef HAVE_FSTAT 32 | #undef HAVE_GETTIMEOFDAY 33 | #undef HAVE_INT64_T 34 | #undef HAVE_INTTYPES_H 35 | #undef HAVE_ISINF 36 | #undef HAVE_ISNAN 37 | #undef HAVE_LIMITS_H 38 | #undef HAVE_LONG_LONG 39 | #undef HAVE_MATHERR 40 | #undef HAVE_MATH__LIB_VERSION 41 | #undef HAVE_MEMORY_H 42 | #undef HAVE_MKTIME 43 | #undef HAVE_PIPE 44 | #undef HAVE_REAL_PIPES 45 | #undef HAVE_REGEXPR_H_FUNCS 46 | #undef HAVE_REGEXP_H_FUNCS 47 | #undef HAVE_REGEX_H_FUNCS 48 | #undef HAVE_SIGACTION 49 | #undef HAVE_SIGACTION_SA_SIGACTION 50 | #undef HAVE_SIGINFO_H 51 | #undef HAVE_STDINT_H 52 | #undef HAVE_STDLIB_H 53 | #undef HAVE_STRFTIME 54 | #undef HAVE_STRINGS_H 55 | #undef HAVE_STRING_H 56 | #undef HAVE_STRTOD_OVF_BUG 57 | #undef HAVE_SYS_STAT_H 58 | #undef HAVE_SYS_TYPES_H 59 | #undef HAVE_SYS_WAIT_H 60 | #undef HAVE_TDESTROY 61 | #undef HAVE_TSEARCH 62 | #undef HAVE_UINT64_T 63 | #undef HAVE_UNISTD_H 64 | #undef HAVE_WAIT 65 | #undef LOCALE 66 | #undef LOCAL_REGEXP 67 | #undef MAWK_RAND_MAX 68 | #undef MAX__INT 69 | #undef MAX__LONG 70 | #undef MAX__UINT 71 | #undef MAX__ULONG 72 | #undef NAME_RANDOM 73 | #undef NOINFO_SIGFPE 74 | #undef NO_GAWK_OPTIONS 75 | #undef NO_INIT_SRAND 76 | #undef NO_INTERVAL_EXPR 77 | #undef NO_LEAKS 78 | #undef SIZEOF_DOUBLE 79 | #undef SIZEOF_FLOAT 80 | #undef SIZEOF_INT64_T 81 | #undef SIZEOF_LONG 82 | #undef SIZEOF_LONG_LONG 83 | #undef SIZE_T_STDDEF_H 84 | #undef SIZE_T_TYPES_H 85 | #undef STDC_HEADERS 86 | #undef SYSTEM_NAME 87 | #undef TURN_OFF_FPE_TRAPS 88 | #undef TURN_ON_FPE_TRAPS 89 | #undef USE_IEEEFP_H 90 | #undef YY_NO_LEAKS 91 | #undef const 92 | #undef mawk_rand 93 | #undef mawk_srand 94 | 95 | #ifndef GCC_NORETURN 96 | #define GCC_NORETURN /* nothing */ 97 | #endif 98 | 99 | #ifndef GCC_UNUSED 100 | #define GCC_UNUSED /* nothing */ 101 | #endif 102 | 103 | #ifndef OPT_TRACE 104 | #define OPT_TRACE 0 105 | #endif 106 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | dnl $MawkId: configure.in,v 1.77 2024/12/14 00:43:08 tom Exp $ 2 | dnl configure.in for mawk 3 | dnl ########################################################################### 4 | dnl copyright 2008-2023,2024, Thomas E. Dickey 5 | dnl copyright 1991-1994,1995, Michael D. Brennan 6 | dnl 7 | dnl This is a source file for mawk, an implementation of 8 | dnl the AWK programming language. 9 | dnl 10 | dnl Mawk is distributed without warranty under the terms of 11 | dnl the GNU General Public License, version 2, 1991. 12 | dnl ########################################################################### 13 | dnl 14 | AC_PREREQ(2.52.20230114) 15 | AC_INIT(mawk.h) 16 | 17 | AC_CONFIG_HEADER(config.h:config_h.in) 18 | CF_CHECK_CACHE 19 | 20 | AC_ARG_PROGRAM 21 | 22 | AC_DEFUN([AC_PATH_XTRA],[]) 23 | CF_PROG_CC 24 | AC_PROG_MAKE_SET 25 | CF_MAKEFLAGS 26 | CF_MAKE_PHONY 27 | AC_PROG_CPP 28 | AC_PROG_INSTALL 29 | 30 | AC_PROG_YACC 31 | CF_PROG_LINT 32 | CF_MAKE_TAGS 33 | 34 | CF_XOPEN_SOURCE 35 | CF_LARGEFILE 36 | AC_CHECK_DECL(exit) 37 | 38 | CF_HELP_MESSAGE(Cross-compiling) 39 | CF_BUILD_CC 40 | 41 | CF_MAWK_MATHLIB 42 | 43 | CF_HELP_MESSAGE(Miscellaneous options) 44 | CF_DISABLE_ECHO 45 | CF_ENABLE_WARNINGS 46 | CF_WITH_MAN2HTML 47 | 48 | ############################################################################### 49 | AC_MSG_CHECKING(if you want to use mawk's own regular-expressions engine) 50 | AC_ARG_WITH([builtin-regex], 51 | [ --without-builtin-regex do not use mawk's own regular-expressions engine], 52 | [ 53 | with_builtin_regex=$withval 54 | ]) 55 | if test "x${with_builtin_regex}" != xno; then 56 | with_builtin_regex=yes 57 | AC_DEFINE(LOCAL_REGEXP,1,[define to 1 to use mawk's own regular-expressions engine]) 58 | fi 59 | AC_MSG_RESULT($with_builtin_regex) 60 | 61 | if test "x${with_builtin_regex}" = xno; then 62 | CF_REGEX 63 | fi 64 | 65 | ############################################################################### 66 | AC_MSG_CHECKING(if you want to use mawk's own srand/rand functions) 67 | CF_ARG_ENABLE([builtin-srand], 68 | [ --enable-builtin-srand use mawk's own srand/rand functions], 69 | [with_builtin_srand=yes], 70 | [with_builtin_srand=no]) 71 | if test "x${with_builtin_srand}" != xno; then 72 | with_builtin_srand=yes 73 | fi 74 | AC_MSG_RESULT($with_builtin_srand) 75 | 76 | if test "x${with_builtin_srand}" = xno; then 77 | CF_SRAND(mawk_,no) 78 | AC_DEFINE_UNQUOTED(NAME_RANDOM, "$cf_cv_srand_func", [Define to the name of the random-function]) 79 | fi 80 | 81 | ############################################################################### 82 | AC_MSG_CHECKING(if you want mawk to initialize random numbers at startup) 83 | CF_ARG_DISABLE([init-srand], 84 | [ --disable-init-srand suppress automatic initialization of random numbers], 85 | [with_init_srand=no], 86 | [with_init_srand=yes]) 87 | if test "x${with_init_srand}" != xno; then 88 | with_init_srand=yes 89 | else 90 | AC_DEFINE(NO_INIT_SRAND,1,[define to 1 to suppress automatic initialization of random numbers]) 91 | fi 92 | AC_MSG_RESULT($with_init_srand) 93 | 94 | ############################################################################### 95 | AC_MSG_CHECKING(if you want mawk to support regex interval expressions {m[,]n}) 96 | CF_ARG_DISABLE([interval-expr], 97 | [ --disable-interval-expr suppress regex interval expressions {m,n}], 98 | [with_interval_expr=no], 99 | [with_interval_expr=yes]) 100 | if test "x${with_interval_expr}" != xno; then 101 | with_interval_expr=yes 102 | else 103 | AC_DEFINE(NO_INTERVAL_EXPR,1,[define to 1 to suppress regex interval expressions {m,n}]) 104 | fi 105 | AC_MSG_RESULT($with_interval_expr) 106 | 107 | ############################################################################### 108 | 109 | CF_HELP_MESSAGE(Testing-options) 110 | CF_DISABLE_LEAKS 111 | 112 | CF_ENABLE_TRACE 113 | 114 | if test "x$with_trace" = xyes 115 | then 116 | EXTRAOBJS="$EXTRAOBJS trace\$o" 117 | fi 118 | AC_SUBST(EXTRAOBJS) 119 | 120 | AC_CHECK_HEADERS(errno.h fcntl.h sys/time.h sys/wait.h) 121 | 122 | AC_CHECK_TYPES([int64_t, uint64_t, long long]) 123 | 124 | AC_CHECK_SIZEOF(float) 125 | AC_CHECK_SIZEOF(double) 126 | AC_CHECK_SIZEOF(long) 127 | AC_CHECK_SIZEOF(int64_t) 128 | AC_CHECK_SIZEOF(long long) 129 | 130 | CF_MAWK_FIND_SIZE_T 131 | 132 | CF_LOCALE 133 | CF_CHECK_ENVIRON(environ) 134 | 135 | AC_CHECK_FUNCS(fork fstat matherr mktime pipe strftime tsearch wait) 136 | CF_FUNC_GETTIME 137 | 138 | ### Checks for libraries. 139 | case $cf_cv_system_name in 140 | (*mingw32*) 141 | CPPFLAGS="$CPPFLAGS -DWINVER=0x0501" 142 | # LIBS=" -lpsapi $LIBS" 143 | ;; 144 | esac 145 | 146 | test "$ac_cv_func_fork" = yes && \ 147 | test "$ac_cv_func_pipe" = yes && \ 148 | test "$ac_cv_func_wait" = yes && \ 149 | AC_DEFINE(HAVE_REAL_PIPES,1,[Define to 1 if we have functions needed to setup Unix pipes]) 150 | 151 | CF_SET_MATH_LIB_VERSION 152 | CF_MAWK_FIND_MAX_INT 153 | CF_MAWK_RUN_FPE_TESTS 154 | 155 | AC_CONFIG_FILES([Makefile man/Makefile]) 156 | AC_OUTPUT 157 | -------------------------------------------------------------------------------- /examples/ct_length.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: ct_length.awk,v 1.3 2020/09/19 14:49:10 tom Exp $ 3 | 4 | # ct_length.awk 5 | # 6 | # replaces all length 7 | # by length($0) 8 | 9 | { 10 | 11 | while ( ( i = index($0, "length") ) > 0 ) 12 | { 13 | printf "%s" , substr($0,1, i+5) # ...length 14 | $0 = substr($0,i+6) 15 | 16 | if ( match($0, /^[ \t]*\(/) ) 17 | { 18 | # its OK 19 | printf "%s", substr($0, 1, RLENGTH) 20 | $0 = substr($0, RLENGTH+1) 21 | } 22 | else # length alone 23 | printf "($0)" 24 | 25 | } 26 | print 27 | } 28 | -------------------------------------------------------------------------------- /examples/decl.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | # $MawkId: decl.awk,v 1.12 2020/09/19 13:46:31 tom Exp $ 3 | 4 | # parse a C declaration by recursive descent 5 | # based on a C program in K&R ANSI edition 6 | # 7 | # run on a C file it finds the declarations 8 | # 9 | # restrictions: one declaration per line 10 | # doesn't understand struct {...} 11 | # makes assumptions about type names 12 | # 13 | # 14 | # some awks need double escapes on strings used as 15 | # regular expressions. If not run on mawk, use gdecl.awk 16 | 17 | ################################################ 18 | # lexical scanner -- gobble() 19 | # input : string s -- treated as a regular expression 20 | # gobble eats SPACE, then eats longest match of s off front 21 | # of global variable line. 22 | # Cuts the matched part off of line 23 | 24 | function gobble(s, xg) 25 | { 26 | if ( length(line) > 0 ) { 27 | sub( /^ /, "", line) # eat SPACE if any 28 | 29 | # surround s with parenthesis to make sure ^ acts on the 30 | # whole thing 31 | 32 | if ( match(line, "^" "(" s ")") > 0 ) { 33 | xg = substr(line, 1, RLENGTH) 34 | line = (RLENGTH < length(line)) ? substr(line, RLENGTH+1) : "" 35 | return xg 36 | } else { 37 | return ""; 38 | } 39 | } else { 40 | return ""; 41 | } 42 | } 43 | 44 | function ptr_to(n, xp) # print "pointer to" , n times 45 | { n = int(n) 46 | if ( n <= 0 ) return "" 47 | xp = "pointer to" ; n-- 48 | while ( n-- ) xp = xp " pointer to" 49 | return xp 50 | } 51 | 52 | #recursively get a decl 53 | # returns an english description of the declaration or 54 | # "" if not a C declaration. 55 | function decl( xd, t, ptr_part) 56 | { 57 | 58 | xd = gobble("[* ]+") # get list of *** ... 59 | gsub(/ /, "", xd) # remove all SPACES 60 | ptr_part = ptr_to( length(xd) ) 61 | 62 | # We expect to see either an identifier or '(' 63 | # 64 | 65 | if ( gobble("[(]") ) 66 | { 67 | # this is the recursive descent part 68 | # we expect to match a declaration and closing ')' 69 | # If not return "" to indicate failure 70 | 71 | if ( (xd = decl()) == "" || gobble( "[)]" ) == "" ) return "" 72 | 73 | } 74 | else # expecting an identifier 75 | { 76 | if ( (xd = gobble(id)) == "" ) return "" 77 | xd = xd ":" 78 | } 79 | 80 | # finally look for () 81 | # or [ opt_size ] 82 | 83 | while ( 1 ) 84 | if ( gobble( funct_mark ) ) xd = xd " function returning" 85 | else 86 | if ( ( t = gobble( array_mark ) ) != "" ) 87 | { gsub(/ /, "", t) 88 | xd = xd " array" t " of" 89 | } 90 | else break 91 | 92 | xd = xd " " ptr_part 93 | return xd 94 | } 95 | 96 | BEGIN { 97 | id = "[_A-Za-z][_A-Za-z0-9]*" 98 | funct_mark = "[(][ \t]*[)]" 99 | array_mark = "[[ \t]*[_A-Za-z0-9]*[ \t]*]" 100 | 101 | # I've assumed types are keywords or all CAPS or end in _t 102 | # Other conventions could be added. 103 | 104 | type0 = "int|char|short|long|double|float|void" 105 | type1 = "[_A-Z][_A-Z0-9]*" # types are CAPS 106 | type2 = "[_A-Za-z][_A-Za-z0-9]*_t" # end in _t 107 | 108 | types = "(" type0 "|" type1 "|" type2 ")" 109 | } 110 | 111 | 112 | { 113 | gsub( "/[*]([^*]|[*][^/])*([*]/|$)" , " ") # remove comments 114 | gsub( /[ \t]+/, " ") # squeeze white space to a single space 115 | 116 | line = $0 117 | 118 | scope = gobble( "extern|static" ) 119 | 120 | if ( ( type = gobble("(struct|union|enum) ") ) != "" ) 121 | type = type gobble(id) # get the tag 122 | else 123 | { 124 | type = gobble("(un)?signed ") gobble( types ) 125 | } 126 | 127 | if ( ! type ) next 128 | 129 | if ( (x = decl()) != "" && gobble( ";") ) 130 | { 131 | x = x " " type 132 | if ( scope ) x = x " (" scope ")" 133 | gsub( / +/, " ", x) # 134 | print x 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /examples/deps.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: deps.awk,v 1.4 2023/10/31 22:58:49 tom Exp $ 3 | # vile: notab ts=4 sw=4 4 | 5 | # find include dependencies in C source 6 | # 7 | # mawk -f deps.awk C_source_files 8 | # -- prints a dependency list suitable for make 9 | 10 | BEGIN { 11 | stack_index = 0 # stack[] holds the input files 12 | 13 | for(i = 1 ; i < ARGC ; i++) 14 | { 15 | file = ARGV[i] 16 | if ( file !~ /\.[cC]$/ ) continue # skip it 17 | outfile = substr(file, 1, length(file)-2) ".o" 18 | 19 | # INCLUDED[] stores the set of included files 20 | # -- start with the empty set 21 | for( j in INCLUDED ) delete INCLUDED[j] 22 | 23 | while ( 1 ) 24 | { 25 | if ( getline line < file <= 0 ) # no open or EOF 26 | { 27 | if ( stack_index == 0 ) break # empty stack 28 | else 29 | { 30 | file = stack[ stack_index-- ] 31 | continue 32 | } 33 | } 34 | 35 | if ( line ~ /^#include[ \t]+".*"/ ) 36 | split(line, X, "\"") # filename is in X[2] 37 | else if ( line ~ /^#include[ \t]+<.*>/ ) 38 | split(line, X, "[<>]") # filename is in X[2] 39 | else 40 | continue; 41 | 42 | if ( X[2] in INCLUDED ) # we've already included it 43 | continue 44 | if ( getline line < X[2] <= 0 ) # no open or EOF 45 | continue; 46 | 47 | #push current file 48 | stack[ ++stack_index ] = file 49 | INCLUDED[ file = X[2] ] = "" 50 | } # end of while 51 | 52 | # test if INCLUDED is empty 53 | flag = 0 # on once the front is printed 54 | for( j in INCLUDED ) 55 | { 56 | if ( ! flag ) 57 | { printf "%s : %s" , outfile, j ; flag = 1 } 58 | else printf " %s" , j 59 | close(j); 60 | } 61 | 62 | if ( flag ) print "" 63 | 64 | }# end of loop over files in ARGV[i] 65 | 66 | } 67 | -------------------------------------------------------------------------------- /examples/eatc.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: eatc.awk,v 1.3 2020/09/19 11:51:23 tom Exp $ 3 | # eatc.awk 4 | # another program to remove comments 5 | 6 | { while( ( t = index($0 , "/*") ) > 0 ) 7 | { 8 | if ( t > 1 ) 9 | printf "%s" , substr($0,1,t-1) 10 | $0 = eat_comment( ( t + 2 <= length($0) ) ? substr($0, t+2) : "" ) 11 | } 12 | 13 | print 14 | } 15 | 16 | 17 | function eat_comment(s, t2) 18 | { 19 | #replace comment by one space 20 | printf " " 21 | 22 | while ( (t2 = index(s, "*/")) == 0 ) 23 | if ( getline s == 0 ) 24 | { # input error -- unterminated comment 25 | system("/bin/sh -c 'echo unterminated comment' 1>&2") 26 | exit 1 27 | } 28 | 29 | return ( t2 + 2 <= length(s) ) ? substr(s,t2+2) : "" 30 | } 31 | -------------------------------------------------------------------------------- /examples/gdecl.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: gdecl.awk,v 1.6 2020/09/19 14:04:25 tom Exp $ 3 | 4 | # parse a C declaration by recursive descent 5 | # 6 | # decl.awk with extra escapes \ 7 | 8 | ################################################ 9 | ############################################ 10 | 11 | 12 | # lexical scanner -- gobble() 13 | # input : string s -- treated as a regular expression 14 | # gobble eats SPACE, then eats longest match of s off front 15 | # of global variable line. 16 | # Cuts the matched part off of line 17 | 18 | function gobble(s, xg) 19 | { 20 | sub( /^ /, "", line) # eat SPACE if any 21 | 22 | # surround s with parenthesis to make sure ^ acts on the 23 | # whole thing 24 | 25 | if ( match(line, "^" "(" s ")") > 0 ) { 26 | xg = substr(line, 1, RLENGTH) 27 | line = (RLENGTH < length(line)) ? substr(line, RLENGTH+1) : "" 28 | return xg 29 | } else { 30 | return "" 31 | } 32 | } 33 | 34 | function ptr_to(n, xp) # print "pointer to" , n times 35 | { n = int(n) 36 | if ( n <= 0 ) return "" 37 | xp = "pointer to" ; n-- 38 | while ( n-- ) xp = xp " pointer to" 39 | return xp 40 | } 41 | 42 | #recursively get a decl 43 | # returns an english description of the declaration or 44 | # "" if not a C declaration. 45 | function decl( xd, t, ptr_part) 46 | { 47 | 48 | xd = gobble("[* ]+") # get list of *** ... 49 | gsub(/ /, "", xd) # remove all SPACES 50 | ptr_part = ptr_to( length(xd) ) 51 | 52 | # We expect to see either an identifier or '(' 53 | if ( gobble("\\(") ) 54 | { 55 | # this is the recursive descent part 56 | # we expect to match a declaration and closing ')' 57 | # If not return "" to indicate failure 58 | 59 | if ( (xd = decl()) == "" || gobble( "\\)" ) == "" ) return "" 60 | 61 | } 62 | else # expecting an identifier 63 | { 64 | if ( (xd = gobble(id)) == "" ) return "" 65 | xd = xd ":" 66 | } 67 | 68 | # finally look for () 69 | # or [ opt_size ] 70 | 71 | while ( 1 ) 72 | if ( gobble( funct_mark ) ) xd = xd " function returning" 73 | else 74 | if ( ( t = gobble( array_mark ) ) != "" ) 75 | { gsub(/ /, "", t) 76 | xd = xd " array" t " of" 77 | } 78 | else break 79 | 80 | 81 | xd = xd " " ptr_part 82 | return xd 83 | } 84 | 85 | 86 | BEGIN { id = "[_A-Za-z][_A-Za-z0-9]*" 87 | funct_mark = "\\([ \t]*\\)" 88 | array_mark = "\\[[ \t]*[_A-Za-z0-9]*[ \t]*\\]" 89 | 90 | # I've assumed types are keywords or all CAPS or end in _t 91 | # Other conventions could be added. 92 | 93 | type0 = "int|char|short|long|double|float|void" 94 | type1 = "[_A-Z][_A-Z0-9]*" # types are CAPS 95 | type2 = "[_A-Za-z][_A-Za-z0-9]*_t" # end in _t 96 | 97 | types = "(" type0 "|" type1 "|" type2 ")" 98 | } 99 | 100 | { 101 | gsub( /\/\*([^*]|\*[^\/])*(\*\/|$)/ , " ") # remove comments 102 | gsub( /[ \t]+/, " ") # squeeze white space to a single space 103 | 104 | line = $0 105 | 106 | scope = gobble( "extern|static" ) 107 | 108 | if ( ( type = gobble("(struct|union|enum) ") ) != "" ) 109 | { 110 | type = type gobble(id) # get the tag 111 | } 112 | else 113 | { 114 | type = gobble("(un)?signed ") gobble( types ) 115 | } 116 | 117 | if ( ! type ) next 118 | 119 | if ( ( (x = decl()) != "" ) && gobble( ";") ) 120 | { 121 | x = x " " type 122 | if ( scope ) x = x " (" scope ")" 123 | gsub( / +/, " ", x) # 124 | print x 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /examples/hical: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $MawkId: hical,v 1.4 2009/08/21 00:36:34 tom Exp $ 3 | 4 | # @(#) hical - displays previous, current & next months - today highlighted 5 | # @(#) an "internationalizationable" version of a 3-month 'cal' display, it 6 | # @(#) may be edited for week to start with Sun or Mon & for local language 7 | 8 | prog=${TMPDIR-/tmp}/hical.$$ ; trap 'rm -f $prog ; trap 0 ; exit' 0 1 2 3 15 9 | 10 | : ${so:=`tput smso`} ${se:=`tput rmso`} 11 | 12 | # USER EDITS MAY BE REQUIRED for the arguments to the 'date' command 13 | # the script presumes 'date' recognizes these arguments in these ways: 14 | # w - Day of the week - Sunday = 0 15 | # m - Month of year - 01 to 12 16 | # d - Day of month - 01 to 31 17 | # T - Time as HH:MM:SS 18 | # Y - Year (including century), as decimal numbers 19 | DATE_ARGS='%w %m %d %T %Y' 20 | 21 | # the 'awk' program file is written to a temporary file to avoid any 22 | # "arg list too long" error messages, yet have all the code in one file. 23 | cat >$prog <<'EOF' 24 | { 25 | # USER EDITS MAY BE REQUIRED (for FMT, day & month names, and the time stuff) 26 | # FMT = 0 # for weekdays ordered "Mo Tu We Th Fr Sa Su" 27 | FMT = 1 # for weekdays ordered "Su Mo Tu We Th Fr Sa" 28 | Header[0] = "Mo Tu We Th Fr Sa Su" 29 | Header[1] = "Su Mo Tu We Th Fr Sa" 30 | months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" 31 | time_is = "The time is:" ; time_fmt = "%s %s %s %s\n" 32 | # NO MORE USER EDITS REQUIRED (I think!) 33 | split(months,M_Name) ; split("31 28 31 30 31 30 31 31 30 31 30 31",M_Len) 34 | daynum = $1 + FMT 35 | Mon[2] = $2 + 0 36 | today = $3 + 0 37 | time = $4 38 | Year[1] = Year[2] = Year[3] = $NF 39 | if ( Mon[2] == 1 ) { Year[1] = Year[1] - 1 ; Mon[1] = 12 } 40 | else { Mon[1] = Mon[2] - 1 } 41 | if ( Mon[2] == 12 ) { Year[3] = Year[3] + 1 ; Mon[3] = 1 } 42 | else { Mon[3] = Mon[2] + 1 } 43 | if ( Year[2] % 4 == 0 && 44 | Year[2] % 100 != 0 || 45 | Year[2] % 400 == 0 ) M_Len[2] = 29 46 | Start[2] = 7 - ( ( today - daynum ) % 7 ) 47 | Start[1] = 7 - ( ( M_Len[Mon[1]] - Start[2] ) % 7 ) 48 | Start[3] = ( M_Len[Mon[2]] + Start[2] ) % 7 49 | for (i=1;i<=3;i++) { while ( Start[i] >= 7 ) Start[i] -= 7 } 50 | for (mm=1;mm<=3;mm++) { 51 | if ( Year[mm] != Year[mm-1] ) 52 | printf( "%s %s %s\n", so, Year[mm], se ) 53 | if ( mm == 1 ) printf( "%s %s %s\n", so, Header[FMT], se ) 54 | j = k = 1 55 | while ( j <= M_Len[Mon[mm]] ) { 56 | line = "" 57 | for (i=1;i<=7;i++) { 58 | if ( Start[mm] > 0 || j > M_Len[Mon[mm]] ) { date = "" ; Start[mm]-- } 59 | else date = j++ 60 | if ( mm == 2 && date == today ) { So = so ; Se = se } 61 | else { So = Se = "" } 62 | line = sprintf( "%s%s%2s%s ", line, So, date, Se ) 63 | } 64 | m1 = substr(M_Name[Mon[mm]],k++,1) 65 | printf( "%s %1s %s %s%s %s\n", so, m1, se, line, so, se ) 66 | } 67 | } 68 | printf( time_fmt, so, time_is, time, se ) 69 | } 70 | EOF 71 | 72 | date +"$DATE_ARGS" | ${AWK:=mawk} -f $prog so=$so se=$se 73 | 74 | exit 0 75 | 76 | # EOF 'hical' - Tue Dec 19 19:19:19 EST 1994 77 | # Bob Stockler - bob@trebor.iglou.com - CIS: 72726,452 78 | -------------------------------------------------------------------------------- /examples/nocomment.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: nocomment.awk,v 1.3 2020/09/19 13:02:14 tom Exp $ 3 | 4 | # remove C comments from a list of files 5 | # using a comment as the record separator 6 | # 7 | # this is trickier than I first thought 8 | # The first version in .97-.9993 was wrong 9 | 10 | BEGIN { 11 | # RS is set to a comment (this is mildly tricky, I blew it here 12 | RS = "/[*]([^*]|[*]+[^*/])*[*]+/" 13 | ORS = " " 14 | getline hold 15 | filename = FILENAME 16 | } 17 | 18 | # if changing files 19 | filename != FILENAME { 20 | filename = FILENAME 21 | printf "%s" , hold 22 | hold = $0 23 | next 24 | } 25 | 26 | { # hold one record because we don't want ORS on the last 27 | # record in each file 28 | print hold 29 | hold = $0 30 | } 31 | 32 | END { printf "%s", hold } 33 | -------------------------------------------------------------------------------- /examples/primes.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | 3 | # primes.awk 4 | # 5 | # mawk -f primes.awk [START] STOP 6 | # find all primes between 2 and STOP 7 | # or START and STOP 8 | # 9 | 10 | 11 | 12 | function usage() 13 | { ustr = sprintf("usage: %s [start] stop", ARGV[0]) 14 | system( "echo " ustr) 15 | exit 1 16 | } 17 | 18 | 19 | BEGIN { if (ARGC == 1 || ARGC > 3 ) usage() 20 | if ( ARGC == 2 ) { start = 2 ; stop = ARGV[1]+0 } 21 | else 22 | if ( ARGC == 3 ) { start = ARGV[1]+0 ; stop = ARGV[2]+0 } 23 | 24 | if ( start < 2 ) start = 2 25 | if ( stop < start ) stop = start 26 | 27 | prime[ p_cnt = 1 ] = 3 # keep primes in prime[] 28 | 29 | # keep track of integer part of square root by adding 30 | # odd integers 31 | odd = test = 5 32 | root = 2 33 | squares = 9 34 | 35 | 36 | while ( test <= stop ) 37 | { 38 | if ( test >= squares ) 39 | { root++ 40 | odd += 2 41 | squares += odd 42 | } 43 | 44 | flag = 1 45 | for ( i = 1 ; prime[i] <= root ; i++ ) 46 | if ( test % prime[i] == 0 ) # not prime 47 | { flag = 0 ; break } 48 | 49 | if ( flag ) prime[ ++p_cnt ] = test 50 | 51 | test += 2 52 | } 53 | 54 | prime[0] = 2 55 | 56 | for( i = 0 ; prime[i] < start ; i++) ; 57 | 58 | for ( ; i <= p_cnt ; i++ ) print prime[i] 59 | 60 | } 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/qsort.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/mawk -f 2 | # $MawkId: qsort.awk,v 1.4 2020/09/19 14:20:45 tom Exp $ 3 | 4 | # qsort text files 5 | 6 | function middle(x,y,z) #return middle of 3 7 | { 8 | if ( x <= y ) 9 | { if ( z >= y ) return y 10 | if ( z < x ) return x 11 | return z 12 | } 13 | 14 | if ( z >= x ) return x 15 | if ( z < y ) return y 16 | return z 17 | } 18 | 19 | function isort(A , n, i, j, hold) 20 | { 21 | # if needed a sentinel at A[0] will be created 22 | 23 | for( i = 2 ; i <= n ; i++) 24 | { 25 | hold = A[ j = i ] 26 | while ( A[j-1] > hold ) 27 | { j-- ; A[j+1] = A[j] } 28 | 29 | A[j] = hold 30 | } 31 | } 32 | 33 | # recursive quicksort 34 | function qsort(A, left, right ,i , j, pivot, hold) 35 | { 36 | pivot = middle(A[left], A[int((left+right)/2)], A[right]) 37 | 38 | i = left 39 | j = right 40 | 41 | while ( i <= j ) 42 | { 43 | while ( A[i] < pivot ) i++ 44 | while ( A[j] > pivot ) j-- 45 | 46 | if ( i <= j ) 47 | { hold = A[i] 48 | A[i++] = A[j] 49 | A[j--] = hold 50 | } 51 | } 52 | 53 | if ( j - left > BLOCK ) qsort(A,left,j) 54 | if ( right - i > BLOCK ) qsort(A,i,right) 55 | } 56 | 57 | BEGIN { BLOCK = 5 } 58 | 59 | { line[NR] = $0 "" # sort as string 60 | } 61 | 62 | END { 63 | 64 | if ( NR > BLOCK ) qsort(line, 1, NR) 65 | 66 | isort(line, NR) 67 | 68 | for(ie = 1 ; ie <= NR ; ie++) print line[ie] 69 | } 70 | -------------------------------------------------------------------------------- /field.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | field.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991-1995,2014 Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: field.h,v 1.21 2024/11/15 01:59:53 tom Exp $ 15 | */ 16 | 17 | /* field.h */ 18 | 19 | #ifndef MAWK_FIELD_H 20 | #define MAWK_FIELD_H 1 21 | 22 | #include 23 | #include 24 | 25 | extern void set_field0(const char *, size_t); 26 | extern void split_field0(void); 27 | extern void field_assign(CELL *, CELL *); 28 | extern char *is_string_split(PTR, size_t *); 29 | extern void slow_cell_assign(CELL *, CELL *); 30 | extern CELL *slow_field_ptr(int); 31 | extern int field_addr_to_index(const CELL *); 32 | extern void set_binmode(long); 33 | 34 | #define NUM_PFIELDS 5 35 | extern CELL field[FBANK_SZ + NUM_PFIELDS]; 36 | /* $0, $1 ... $(FBANK_SZ-1), NF, RS, RS, CONVFMT, OFMT */ 37 | 38 | /* more fields if needed go here */ 39 | extern CELL **fbankv; /* fbankv[0] == field */ 40 | 41 | /* index to CELL * for a field */ 42 | #define field_ptr(i) ((i) < FBANK_SZ ? field + (i) : slow_field_ptr(i)) 43 | 44 | /* some, such as RS may be defined in system-headers */ 45 | #undef NF 46 | #undef RS 47 | #undef FS 48 | #undef CONVFMT 49 | #undef OFMT 50 | 51 | /* some compilers choke on (NF-field) in a case statement 52 | even though it's constant so ... 53 | */ 54 | #define NF_field FBANK_SZ 55 | #define RS_field (FBANK_SZ + 1) 56 | #define FS_field (FBANK_SZ + 2) 57 | #define CONVFMT_field (FBANK_SZ + 3) 58 | #define OFMT_field (FBANK_SZ + 4) 59 | 60 | /* the pseudo fields, assignment has side effects */ 61 | #define NF (field + NF_field) /* must be first */ 62 | #define RS (field + RS_field) 63 | #define FS (field + FS_field) 64 | #define CONVFMT (field + CONVFMT_field) 65 | #define OFMT (field + OFMT_field) /* must be last */ 66 | 67 | #define LAST_PFIELD OFMT 68 | 69 | extern int OFMT_type; /* PF_xxx type, for out-of-range print */ 70 | extern int nf; /* shadows NF */ 71 | 72 | /* a shadow type for RS and FS */ 73 | #define SEP_SPACE 0 74 | #define SEP_CHAR 1 75 | #define SEP_STR 2 76 | #define SEP_RE 3 77 | #define SEP_MLR 4 78 | 79 | typedef struct _separator 80 | #ifdef Visible_SEPARATOR 81 | { 82 | char type; 83 | char c; 84 | union { 85 | STRING *s_ptr; 86 | RE_NODE *r_ptr; 87 | } u; 88 | } 89 | #endif 90 | SEPARATOR; 91 | 92 | extern SEPARATOR rs_shadow; 93 | extern CELL fs_shadow; 94 | 95 | #endif /* MAWK_FIELD_H */ 96 | -------------------------------------------------------------------------------- /files.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | files.h 3 | copyright 2009-2020,2024, Thomas E. Dickey 4 | copyright 1991-1994,1996, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: files.h,v 1.16 2024/08/25 17:17:31 tom Exp $ 15 | */ 16 | 17 | #ifndef MAWK_FILES_H 18 | #define MAWK_FILES_H 19 | 20 | #include 21 | #include 22 | 23 | /* IO redirection types */ 24 | #define F_IN (-5) 25 | #define PIPE_IN (-4) 26 | #define PIPE_OUT (-3) 27 | #define F_APPEND (-2) 28 | #define F_TRUNC (-1) 29 | #define IS_OUTPUT(type) ((type)>=PIPE_OUT) 30 | 31 | extern const char *shell; /* for pipes and system() */ 32 | 33 | extern PTR file_find(STRING *, int); 34 | extern int file_close(STRING *); 35 | extern int file_flush(STRING *); 36 | extern int flush_all_output(void); 37 | extern PTR get_pipe(char *, int, int *); 38 | extern int wait_for(int); 39 | extern int wait_status(int); 40 | extern void close_out_pipes(void); 41 | 42 | #ifdef HAVE_FAKE_PIPES 43 | extern void close_fake_pipes(void); 44 | extern int close_fake_outpipe(char *, int); 45 | extern char *tmp_file_name(int, char *); 46 | #endif 47 | 48 | #ifdef MSDOS 49 | extern int DOSexec(char *); 50 | extern void enlarge_output_buffer(FILE *); 51 | #endif 52 | 53 | #if USE_BINMODE 54 | extern int binmode(void); 55 | extern void set_binmode(long); 56 | extern void stdout_init(void); 57 | #endif 58 | 59 | #endif /* MAWK_FILES_H */ 60 | -------------------------------------------------------------------------------- /fin.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | fin.h 3 | copyright 2009-2023,2024, Thomas E. Dickey 4 | copyright 1991-1992,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: fin.h,v 1.16 2024/08/25 17:11:16 tom Exp $ 15 | */ 16 | 17 | /* fin.h */ 18 | 19 | #ifndef FIN_H 20 | #define FIN_H 21 | 22 | #include 23 | 24 | /* structure to control input files */ 25 | 26 | typedef struct _fin 27 | #ifdef Visible_FIN 28 | { 29 | int fd; /* file-descriptor */ 30 | FILE *fp; /* NULL unless interactive */ 31 | char *buff; /* base of data read from file */ 32 | char *buffp; /* current position to read-next */ 33 | char *limit; /* points past the data in *buff */ 34 | size_t buff_size; /* allocated size of buff[] */ 35 | int flags; 36 | } 37 | #endif 38 | FIN; 39 | 40 | #define MAIN_FLAG 1 /* part of main input stream if on */ 41 | #define EOF_FLAG 2 42 | #define START_FLAG 4 /* used when RS == "" */ 43 | #define FIN_FLAG 8 /* set if fin->buff is no longer beginning */ 44 | 45 | extern FIN *FINdopen(int, int); 46 | extern FIN *FINopen(char *, int); 47 | extern void FINclose(FIN *); 48 | extern void FINsemi_close(FIN *); 49 | extern char *FINgets(FIN *, size_t *); 50 | extern size_t fillbuff(int, char *, size_t); 51 | extern void open_main(void); 52 | 53 | extern FIN *main_fin; /* for the main input stream */ 54 | 55 | #endif /* FIN_H */ 56 | -------------------------------------------------------------------------------- /fpe_check.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | fpe_check.c 3 | copyright 2008-2023,2024 Thomas E. Dickey 4 | copyright 1996, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* This code attempts to figure out what the default 14 | floating point exception handling does. 15 | */ 16 | 17 | /* 18 | * $MawkId: fpe_check.c,v 1.19 2024/11/17 22:11:48 tom Exp $ 19 | */ 20 | 21 | #include "confdefs.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef HAVE_SIGINFO_H 31 | #include 32 | #endif 33 | 34 | #ifdef HAVE_SIGACTION_SA_SIGACTION 35 | #define FPE_ARGS int sig, siginfo_t *sip, void *data 36 | #define FPE_DECL int why = sip->si_code 37 | #else 38 | #define FPE_ARGS int sig, int why 39 | #define FPE_DECL /* nothing */ 40 | #endif 41 | 42 | static void 43 | message(const char *s) 44 | { 45 | printf("\t%s\n", s); 46 | } 47 | 48 | jmp_buf jbuff; 49 | int may_be_safe_to_look_at_why = 0; 50 | int why_v; 51 | int checking_for_strtod_ovf_bug = 0; 52 | 53 | static void catch_FPEs(void); 54 | static int is_nan(double); 55 | static void check_strtod_ovf(void); 56 | 57 | static double 58 | div_by(double x, double y) 59 | { 60 | return x / y; 61 | } 62 | 63 | static double 64 | overflow(double x) 65 | { 66 | double y; 67 | 68 | do { 69 | y = x; 70 | x *= x; 71 | } while (y != x); 72 | return x; 73 | } 74 | 75 | static void 76 | check_fpe_traps(void) 77 | { 78 | int traps = 0; 79 | 80 | if (setjmp(jbuff) == 0) { 81 | div_by(44.0, 0.0); 82 | message("division by zero does not generate an exception"); 83 | } else { 84 | traps = 1; 85 | message("division by zero generates an exception"); 86 | catch_FPEs(); /* set again if sysV */ 87 | } 88 | 89 | if (setjmp(jbuff) == 0) { 90 | overflow(1000.0); 91 | message("overflow does not generate an exception"); 92 | } else { 93 | traps |= 2; 94 | message("overflow generates an exception"); 95 | catch_FPEs(); 96 | } 97 | 98 | if (traps == 0) { 99 | double maybe_nan; 100 | 101 | maybe_nan = sqrt(-8.0); 102 | if (is_nan(maybe_nan)) { 103 | message("math library supports ieee754"); 104 | } else { 105 | traps |= 4; 106 | message("math library does not support ieee754"); 107 | } 108 | } 109 | 110 | exit(traps); 111 | } 112 | 113 | static int 114 | is_nan(double d) 115 | { 116 | int result; 117 | char command[128]; 118 | 119 | #ifdef HAVE_ISNAN 120 | result = isnan(d); 121 | #else 122 | if (!(d == d)) { 123 | result = 1; 124 | } else { 125 | /* on some systems with an ieee754 bug, we need to make another check */ 126 | sprintf(command, 127 | "echo '%f' | egrep '[nN][aA][nN]|\\?' >/dev/null", d); 128 | result = system(command) == 0; 129 | } 130 | #endif 131 | return result; 132 | } 133 | 134 | /* 135 | Only get here if we think we have Berkeley type signals so we can 136 | look at a second argument to fpe_catch() to get the reason for 137 | an exception 138 | */ 139 | static void 140 | get_fpe_codes(void) 141 | { 142 | int divz = 0; 143 | int ovf = 0; 144 | 145 | may_be_safe_to_look_at_why = 1; 146 | 147 | if (setjmp(jbuff) == 0) 148 | div_by(1000.0, 0.0); 149 | else { 150 | divz = why_v; 151 | catch_FPEs(); 152 | } 153 | 154 | if (setjmp(jbuff) == 0) 155 | overflow(1000.0); 156 | else { 157 | ovf = why_v; 158 | catch_FPEs(); 159 | } 160 | 161 | /* make some guesses if sane values */ 162 | if (divz > 0 && ovf > 0 && divz != ovf) { 163 | printf("X FPE_ZERODIVIDE %d\n", divz); 164 | printf("X FPE_OVERFLOW %d\n", ovf); 165 | exit(0); 166 | } else 167 | exit(1); 168 | } 169 | 170 | int 171 | main(int argc, char *argv[]) 172 | { 173 | #ifdef HAVE_MATH__LIB_VERSION 174 | _LIB_VERSION = _IEEE_; 175 | #endif 176 | 177 | catch_FPEs(); 178 | switch (argc) { 179 | case 1: 180 | check_fpe_traps(); 181 | break; 182 | case 2: 183 | get_fpe_codes(); 184 | break; 185 | default: 186 | check_strtod_ovf(); 187 | break; 188 | } 189 | /* not reached */ 190 | return 0; 191 | } 192 | 193 | static RETSIGTYPE 194 | fpe_catch(FPE_ARGS) 195 | { 196 | FPE_DECL; 197 | 198 | if (checking_for_strtod_ovf_bug) 199 | exit(1); 200 | if (may_be_safe_to_look_at_why) 201 | why_v = why; 202 | longjmp(jbuff, 1); 203 | } 204 | 205 | static void 206 | catch_FPEs(void) 207 | { 208 | #if defined(HAVE_SIGACTION_SA_SIGACTION) 209 | { 210 | struct sigaction x; 211 | 212 | memset(&x, 0, sizeof(x)); 213 | x.sa_sigaction = fpe_catch; 214 | x.sa_flags = SA_SIGINFO; 215 | 216 | sigaction(SIGFPE, &x, (struct sigaction *) 0); 217 | } 218 | #else 219 | signal(SIGFPE, fpe_catch); 220 | #endif 221 | } 222 | 223 | char longstr[] = 224 | "1234567890\ 225 | 1234567890\ 226 | 1234567890\ 227 | 1234567890\ 228 | 1234567890\ 229 | 1234567890\ 230 | 1234567890\ 231 | 1234567890\ 232 | 1234567890\ 233 | 1234567890\ 234 | 1234567890\ 235 | 1234567890\ 236 | 1234567890\ 237 | 1234567890\ 238 | 1234567890\ 239 | 1234567890\ 240 | 1234567890\ 241 | 1234567890\ 242 | 1234567890\ 243 | 1234567890\ 244 | 1234567890\ 245 | 1234567890\ 246 | 1234567890\ 247 | 1234567890\ 248 | 1234567890\ 249 | 1234567890\ 250 | 1234567890\ 251 | 1234567890\ 252 | 1234567890\ 253 | 1234567890\ 254 | 1234567890\ 255 | 1234567890\ 256 | 1234567890\ 257 | 1234567890\ 258 | 1234567890\ 259 | 1234567890\ 260 | 1234567890\ 261 | 1234567890\ 262 | 1234567890\ 263 | 1234567890"; 264 | 265 | #ifdef USE_IEEEFP_H 266 | #include 267 | #endif 268 | 269 | static void 270 | check_strtod_ovf(void) 271 | { 272 | #ifdef USE_IEEEFP_H 273 | fpsetmask(fpgetmask() | FP_X_OFL | FP_X_DZ); 274 | #endif 275 | 276 | checking_for_strtod_ovf_bug = 1; 277 | strtod(longstr, (char **) 0); 278 | exit(0); 279 | } 280 | -------------------------------------------------------------------------------- /icons/mawk144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThomasDickey/mawk-snapshots/648b29253f5e5e4553fd2ef2dc95f5c19f30dea2/icons/mawk144.png -------------------------------------------------------------------------------- /icons/mawk48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThomasDickey/mawk-snapshots/648b29253f5e5e4553fd2ef2dc95f5c19f30dea2/icons/mawk48.png -------------------------------------------------------------------------------- /icons/mawk48.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | Mawk 20 | 22 | 29 | 30 | 49 | 51 | 52 | 54 | image/svg+xml 55 | 57 | Mawk 58 | August 31, 2012 59 | 60 | 61 | Thomas E. Dickey 62 | 63 | 64 | 66 | 67 | 69 | 71 | 73 | 75 | 77 | 79 | 80 | 81 | 82 | 88 | M 101 | 102 | 107 | AWK 119 | 120 | 121 | -------------------------------------------------------------------------------- /init.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | init.h 3 | copyright 2009-2020,2024, Thomas E. Dickey 4 | copyright 1991, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: init.h,v 1.9 2024/08/25 17:21:52 tom Exp $ 15 | */ 16 | 17 | /* init.h */ 18 | 19 | #ifndef INIT_H 20 | #define INIT_H 21 | 22 | #include 23 | 24 | /* nodes to link file names for multiple 25 | -f option */ 26 | 27 | typedef struct _pfile 28 | #ifdef Visible_PFILE 29 | { 30 | struct _pfile *link; 31 | char *fname; 32 | } 33 | #endif 34 | PFILE; 35 | 36 | extern PFILE *pfile_list; 37 | 38 | extern char *sprintf_buff, *sprintf_limit; 39 | 40 | void initialize(int, char **); 41 | void code_init(void); 42 | void code_cleanup(void); 43 | void compile_cleanup(void); 44 | void scan_init(const char *); 45 | void bi_vars_init(void); 46 | void bi_funct_init(void); 47 | void print_init(void); 48 | void kw_init(void); 49 | void field_init(void); 50 | void fpe_init(void); 51 | void load_environ(ARRAY); 52 | void set_stdio(void); 53 | 54 | GCC_NORETURN void print_version(FILE *fp); 55 | int is_cmdline_assign(char *); 56 | 57 | #endif /* INIT_H */ 58 | -------------------------------------------------------------------------------- /jmp.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | jmp.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: jmp.h,v 1.8 2024/08/25 17:15:43 tom Exp $ 15 | */ 16 | 17 | #ifndef MAWK_JMP_H 18 | #define MAWK_JMP_H 19 | 20 | #include 21 | #include 22 | 23 | void BC_new(void); 24 | void BC_insert(int, const INST *); 25 | void BC_clear(INST *, INST *); 26 | void code_push(INST *, unsigned, int, FBLOCK *); 27 | unsigned code_pop(INST *); 28 | void code_jmp(int, const INST *); 29 | void patch_jmp(const INST *); 30 | 31 | extern int code_move_level; 32 | /* used to as one part of unique identification of context when 33 | moving code. Global for communication with parser. 34 | */ 35 | 36 | #endif /* MAWK_JMP_H */ 37 | -------------------------------------------------------------------------------- /kw.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | kw.c 3 | copyright 2008-2023,2024, Thomas E. Dickey 4 | copyright 1991-1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: kw.c,v 1.11 2024/08/25 17:21:36 tom Exp $ 15 | */ 16 | 17 | #define Visible_SYMTAB 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | /* *INDENT-OFF* */ 24 | static const struct kw 25 | { 26 | const char text[12]; 27 | short kw; 28 | } 29 | keywords[] = 30 | { 31 | { "BEGIN", BEGIN }, 32 | { "END", END }, 33 | { "break", BREAK }, 34 | { "continue", CONTINUE }, 35 | { "delete", DELETE }, 36 | { "do", DO }, 37 | { "else", ELSE }, 38 | { "exit", EXIT }, 39 | { "for", FOR }, 40 | { "function", FUNCTION }, 41 | { "getline", GETLINE }, 42 | { "gsub", GSUB }, 43 | { "if", IF }, 44 | { "in", IN }, 45 | { "length", LENGTH }, 46 | { "match", MATCH_FUNC }, 47 | { "next", NEXT }, 48 | { "nextfile", NEXTFILE }, 49 | { "print", PRINT }, 50 | { "printf", PRINTF }, 51 | { "return", RETURN }, 52 | { "split", SPLIT }, 53 | { "sub", SUB }, 54 | { "while", WHILE }, 55 | { "", 0 } 56 | }; 57 | /* *INDENT-ON* */ 58 | 59 | /* put keywords in the symbol table */ 60 | void 61 | kw_init(void) 62 | { 63 | register const struct kw *p = keywords; 64 | 65 | while (p->text[0]) { 66 | register SYMTAB *q; 67 | 68 | q = insert(p->text); 69 | q->type = ST_KEYWORD; 70 | q->stval.kw = p++->kw; 71 | } 72 | } 73 | 74 | /* find a keyword to emit an error message */ 75 | const char * 76 | find_kw_str(int kw_token) 77 | { 78 | const struct kw *p; 79 | 80 | for (p = keywords; p->text[0]; p++) 81 | if (p->kw == kw_token) 82 | return p->text; 83 | /* search failed */ 84 | return (char *) 0; 85 | } 86 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | main.c 3 | copyright 2009-2017,2024, Thomas E. Dickey 4 | copyright 1991-1995,2014, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: main.c,v 1.35 2024/12/14 12:53:14 tom Exp $ 15 | */ 16 | 17 | #define Visible_CELL 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef LOCALE 26 | #include 27 | #endif 28 | 29 | short mawk_state; /* 0 is compiling */ 30 | int exit_code; 31 | 32 | #if defined(__GNUC__) && defined(_FORTIFY_SOURCE) 33 | int ignore_unused; 34 | #endif 35 | 36 | #ifdef LOCALE 37 | char decimal_dot; 38 | #endif 39 | 40 | int 41 | main(int argc, char **argv) 42 | { 43 | #ifdef LOCALE 44 | setlocale(LC_CTYPE, ""); 45 | setlocale(LC_NUMERIC, "C"); 46 | #endif 47 | initialize(argc, argv); 48 | #ifdef LOCALE 49 | { 50 | struct lconv *data; 51 | 52 | decimal_dot = '\0'; /* only set to nonzero if not POSIX '.' */ 53 | setlocale(LC_NUMERIC, ""); 54 | data = localeconv(); 55 | if (data != NULL 56 | && data->decimal_point != NULL 57 | && strlen(data->decimal_point) == 1) { 58 | decimal_dot = data->decimal_point[0]; 59 | } else { 60 | /* back out of this if we cannot handle it */ 61 | setlocale(LC_NUMERIC, "C"); 62 | } 63 | if (decimal_dot == '.') 64 | decimal_dot = 0; 65 | } 66 | #endif 67 | 68 | parse(); 69 | 70 | mawk_state = EXECUTION; 71 | execute(execution_start, NULL, NULL); 72 | /* never returns */ 73 | return 0; 74 | } 75 | 76 | void 77 | mawk_exit(int x) 78 | { 79 | TRACE(("mawk_exit(%d)\n", x)); 80 | #ifdef HAVE_REAL_PIPES 81 | close_out_pipes(); /* actually closes all output */ 82 | #else 83 | #ifdef HAVE_FAKE_PIPES 84 | close_fake_pipes(); 85 | #endif 86 | #endif 87 | 88 | #ifdef NO_LEAKS 89 | code_leaks(); 90 | scan_leaks(); 91 | cell_leaks(); 92 | re_leaks(); 93 | rexp_leaks(); 94 | bi_vars_leaks(); 95 | hash_leaks(); 96 | array_leaks(); 97 | files_leaks(); 98 | fin_leaks(); 99 | field_leaks(); 100 | zmalloc_leaks(); 101 | #if OPT_TRACE > 0 102 | trace_leaks(); 103 | #endif 104 | #endif 105 | 106 | exit(x); 107 | } 108 | -------------------------------------------------------------------------------- /makebits.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | makebits.c 3 | copyright 2024, Thomas E. Dickey 4 | 5 | This is a source file for mawk, an implementation of 6 | the AWK programming language. 7 | 8 | Mawk is distributed without warranty under the terms of 9 | the GNU General Public License, version 2, 1991. 10 | ********************************************/ 11 | 12 | /* 13 | * $MawkId: makebits.c,v 1.1 2024/11/17 20:33:16 tom Exp $ 14 | */ 15 | 16 | #include "config.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define my_name "_MAKEBITS_H" 23 | 24 | static int 25 | digits_of(double value) 26 | { 27 | int result = 0; 28 | while (value >= 1.0) { 29 | value /= 10.0; 30 | ++result; 31 | } 32 | return result; 33 | } 34 | 35 | static void 36 | header(void) 37 | { 38 | printf("/* this file was generated by makebits */\n"); 39 | printf("\n"); 40 | printf("#ifndef %s\n", my_name); 41 | printf("#define %s 1\n", my_name); 42 | } 43 | 44 | static void 45 | section(const char *msg) 46 | { 47 | printf("\n"); 48 | printf("/* %s */\n", msg); 49 | } 50 | 51 | static void 52 | footer(void) 53 | { 54 | printf("\n"); 55 | printf("#endif /* %s */\n", my_name); 56 | } 57 | 58 | int main(void) 59 | { 60 | double unsigned_limits; 61 | double integers_limits; 62 | int unsigned_digits; 63 | int integers_digits; 64 | int n; 65 | #ifdef HAVE_LONG_LONG 66 | union { 67 | double dd; 68 | unsigned long long ll; 69 | } samebits; 70 | unsigned len_significand; 71 | double max_significand; 72 | 73 | header(); 74 | 75 | section("significand size"); 76 | 77 | /* 78 | * Assume IEEE floating point, which means that "1.0" has all 0's to the 79 | * right of the exponent (which happens to be an odd number for "1.0"). 80 | * 81 | * The maximum number of bits in the significand should be 53 for 32-bit 82 | * and 64-bit double format, provided that we have long long. 83 | */ 84 | samebits.dd = 1.0; 85 | for (len_significand = 1; (samebits.ll & 1) == 0; ++len_significand) { 86 | samebits.ll /= 2; 87 | } 88 | printf("#define LEN_SIGNIFICAND %d\n", len_significand); 89 | 90 | /* 91 | * When converting to/from double, we are limited by the significand's 92 | * number of bits. 93 | */ 94 | max_significand = 1.0; 95 | for (n = 0; n < (int) len_significand; ++n) { 96 | max_significand *= 2.0; 97 | } 98 | printf("#define MAX_SIGNIFICAND %.30g\n", max_significand); 99 | #else 100 | header(); 101 | #endif 102 | 103 | section("limits for integer/floating conversion"); 104 | 105 | /* 106 | * For maximum precision, use integer arithmetic (e.g., 2^32 - 1 for 107 | * unsigned values), plus the special case of the first power-of-two value 108 | * past the integer range. 109 | */ 110 | unsigned_limits = 1.0; 111 | for (n = 0; n < (int) (CHAR_BIT * sizeof(double)); ++n) { 112 | unsigned_limits *= 2.0; 113 | } 114 | integers_limits = unsigned_limits / 2.0; 115 | 116 | printf("#define UNSIGNED_LIMITS %.30g.0\n", unsigned_limits); 117 | printf("#define INTEGERS_LIMITS %.30g.0\n", integers_limits); 118 | 119 | section("number of digits for integer/floating special case"); 120 | unsigned_digits = digits_of(unsigned_limits); 121 | integers_digits = digits_of(integers_limits); 122 | printf("#define UNSIGNED_DIGITS %d\n", unsigned_digits); 123 | printf("#define INTEGERS_DIGITS %d\n", integers_digits); 124 | 125 | section("format for integer/floating special case"); 126 | printf("#define UNSIGNED_FORMAT \"%%.%dg\"\n", unsigned_digits); 127 | printf("#define INTEGERS_FORMAT \"%%.%dg\"\n", integers_digits); 128 | 129 | footer(); 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /makedeps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $MawkId: makedeps.sh,v 1.4 2024/09/05 22:45:32 tom Exp $ 3 | ############################################################################### 4 | # copyright 2009-2023,2024 Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | if test ! -f config.h 13 | then 14 | echo "? config.h not found" 15 | exit 1 16 | fi 17 | 18 | if test ! -f mawk 19 | then 20 | echo "? mawk not found" 21 | exit 1 22 | fi 23 | 24 | cat >makedeps.awk <<'EOF' 25 | # vile:awkmode 26 | # regexp.c is a special case 27 | function AddDeps() { 28 | for (n = 1; n < NF; ++n) { 29 | name = $n; 30 | if ( name == ":" ) { 31 | ; 32 | } else { 33 | sub("[.]o$", ".c", name); 34 | deps[name] = 1; 35 | } 36 | } 37 | } 38 | BEGIN { count = 0; } 39 | EOF 40 | 41 | grep -E 'include.*\.c"' regexp.c | 42 | sed -e 's/^#[^"]*"/\/^/' \ 43 | -e 's/\.c/\\.o/' \ 44 | -e 's/"/\/ { AddDeps(); next; }/' \ 45 | >>makedeps.awk 46 | grep -E 'include.*\.c>' regexp.c | 47 | sed -e 's/^#[^<]*/\/ { AddDeps(); next; }/' \ 50 | >>makedeps.awk 51 | 52 | cat >>makedeps.awk <<'EOF' 53 | { print; } 54 | END { 55 | printf "regexp.o :"; 56 | for (name in deps) { 57 | printf " %s", name; 58 | } 59 | printf "\n"; 60 | } 61 | EOF 62 | 63 | WHINY_USERS=yes ./mawk -f examples/deps.awk *.c | mawk -f makedeps.awk 64 | -------------------------------------------------------------------------------- /makescan.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | makescan.c 3 | copyright 2009-2016,2024, Thomas E. Dickey 4 | copyright 1991, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: makescan.c,v 1.12 2024/08/25 17:17:31 tom Exp $ 15 | */ 16 | 17 | /* source for makescan.exe which builds the scancode[] 18 | via: makescan.exe > scancode.c 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | char scan_code[256]; 28 | 29 | static void 30 | scan_init(void) 31 | { 32 | register char *p; 33 | 34 | memset(scan_code, SC_UNEXPECTED, sizeof(scan_code)); 35 | for (p = &scan_code['0']; p <= &scan_code['9']; p++) 36 | *p = SC_DIGIT; 37 | scan_code[0] = 0; 38 | scan_code[' '] = scan_code['\t'] = scan_code['\f'] = SC_SPACE; 39 | scan_code['\r'] = scan_code['\013'] = SC_SPACE; 40 | 41 | scan_code[';'] = SC_SEMI_COLON; 42 | scan_code['\n'] = SC_NL; 43 | scan_code['{'] = SC_LBRACE; 44 | scan_code['}'] = SC_RBRACE; 45 | scan_code['+'] = SC_PLUS; 46 | scan_code['-'] = SC_MINUS; 47 | scan_code['*'] = SC_MUL; 48 | scan_code['/'] = SC_DIV; 49 | scan_code['%'] = SC_MOD; 50 | scan_code['^'] = SC_POW; 51 | scan_code['('] = SC_LPAREN; 52 | scan_code[')'] = SC_RPAREN; 53 | scan_code['_'] = SC_IDCHAR; 54 | scan_code['='] = SC_EQUAL; 55 | scan_code['#'] = SC_COMMENT; 56 | scan_code['\"'] = SC_DQUOTE; 57 | scan_code[','] = SC_COMMA; 58 | scan_code['!'] = SC_NOT; 59 | scan_code['<'] = SC_LT; 60 | scan_code['>'] = SC_GT; 61 | scan_code['|'] = SC_OR; 62 | scan_code['&'] = SC_AND; 63 | scan_code['?'] = SC_QMARK; 64 | scan_code[':'] = SC_COLON; 65 | scan_code['['] = SC_LBOX; 66 | scan_code[']'] = SC_RBOX; 67 | scan_code['\\'] = SC_ESCAPE; 68 | scan_code['.'] = SC_DOT; 69 | scan_code['~'] = SC_MATCH; 70 | scan_code['$'] = SC_DOLLAR; 71 | 72 | for (p = &scan_code['A']; p <= &scan_code['Z']; p++) 73 | p[0] = p['a' - 'A'] = SC_IDCHAR; 74 | 75 | } 76 | 77 | static void 78 | scan_print(void) 79 | { 80 | time_t now = time((time_t *) 0); 81 | register char *p = scan_code; 82 | register int c; /* column */ 83 | register int r; /* row */ 84 | 85 | printf("/*\n * %cMawkId%c\n * generated by makescan.c\n * date: %s */\n", 86 | '$', '$', ctime(&now)); 87 | printf("#include \"scancode.h\"\n"); 88 | printf("/* *INDENT-OFF* */\n"); 89 | printf("char scan_code[256] = {\n"); 90 | 91 | for (r = 1; r <= 16; r++) { 92 | for (c = 1; c <= 16; c++) { 93 | printf("%2d", *p++); 94 | if (r != 16 || c != 16) 95 | putchar(','); 96 | } 97 | putchar('\n'); 98 | } 99 | 100 | printf("} ;\n"); 101 | printf("/* *INDENT-ON* */\n"); 102 | } 103 | 104 | int 105 | main(void) 106 | { 107 | scan_init(); 108 | scan_print(); 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /man/Makefile.in: -------------------------------------------------------------------------------- 1 | # $MawkId: Makefile.in,v 1.7 2024/01/24 01:08:43 tom Exp $ 2 | ############################################################################### 3 | # copyright 2010-2023,2024 Thomas E. Dickey 4 | # 5 | # This is a source file for mawk, an implementation of 6 | # the AWK programming language. 7 | # 8 | # Mawk is distributed without warranty under the terms of 9 | # the GNU General Public License, version 2, 1991. 10 | ############################################################################### 11 | # produce alternate forms from mawk's documentation. 12 | 13 | SHELL=/bin/sh 14 | 15 | srcdir = @srcdir@ 16 | VPATH = @srcdir@ 17 | 18 | prefix = @prefix@ 19 | datarootdir = @datarootdir@ 20 | 21 | mandir = @mandir@ 22 | 23 | INSTALL = @INSTALL@ 24 | INSTALL_DATA = @INSTALL_DATA@ 25 | 26 | # these are overridden by top-level makefile 27 | PROGRAM = mawk 28 | TOPIC = 29 | SECTION = 1 30 | 31 | # what/where to put the man pages (do not override) 32 | MANDIR = $(DESTDIR)$(mandir) 33 | TARGET_DIR = $(MANDIR)/man$(SECTION) 34 | SOURCE_ROOT = mawk$(TOPIC) 35 | TARGET_ROOT = $(PROGRAM)$(TOPIC) 36 | SOURCE_FILE = $(SOURCE_ROOT).$(SECTION) 37 | TARGET_FILE = $(TARGET_ROOT).$(SECTION) 38 | 39 | .SUFFIXES : .html .$(SECTION) .man .ps .pdf .doc .txt 40 | 41 | .$(SECTION).html : 42 | ../man2html.tmp $* $(SECTION) man >$@ 43 | 44 | .$(SECTION).ps : 45 | $(SHELL) -c "tbl $*.$(SECTION) | groff -man" >$@ 46 | 47 | .$(SECTION).doc : 48 | GROFF_NO_SGR=stupid $(SHELL) -c "tbl $*.$(SECTION) | nroff -Tascii -man" >$@ 49 | 50 | .$(SECTION).txt : 51 | GROFF_NO_SGR=stupid $(SHELL) -c "tbl $*.$(SECTION) | nroff -Tascii -man | col -bx" >$@ 52 | 53 | .ps.pdf : 54 | ps2pdf $*.ps 55 | 56 | ALL = \ 57 | $(SOURCE_ROOT).html \ 58 | $(SOURCE_ROOT).pdf \ 59 | $(SOURCE_ROOT).ps 60 | 61 | all: $(SOURCE_ROOT).txt $(SOURCE_ROOT).doc $(ALL) 62 | 63 | install: $(TARGET_DIR) 64 | @echo "$@ing $(TARGET_DIR)/$(TARGET_FILE) manpage" 65 | @$(INSTALL_DATA) $(SOURCE_FILE) $(TARGET_DIR)/$(TARGET_FILE) 66 | 67 | uninstall: 68 | @echo "$@ing $(TARGET_DIR)/$(TARGET_FILE) manpage" 69 | @-rm -f $(TARGET_DIR)/$(TARGET_FILE) 70 | 71 | clean: 72 | -rm -f $(ALL) 73 | 74 | distclean: clean 75 | rm -f Makefile 76 | 77 | maintainer-clean: clean 78 | rm -f $(SOURCE_ROOT).txt $(SOURCE_ROOT).doc 79 | 80 | $(SOURCE_ROOT).pdf : $(SOURCE_ROOT).ps 81 | 82 | $(TARGET_DIR) : 83 | mkdir -p "$@" 84 | -------------------------------------------------------------------------------- /man/TODO: -------------------------------------------------------------------------------- 1 | -- $MawkId: TODO,v 1.8 2020/07/19 15:02:06 tom Exp $ 2 | mawk was implemented to conform with POSIX 1003.2-1992 3 | 4 | According to 5 | 6 | http://www.opengroup.org/austin/papers/posix_faq.html 7 | 8 | that was merged into POSIX-1003.1, and the latest relevant text of that is 9 | documented here: 10 | 11 | http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html 12 | 13 | The extended regular expressions are documented here: 14 | 15 | http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html 16 | 17 | Sections below refer to the awk.html sections. 18 | 19 | OPTIONS 20 | mawk complies here. 21 | 22 | OPERANDS 23 | mawk complies here. 24 | 25 | STDIN 26 | mawk complies here. 27 | 28 | INPUT FILES 29 | mawk complies here. 30 | 31 | ENVIRONMENT VARIABLES 32 | mawk ignores LC_COLLATE, LC_MESSAGES, LC_NUMERIC and NLSPATH 33 | 34 | mawk implements extensions 35 | 36 | MAWKBINMODE which gawk does as BINMODE 37 | 38 | MAWK_LONG_OPTIONS to ignore long options such as gawk's. Values 39 | are: error, warn, ignore (only the first character is checked). 40 | 41 | WHINY_USERS feature from gawk which makes iteration over array 42 | in sorted order. 43 | 44 | EXTENDED DESCRIPTION 45 | strings are converted to double using strtod(), which could be 46 | implemented using atof(). 47 | 48 | ENVIRON and CONVFMT are in the standard now, not extensions. 49 | 50 | >Expressions in awk 51 | mawk complies 52 | 53 | >Variables and Special Variables 54 | mawk complies 55 | 56 | >Regular Expressions 57 | mawk's built-in regular expressions supports brace expressions 58 | (used to denote minimum/maximum number of matches). 59 | 60 | mawk can be built with an external regular-expression library. 61 | However, POSIX regular expressions do not support matches of 62 | NUL-bytes. mawk's internal regular expressions support NULs. 63 | 64 | >Expression Patterns 65 | ok 66 | 67 | >Pattern Ranges 68 | ok 69 | 70 | >Actions 71 | delete is now part of POSIX-1003.1 72 | 73 | >Output Statements 74 | mawk does not use popen/pclose for opening/closing a pipe. 75 | 76 | >Arithmetic Functions 77 | ok 78 | 79 | >String Functions 80 | toupper and tolower are now part of POSIX-1003.1 81 | 82 | >Input/Output and General Functions 83 | ok 84 | 85 | >User-Defined Functions 86 | ok 87 | -------------------------------------------------------------------------------- /man/mawk-externs.dat: -------------------------------------------------------------------------------- 1 | # $MawkId: mawk-externs.dat,v 1.1 2020/08/03 19:44:42 tom Exp $ 2 | # manpages to exclude from man2html linking, for post-processing. 3 | atof(3) 4 | grep(1) 5 | sprintf(3) 6 | -------------------------------------------------------------------------------- /memory.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | memory.c 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991-1992,1993 Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: memory.c,v 1.10 2024/08/25 17:15:43 tom Exp $ 15 | */ 16 | 17 | #define Visible_STRING 18 | 19 | #include 20 | #include 21 | 22 | STRING null_str = 23 | {0, 1, ""}; 24 | 25 | static STRING * 26 | xnew_STRING(size_t len) 27 | { 28 | STRING *sval = (STRING *) zmalloc(len + STRING_OH); 29 | 30 | sval->len = len; 31 | sval->ref_cnt = 1; 32 | return sval; 33 | } 34 | 35 | /* allocate space for a STRING */ 36 | 37 | STRING * 38 | new_STRING0(size_t len) 39 | { 40 | if (len == 0) { 41 | null_str.ref_cnt++; 42 | return &null_str; 43 | } else { 44 | STRING *sval = xnew_STRING(len); 45 | sval->str[len] = 0; 46 | return sval; 47 | } 48 | } 49 | 50 | /* 51 | * Create a new string which may contain embedded nulls. 52 | */ 53 | STRING * 54 | new_STRING1(const char *s, size_t len) 55 | { 56 | if (len == 0) { 57 | null_str.ref_cnt++; 58 | return &null_str; 59 | } else { 60 | STRING *sval = xnew_STRING(len); 61 | memcpy(sval->str, s, len); 62 | sval->str[len] = 0; 63 | return sval; 64 | } 65 | } 66 | 67 | /* convert char* to STRING* */ 68 | 69 | STRING * 70 | new_STRING(const char *s) 71 | { 72 | 73 | if (s[0] == 0) { 74 | null_str.ref_cnt++; 75 | return &null_str; 76 | } else { 77 | STRING *sval = xnew_STRING(strlen(s)); 78 | strcpy(sval->str, s); 79 | return sval; 80 | } 81 | } 82 | 83 | #ifdef DEBUG 84 | 85 | void 86 | DB_free_STRING(STRING * sval) 87 | { 88 | if (--sval->ref_cnt == 0 && 89 | sval != &null_str) { 90 | zfree(sval, sval->len + STRING_OH); 91 | } 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /memory.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | memory.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: memory.h,v 1.11 2024/08/25 17:17:31 tom Exp $ 15 | */ 16 | 17 | /* memory.h */ 18 | 19 | #ifndef MAWK_MEMORY_H 20 | #define MAWK_MEMORY_H 21 | 22 | #include 23 | #include 24 | 25 | STRING *new_STRING(const char *); 26 | STRING *new_STRING0(size_t); 27 | STRING *new_STRING1(const char *, size_t); 28 | 29 | #ifdef DEBUG 30 | void DB_free_STRING(STRING *); 31 | 32 | #define free_STRING(s) DB_free_STRING(s) 33 | 34 | #else 35 | 36 | #define free_STRING(sval) \ 37 | do { \ 38 | if ( -- (sval)->ref_cnt == 0 && \ 39 | sval != &null_str ) \ 40 | zfree(sval, (sval)->len + STRING_OH) ; \ 41 | } while (0) 42 | #endif 43 | 44 | #endif /* MAWK_MEMORY_H */ 45 | -------------------------------------------------------------------------------- /msdos/dosexec.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | dosexec.c 3 | copyright 2009-2014,2023, Thomas E. Dickey 4 | copyright 1991-1994,1995, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: dosexec.c,v 1.6 2023/07/25 21:27:16 tom Exp $ 15 | */ 16 | 17 | /* system() and pipes() for MSDOS and Win32 console */ 18 | 19 | #include "mawk.h" 20 | 21 | #if defined(MSDOS) || defined(_WINNT) 22 | #include "memory.h" 23 | #include "files.h" 24 | #include "fin.h" 25 | 26 | #undef _POSIX_ 27 | 28 | #include 29 | 30 | #ifndef P_WAIT 31 | #define P_WAIT _P_WAIT /* works with VS2008 */ 32 | #endif 33 | 34 | static char *my_shell; /* e.g. "c:\\sys\\command.com" */ 35 | static char *command_opt; /* " /c" */ 36 | 37 | static void 38 | get_shell(void) 39 | { 40 | char *s, *p; 41 | int len; 42 | 43 | if ((s = getenv("MAWKSHELL")) != 0) { 44 | /* break into shell part and option part */ 45 | p = s; 46 | while (*p != ' ' && *p != '\t') 47 | p++; 48 | len = p - s; 49 | my_shell = (char *) zmalloc(len + 1); 50 | memcpy(my_shell, s, len); 51 | my_shell[len] = 0; 52 | command_opt = p; 53 | } else if ((s = getenv("COMSPEC")) != 0) { 54 | my_shell = s; 55 | command_opt = " /c"; 56 | /* leading space needed because of bug in command.com */ 57 | } else { 58 | errmsg(0, 59 | "cannot exec(), must set MAWKSHELL or COMSPEC in environment"); 60 | exit(2); 61 | } 62 | } 63 | 64 | int 65 | DOSexec(char *command) 66 | { 67 | char xbuff[256]; 68 | 69 | if (!my_shell) 70 | get_shell(); 71 | 72 | sprintf(xbuff, "%s %s", command_opt, command); 73 | 74 | fflush(stderr); 75 | fflush(stdout); 76 | 77 | return spawnl(P_WAIT, my_shell, my_shell, xbuff, (char *) 0); 78 | } 79 | 80 | static int next_tmp; /* index for naming temp files */ 81 | static char *tmpdir; /* directory to hold temp files */ 82 | static unsigned mawkid; /* unique to this mawk process */ 83 | 84 | /* compute the unique temp file name associated with id */ 85 | char * 86 | tmp_file_name(int id, 87 | char *buffer) 88 | { 89 | if (mawkid == 0) { 90 | /* first time */ 91 | union { 92 | void *ptr; 93 | unsigned w[2]; 94 | } xptr; 95 | 96 | memset(&xptr, 0, sizeof(xptr)); 97 | xptr.ptr = (void *) &mawkid; 98 | mawkid = xptr.w[1]; 99 | 100 | tmpdir = getenv("MAWKTMPDIR"); 101 | if (!tmpdir || strlen(tmpdir) > 80) 102 | tmpdir = ""; 103 | } 104 | 105 | (void) sprintf(buffer, "%sMAWK%04X.%03X", tmpdir, mawkid, id); 106 | return buffer; 107 | } 108 | 109 | /* open a pipe, returning a temp file identifier by 110 | reference 111 | */ 112 | 113 | PTR 114 | get_pipe(char *command, 115 | int type, int *tmp_idp) 116 | { 117 | PTR retval; 118 | char xbuff[256]; 119 | char *tmpname; 120 | 121 | *tmp_idp = next_tmp; 122 | tmpname = tmp_file_name(next_tmp, xbuff + 163); 123 | 124 | if (type == PIPE_OUT) { 125 | retval = (PTR) fopen(tmpname, (binmode() & 2) ? "wb" : "w"); 126 | } else { 127 | sprintf(xbuff, "%s > %s", command, tmpname); 128 | tmp_idp[1] = DOSexec(xbuff); 129 | retval = (PTR) FINopen(tmpname, 0); 130 | } 131 | 132 | next_tmp++; 133 | return retval; 134 | } 135 | 136 | /* closing a fake pipes involves running the out pipe 137 | command 138 | */ 139 | 140 | int 141 | close_fake_outpipe(char *command, 142 | int tid) /* identifies the temp file */ 143 | { 144 | char xbuff[256]; 145 | char *tmpname = tmp_file_name(tid, xbuff + 163); 146 | int retval; 147 | 148 | sprintf(xbuff, "%s < %s", command, tmpname); 149 | retval = DOSexec(xbuff); 150 | (void) unlink(tmpname); 151 | return retval; 152 | } 153 | 154 | #endif /* MSDOS */ 155 | -------------------------------------------------------------------------------- /msdos/examples/add_cr.awk: -------------------------------------------------------------------------------- 1 | 2 | # add_cr.awk 3 | # converts from Unix (LF only) text files to 4 | # DOS (CRLF) text files 5 | # 6 | # works on both unix and dos 7 | # if used on unix change COPY and DEL in BEGIN section 8 | # 9 | # mawk -f add_cr.awk [files] 10 | 11 | # with no files reads stdin writes stdout 12 | # otherwise the original is overwritten 13 | # 14 | # If a file of the form `@file', then arguments are read from 15 | # `file', one per line 16 | 17 | # 18 | # To add cr's to the whole distribution 19 | # 20 | # mawk -f doslist.awk packing.lis | mawk "{print $2}" > list 21 | # mawk -f add_cr.awk @list 22 | # 23 | 24 | 25 | # read arguments for @file into ARGV[] 26 | function reset_argv(T, i, j, flag, file) #all args local 27 | { 28 | for( i = 1 ; i < ARGC ; i++ ) 29 | { 30 | T[i] = ARGV[i] 31 | if ( T[i] ~ /^@/ ) flag = 1 32 | } 33 | 34 | if ( ! flag ) return 35 | 36 | # need to read from a @file into ARGV 37 | j = 1 38 | for( i = 1 ; i < ARGC ; i++ ) 39 | { 40 | if ( T[i] !~ /^@/ ) ARGV[j++] = T[i] 41 | else 42 | { 43 | T[i] = substr(T[i],2) 44 | # read arguments from T[i] 45 | while ( (getline file < T[i]) > 0 ) ARGV[j++] = file 46 | } 47 | } 48 | ARGC = j 49 | } 50 | 51 | 52 | BEGIN { 53 | COPY = "copy" # unix: "cp" 54 | DEL = "del" # unix: "rm" 55 | 56 | tmpfile = ENVIRON["MAWKTMPDIR"] "MAWK.TMP" 57 | 58 | reset_argv() 59 | } 60 | 61 | 62 | FILENAME == "-" { 63 | # just write to stdout 64 | printf "%s\r\n" , $0 65 | next 66 | } 67 | 68 | FILENAME != filename { 69 | 70 | if ( filename ) 71 | { 72 | close(tmpfile) 73 | syscmd = sprintf( "%s %s %s", COPY, tmpfile, filename ) 74 | system(syscmd) 75 | } 76 | 77 | filename = FILENAME 78 | } 79 | 80 | { printf "%s\r\n" , $0 > tmpfile } 81 | 82 | 83 | END { 84 | if ( filename ) 85 | { 86 | close(tmpfile) 87 | syscmd = sprintf( "%s %s %s", COPY, tmpfile, filename ) 88 | system(syscmd) 89 | system(DEL " " tmpfile) 90 | } 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /msdos/examples/doslist.awk: -------------------------------------------------------------------------------- 1 | 2 | # print truncated DOS file names 3 | # from packing.list (packing.lis) 4 | # 5 | # mawk -f doslist.awk packing.lis 6 | 7 | 8 | # discard blanks and comments 9 | /^#/ || /^[ \t]*$/ {next} 10 | 11 | 12 | function dos_name(s, n, front, X) 13 | { 14 | #lowercase, split on extension and truncate pieces 15 | s = tolower(s) 16 | n = split(s, X, ".") 17 | 18 | front = substr(X[1],1,8) 19 | 20 | if ( n == 1 ) return front 21 | else return front "." substr(X[2], 1, 3) 22 | } 23 | 24 | { 25 | n = split($1, X, "/") 26 | new = dos_name(X[1]) 27 | 28 | for( i = 2 ; i <= n ; i++ ) 29 | new = new "\\" dos_name(X[i]) 30 | 31 | printf "%-30s%s\n", $1, new 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /msdos/examples/objstat.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | # Sum up sizes of OBJ files in current directory 4 | # A clumsy script to count OBJs and sum up their sizes 5 | # run with 6 | # bmawk -fobjsize.awk workfile 7 | # or similar command syntax with your awk program 8 | # where workfile is a work file 9 | BEGIN { 10 | # redirection done by shelled command 11 | system("dir *.obj >" ARGV[1]) 12 | osize = 0 # size accumulator 13 | ocount = 0 # obj counter 14 | } 15 | # Now read workfile back, skipping lines that are not files 16 | $2 == "OBJ" { osize += $3 ; ocount++ } 17 | END { 18 | print ocount " OBJs, total size " osize " bytes" 19 | system("del "ARGV[1]) 20 | } 21 | -------------------------------------------------------------------------------- /msdos/examples/shell.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | # Test pipes under DOS. comment/uncomment print statements below 4 | BEGIN { 5 | # redirection done by shelled command 6 | system("dir *.* /b >pippo.") 7 | lcount = 0 8 | } 9 | { 10 | # print 11 | # Below is redirection done by mawk 12 | # print >"pippo2." 13 | print $0 | "sort" 14 | lcount++ 15 | } 16 | END { print "mawk NR line count=" NR " our line count=" lcount " lines in pippo"} 17 | -------------------------------------------------------------------------------- /msdos/examples/srcstat.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | # Sum up number, line count, and sizes of SOURCE files in current directory 4 | # run with 5 | # bmawk -fsrcsize.awk workfile 6 | # or similar command syntax with your awk program 7 | # where workfile is a work file 8 | BEGIN { 9 | # redirection done by shelled command 10 | # system("dir *.* >workfile") 11 | system("dir *.* >" ARGV[1]) 12 | ssize = 0 # size accumulator 13 | slines = 0 # line counter 14 | scount = 0 # obj counter 15 | } 16 | # Now read workfile back in 17 | $2 == "C" || $2 == "H" || $2 == "CPP" || $2 == "HPP" { 18 | filename = sprintf("%s.%s", $1, $2) 19 | ssize += $3 20 | while (getline < filename > 0) {slines++} 21 | scount++ 22 | } 23 | END { 24 | print scount " files, " slines " lines, total size " ssize " bytes" 25 | system("del " ARGV[1]) 26 | } 27 | -------------------------------------------------------------------------------- /msdos/examples/srcstat2.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | # Sum up number, line count, and sizes of SOURCE files in current directory 4 | # run with 5 | # bmawk -fsrcsize.awk workfile 6 | # or similar command syntax with your awk program 7 | # where workfile is a work file 8 | BEGIN { 9 | # redirection done by shelled command 10 | system("dir *.* >workfile") 11 | ssize = 0 # size accumulator 12 | slines = 0 # line counter 13 | scount = 0 # obj counter 14 | exit 15 | } 16 | END { 17 | # Now read workfile back in 18 | while (getline < "workfile" > 0) { 19 | if ($2 == "C" || $2 == "H" || $2 == "CPP" || $2 == "HPP") { 20 | filename = sprintf("%s.%s", $1, $2) 21 | ssize += $3 22 | while (getline < filename > 0) {slines++} 23 | scount++ 24 | } 25 | } 26 | print scount " files, " slines " lines, total size " ssize " bytes" 27 | system("del workfile") 28 | } 29 | -------------------------------------------------------------------------------- /msdos/examples/texttest.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | /^#include/ { 4 | # got #include, see if it has at least one quote. We don't want #include <> 5 | z = gsub(/"/, "", $2) 6 | while ((z > 0) && (getline x <$2 > 0)) 7 | # while (getline x <$2 > 0) 8 | print x 9 | next 10 | } 11 | { print } 12 | -------------------------------------------------------------------------------- /msdos/examples/winexe.awk: -------------------------------------------------------------------------------- 1 | # Ben Myers <0003571400@mcimail.com> 2 | 3 | # Sum up segment sizes of all Windows EXEs in current directory 4 | # requires DOS 5.0 and Borland TDUMP 5 | # run with 6 | # awk -fwinexe.awk work1 7 | # where work1 is a work file 8 | # You must have at least one filename as an arg, else awk will want to read 9 | # from con:, hence the requirement for work1 10 | BEGIN { 11 | # redirection done by shelled command 12 | system("del workfile.$%$") # Will probably cause a File Not Found message 13 | # Generate a list of EXEs 14 | system("dir *.exe /b > workfile.$%$") 15 | while (getline < "workfile.$%$" > 0) { 16 | # TDUMP keeps on piping to the workfile 17 | system("tdump " $1 ">> " ARGV[1]) 18 | } 19 | module_name = "" # initialize 20 | # Now read workfile back, processing lines that: 21 | # 1. contain EXE file name 22 | # 2. contain segment type 23 | # Print EXE name and stats for each segment type processed 24 | # When there is a new EXE name, print summary for EXE just processed 25 | j = 1 26 | while (getline < ARGV[1] > 0) { 27 | # module name 28 | if($1 == "Display" && $2 == "of" && $3 == "File") { 29 | # Print program summary for all but last program 30 | if(module_name != "") { Print_Summary() } 31 | otcount = 0 # text segment counter 32 | odcount = 0 # data segment counter 33 | otsize = 0 # text size accumulator 34 | odsize = 0 # data size accumulator 35 | module_name = $4 } 36 | # File Size 37 | if($1 == "DOS" && $2 == "File" && $3 == "Size") { 38 | # 6+ digit file size with leading left paren 39 | DOS_Size = substr($5,2,7) 40 | # file size < 6 digits 41 | if(DOS_Size == 0 || DOS_Size == "") { DOS_Size = $6 } 42 | } 43 | # CODE segment 44 | if($1 == "Segment" && $2 == "Type:" && $3 =="CODE") { 45 | decval = hexdec(substr($7,1,4)) 46 | otsize += decval 47 | # printf ("%12s CODE %4s %7u\n", module_name, $7, decval) 48 | otcount++ } 49 | # DATA segment 50 | if($1 == "Segment" && $2 == "Type:" && $3 =="DATA") { 51 | decval = hexdec(substr($7,1,4)) 52 | odsize += decval 53 | # printf ("%12s DATA %4s %7u\n", module_name, $7, decval) 54 | odcount++ } 55 | } # while 56 | } # end of BEGIN section 57 | # no main loop at all! 58 | END { 59 | # print record for last program 60 | Print_Summary() 61 | # delete work files 62 | system("del "ARGV[1]) 63 | system("del workfile.$%$") 64 | } # end of END section 65 | 66 | # No scanf in awk, so convert hex string x to decimal the hard way 67 | function hexdec (x) { 68 | result = 0 69 | for (i=1; i<=length(x); i++) { 70 | thechar = substr(x,i,1) 71 | # digits 0-9 and lower case hex produced by TDUMP 72 | # use brute force 73 | if (thechar == "0") {result = result*16} 74 | if (thechar == "1") {result = result*16 + 1} 75 | if (thechar == "2") {result = result*16 + 2} 76 | if (thechar == "3") {result = result*16 + 3} 77 | if (thechar == "4") {result = result*16 + 4} 78 | if (thechar == "5") {result = result*16 + 5} 79 | if (thechar == "6") {result = result*16 + 6} 80 | if (thechar == "7") {result = result*16 + 7} 81 | if (thechar == "8") {result = result*16 + 8} 82 | if (thechar == "9") {result = result*16 + 9} 83 | if (thechar == "a") {result = result*16 + 10} 84 | if (thechar == "b") {result = result*16 + 11} 85 | if (thechar == "c") {result = result*16 + 12} 86 | if (thechar == "d") {result = result*16 + 13} 87 | if (thechar == "e") {result = result*16 + 14} 88 | if (thechar == "f") {result = result*16 + 15} 89 | if (thechar == "A") {result = result*16 + 10} 90 | if (thechar == "B") {result = result*16 + 11} 91 | if (thechar == "C") {result = result*16 + 12} 92 | if (thechar == "D") {result = result*16 + 13} 93 | if (thechar == "E") {result = result*16 + 14} 94 | if (thechar == "F") {result = result*16 + 15} 95 | } # for (i=1;i 2 | 3 | # Sum up sizes of Windows OBJ files in current directory 4 | # requires DOS 5.0 and Borland TDUMP 5 | # A clumsy script to count Windows OBJs and sum up the CODE sizes 6 | # run with 7 | # awk -fwinobj.awk work1 8 | # where work1 is a work file 9 | # You must have at least one filename as an arg, else awk will want to read 10 | # from con:, hence the requirement for work1 11 | BEGIN { 12 | # redirection done by shelled command 13 | ocount = 0 # obj module counter 14 | otsize = 0 # text size accumulator 15 | odsize = 0 # data size accumulator 16 | system("del workfile.$%$") # Will probably cause a File Not Found message 17 | # Generate a list of OBJs 18 | system("dir *.obj /b >" ARGV[1]) 19 | while (getline < ARGV[1] > 0) { 20 | # TDUMP selects only the SEGDEFs to speed things up a lot 21 | # and keeps on piping to the workfile 22 | system("tdump " $1 " -oiSEGDEF >>workfile.$%$") 23 | ocount++ 24 | } 25 | # Now read workfile back, processing lines that are module ids and SEGDEF info 26 | # Print one line for each SEGDEF processed 27 | j = 1 28 | while (getline < "workfile.$%$" > 0) { 29 | # module name 30 | if($1 == "Display" && $2 == "of" && $3 == "File") { module_name = $4 } 31 | # SEGDEF CODE 32 | if($2 == "SEGDEF" && $9 =="'CODE'") { 33 | decval = hexdec($11) 34 | otsize += decval 35 | printf ("%12s CODE %4s %7i\n", module_name, $11, decval) 36 | j++ } 37 | # SEGDEF DATA 38 | if($2 == "SEGDEF" && $9 =="'DATA'") { 39 | decval = hexdec($11) 40 | odsize += decval 41 | printf ("%12s DATA %4s %7i\n", module_name, $11, decval) 42 | j++ } 43 | } # while 44 | } # end of BEGIN section 45 | # no main loop at all! 46 | END { 47 | # print summary and delete work files 48 | printf ("%i OBJ files\n", ocount) 49 | printf ("Total CODE size %04x %7li bytes\n", otsize, otsize) 50 | printf ("Total DATA size %04x %7li bytes\n", odsize, odsize) 51 | system("del "ARGV[1]) 52 | system("del workfile.$%$") 53 | } # end of END section 54 | 55 | # No scanf in awk, so convert hex string x to decimal the hard way 56 | function hexdec (x) { 57 | result = 0 58 | for (i=1; i<=length(x); i++) { 59 | thechar = substr(x,i,1) 60 | # digits 0-9 and lower case hex produced by TDUMP 61 | # use brute force 62 | if (thechar == "0") {result = result*16} 63 | if (thechar == "1") {result = result*16 + 1} 64 | if (thechar == "2") {result = result*16 + 2} 65 | if (thechar == "3") {result = result*16 + 3} 66 | if (thechar == "4") {result = result*16 + 4} 67 | if (thechar == "5") {result = result*16 + 5} 68 | if (thechar == "6") {result = result*16 + 6} 69 | if (thechar == "7") {result = result*16 + 7} 70 | if (thechar == "8") {result = result*16 + 8} 71 | if (thechar == "9") {result = result*16 + 9} 72 | if (thechar == "a") {result = result*16 + 10} 73 | if (thechar == "b") {result = result*16 + 11} 74 | if (thechar == "c") {result = result*16 + 12} 75 | if (thechar == "d") {result = result*16 + 13} 76 | if (thechar == "e") {result = result*16 + 14} 77 | if (thechar == "f") {result = result*16 + 15} 78 | } # for (i=1;i /* isatty() */ 45 | 46 | #endif /* CONFIG_H */ 47 | -------------------------------------------------------------------------------- /msdos/vs2008.mak: -------------------------------------------------------------------------------- 1 | # $MawkId: vs2008.mak,v 1.1 2014/09/14 22:30:35 tom Exp $ 2 | # Microsoft C makefile for mawk using Visual Studio 2008 and nmake. 3 | # 4 | ############################################################################### 5 | # copyright 2014 Thomas E. Dickey 6 | # 7 | # This is a source file for mawk, an implementation of 8 | # the AWK programming language. 9 | # 10 | # Mawk is distributed without warranty under the terms of 11 | # the GNU General Public License, version 2, 1991. 12 | ############################################################################### 13 | 14 | !include 15 | 16 | #======================================================================== 17 | 18 | CFLAGS = -I. -D_POSIX_ -DWINVER=0x501 -DLOCAL_REGEXP $(cflags) 19 | 20 | .c.obj: 21 | $(CC) $(CFLAGS) -c $< 22 | 23 | OBJ1 = parse.obj array.obj bi_funct.obj bi_vars.obj cast.obj code.obj \ 24 | da.obj error.obj execute.obj fcall.obj 25 | 26 | OBJ2 = field.obj files.obj fin.obj hash.obj jmp.obj init.obj \ 27 | kw.obj main.obj matherr.obj 28 | 29 | OBJ3 = memory.obj print.obj re_cmpl.obj scan.obj scancode.obj split.obj \ 30 | zmalloc.obj version.obj regexp.obj dosexec.obj 31 | 32 | MAWK_OBJ = $(OBJ1) $(OBJ2) $(OBJ3) 33 | 34 | mawk.exe : $(MAWK_OBJ) 35 | $(link) $(LDFLAGS) $(MAWK_OBJ) $(LIBS) -out:mawk.exe -map:mawk.map 36 | 37 | $(MAWK_OBJ) : config.h 38 | 39 | config.h : msdos/vs2008.h 40 | copy msdos\vs2008.h config.h 41 | 42 | dosexec.c : msdos/dosexec.c 43 | copy msdos\dosexec.c dosexec.c 44 | 45 | mawk_test : mawk.exe # test that we have a sane mawk 46 | @echo you may have to run the test manually 47 | cd test && mawktest.bat 48 | 49 | fpe_test : mawk.exe # test FPEs are handled OK 50 | @echo testing floating point exception handling 51 | @echo you may have to run the test manually 52 | cd test && fpe_test.bat 53 | 54 | check : mawk_test fpe_test 55 | 56 | ################################################### 57 | # FIXME 58 | # parse.c is provided 59 | # so you don't need to make it. 60 | # 61 | # But if you do: here's how: 62 | # To make it with byacc 63 | # YACC=byacc 64 | # parse.c : parse.y 65 | # $(YACC) -d parse.y 66 | # rename y_tab.h parse.h 67 | # rename y_tab.c parse.c 68 | ######################################## 69 | 70 | scancode.c : makescan.c scan.h 71 | $(CC) $(CFLAGS) makescan.c 72 | $(link) $(LDFLAGS) makescan.obj $(LIBS) -out:makescan.exe -map:makescan.map 73 | makescan.exe > scancode.c 74 | del makescan.exe 75 | 76 | clean : 77 | -del *.bak 78 | -del *.exe 79 | -del *.ilk 80 | -del *.map 81 | -del *.pdb 82 | -del *.obj 83 | 84 | distclean : clean 85 | -del dosexec.c 86 | -del scancode.c 87 | -del config.h 88 | 89 | # dependencies of .objs on .h 90 | array.o : symtype.h split.h sizes.h mawk.h config.h types.h nstd.h bi_vars.h zmalloc.h memory.h field.h 91 | bi_vars.o : symtype.h sizes.h mawk.h config.h types.h init.h nstd.h bi_vars.h zmalloc.h memory.h field.h 92 | cast.o : scancode.h parse.h symtype.h sizes.h mawk.h config.h types.h nstd.h repl.h zmalloc.h scan.h memory.h field.h 93 | code.o : scancode.h parse.h symtype.h sizes.h mawk.h config.h types.h init.h nstd.h repl.h jmp.h zmalloc.h scan.h code.h memory.h field.h 94 | da.o : symtype.h sizes.h mawk.h config.h types.h nstd.h repl.h zmalloc.h code.h bi_funct.h memory.h field.h 95 | execute.o : symtype.h sizes.h mawk.h config.h fin.h types.h regexp.h nstd.h repl.h bi_vars.h zmalloc.h code.h bi_funct.h files.h memory.h field.h 96 | fcall.o : symtype.h sizes.h mawk.h config.h types.h nstd.h zmalloc.h code.h memory.h 97 | field.o : scancode.h parse.h symtype.h split.h sizes.h mawk.h config.h types.h init.h regexp.h nstd.h repl.h bi_vars.h zmalloc.h scan.h memory.h field.h 98 | files.o : symtype.h sizes.h mawk.h config.h fin.h types.h init.h nstd.h zmalloc.h files.h memory.h 99 | fin.o : scancode.h parse.h symtype.h sizes.h mawk.h config.h types.h fin.h nstd.h bi_vars.h zmalloc.h scan.h memory.h field.h 100 | hash.o : symtype.h sizes.h mawk.h config.h types.h nstd.h bi_vars.h zmalloc.h memory.h 101 | jmp.o : symtype.h sizes.h mawk.h config.h types.h init.h nstd.h jmp.h zmalloc.h code.h memory.h 102 | kw.o : symtype.h parse.h sizes.h mawk.h config.h types.h init.h nstd.h 103 | main.o : symtype.h sizes.h mawk.h config.h types.h init.h nstd.h bi_vars.h zmalloc.h code.h files.h memory.h 104 | makescan.o : scancode.h nstd.h 105 | matherr.o : symtype.h sizes.h mawk.h config.h types.h init.h nstd.h 106 | memory.o : sizes.h mawk.h config.h types.h nstd.h zmalloc.h memory.h 107 | parse.o : symtype.h sizes.h mawk.h config.h types.h nstd.h bi_vars.h jmp.h zmalloc.h code.h bi_funct.h files.h memory.h field.h 108 | print.o : scancode.h symtype.h parse.h sizes.h mawk.h config.h types.h init.h nstd.h bi_vars.h zmalloc.h scan.h bi_funct.h files.h memory.h field.h 109 | re_cmpl.o : scancode.h parse.h symtype.h sizes.h mawk.h config.h types.h regexp.h nstd.h repl.h zmalloc.h scan.h memory.h 110 | regexp_system.o : regexp.h nstd.h 111 | rexp.o : sizes.h config.h types.h regexp.h rexp.h nstd.h 112 | rexp0.o : sizes.h config.h types.h rexp.h nstd.h 113 | rexp1.o : sizes.h config.h types.h rexp.h nstd.h 114 | rexp2.o : sizes.h config.h types.h rexp.h nstd.h 115 | rexp3.o : sizes.h config.h types.h rexp.h nstd.h 116 | rexp4.o : sizes.h mawk.h config.h types.h rexp.h nstd.h field.h 117 | rexpdb.o : sizes.h config.h types.h rexp.h nstd.h 118 | scan.o : scancode.h symtype.h parse.h sizes.h mawk.h config.h types.h fin.h init.h nstd.h repl.h zmalloc.h scan.h code.h files.h memory.h field.h 119 | scancode.o : scancode.h 120 | split.o : scancode.h parse.h symtype.h split.h sizes.h mawk.h config.h types.h regexp.h nstd.h repl.h bi_vars.h zmalloc.h scan.h bi_funct.h memory.h field.h 121 | version.o : symtype.h sizes.h mawk.h config.h types.h init.h nstd.h patchlev.h 122 | zmalloc.o : sizes.h mawk.h config.h types.h nstd.h zmalloc.h 123 | -------------------------------------------------------------------------------- /nstd.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | nstd.h 3 | copyright 2009-2017,2023 Thomas E. Dickey 4 | copyright 1995, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* Never Standard.h 14 | 15 | This has all the prototypes that are supposed to 16 | be in a standard place but never are, and when they are 17 | the standard place isn't standard 18 | */ 19 | 20 | /* 21 | * $MawkId: nstd.h,v 1.12 2023/07/22 22:27:11 tom Exp $ 22 | */ 23 | 24 | #ifndef NSTD_H 25 | #define NSTD_H 1 26 | 27 | #include 28 | 29 | /* types */ 30 | 31 | typedef void *PTR; 32 | 33 | #ifdef SIZE_T_STDDEF_H 34 | #include 35 | #else 36 | #ifdef SIZE_T_TYPES_H 37 | #include 38 | #else 39 | typedef unsigned size_t; 40 | #endif 41 | #endif 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | /* if have to diddle with errno to get errors from the math library */ 49 | #ifndef STDC_MATHERR 50 | #if (defined(FPE_TRAPS_ON) && !defined(HAVE_MATHERR)) 51 | #define STDC_MATHERR 1 52 | #else 53 | #define STDC_MATHERR 0 54 | #endif 55 | #endif 56 | 57 | #endif /* NSTD_H */ 58 | -------------------------------------------------------------------------------- /package/debian/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /package/debian/control: -------------------------------------------------------------------------------- 1 | Source: mawk-cur 2 | Maintainer: Thomas E. Dickey 3 | Section: interpreters 4 | Priority: optional 5 | Standards-Version: 4.6.0.1 6 | Build-Depends: debhelper (>= 12) 7 | Homepage: https://invisible-island.net/mawk/ 8 | 9 | Package: mawk-cur 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends} 12 | Description: pattern scanning and text processing language 13 | mawk is an interpreter for the AWK Programming Language. The AWK language is 14 | useful for manipulation of data files, text retrieval and processing, and for 15 | prototyping and experimenting with algorithms. 16 | -------------------------------------------------------------------------------- /package/debian/copyright: -------------------------------------------------------------------------------- 1 | Upstream source https://invisible-island.net/mawk/mawk.html 2 | 3 | Current maintainer: Thomas Dickey 4 | 5 | ------------------------------------------------------------------------------- 6 | 7 | mawk 1.3.4 and updates, 8 | Copyright: 2008-2024,2025 by Thomas E. Dickey 9 | mawk 1.3.4 includes substantial work by others: 10 | Copyright 2009-2010 by Jonathan Nieder 11 | Copyright 2005 by Aleksey Cheusov 12 | mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan 13 | 14 | Mawk is distributed without warranty under the terms of 15 | the GNU General Public License, version 2, 1991. 16 | 17 | ------------------------------------------------------------------------------- 18 | 19 | Files: aclocal.m4 20 | Licence: other-BSD 21 | Copyright: 2008-2024,2025 by Thomas E. Dickey 22 | Permission is hereby granted, free of charge, to any person obtaining a 23 | copy of this software and associated documentation files (the 24 | "Software"), to deal in the Software without restriction, including 25 | without limitation the rights to use, copy, modify, merge, publish, 26 | distribute, distribute with modifications, sublicense, and/or sell 27 | copies of the Software, and to permit persons to whom the Software is 28 | furnished to do so, subject to the following conditions: 29 | 30 | The above copyright notice and this permission notice shall be included 31 | in all copies or portions of the Software. 32 | 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 34 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 35 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 36 | IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 37 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 38 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 39 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. 40 | 41 | Except as contained in this notice, the name(s) of the above copyright 42 | holders shall not be used in advertising or otherwise to promote the 43 | sale, use or other dealings in this Software without prior written 44 | authorization. 45 | 46 | Files: install-sh 47 | Copyright: 1994 X Consortium 48 | Licence: other-BSD 49 | Permission is hereby granted, free of charge, to any person obtaining a copy 50 | of this software and associated documentation files (the "Software"), to 51 | deal in the Software without restriction, including without limitation the 52 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 53 | sell copies of the Software, and to permit persons to whom the Software is 54 | furnished to do so, subject to the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be included in 57 | all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 60 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 61 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 62 | X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 63 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 64 | TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 65 | 66 | Except as contained in this notice, the name of the X Consortium shall not 67 | be used in advertising or otherwise to promote the sale, use or other deal- 68 | ings in this Software without prior written authorization from the X Consor- 69 | tium. 70 | 71 | FSF changes to this file are in the public domain. 72 | 73 | Calling this script install-sh is preferred over install.sh, to prevent 74 | `make' implicit rules from creating a file called install from it 75 | when there is no Makefile. 76 | 77 | This script is compatible with the BSD install script, but was written 78 | from scratch. It can only install one file at a time, a restriction 79 | shared with many OS's install programs. 80 | 81 | Files: debian/* 82 | Copyright: 2012-2024,2025 Thomas E. Dickey 83 | Licence: other-BSD 84 | Permission to use, copy, modify, and distribute this software and its 85 | documentation for any purpose and without fee is hereby granted, 86 | provided that the above copyright notice appear in all copies and that 87 | both that copyright notice and this permission notice appear in 88 | supporting documentation, and that the name of the above listed 89 | copyright holder(s) not be used in advertising or publicity pertaining 90 | to distribution of the software without specific, written prior 91 | permission. 92 | 93 | THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD 94 | TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 95 | AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE 96 | LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 97 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 98 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 99 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 100 | 101 | On Debian systems, the complete text of the GNU General 102 | Public License can be found in '/usr/share/common-licenses/GPL-2' 103 | -------------------------------------------------------------------------------- /package/debian/docs: -------------------------------------------------------------------------------- 1 | ACKNOWLEDGMENT 2 | -------------------------------------------------------------------------------- /package/debian/postinst: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | echo "** postinst script for mawk: $*" 3 | 4 | set -e 5 | 6 | PRI=50 7 | ALT=mawk 8 | PKG=mawk-cur 9 | 10 | BINDIR=/usr/bin 11 | MANDIR=/usr/share/man/man1 12 | 13 | if [ $1 != "upgrade" ] 14 | then 15 | update-alternatives \ 16 | --force \ 17 | --install \ 18 | $BINDIR/$ALT $ALT \ 19 | $BINDIR/$PKG $PRI \ 20 | --slave $MANDIR/$ALT.1.gz $ALT.1.gz \ 21 | $MANDIR/$PKG.1.gz 22 | fi 23 | 24 | #DEBHELPER# 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /package/debian/postrm: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | echo "** postrm script for mawk: $*" 3 | 4 | set -e 5 | 6 | ALT=mawk 7 | PKG=mawk-base 8 | 9 | ETCDIR=/etc/alternatives 10 | BINDIR=/usr/bin 11 | MANDIR=/usr/share/man/man1 12 | 13 | if [ "x$1" = "xremove" ] 14 | then 15 | # update-alternatives --config mawk 16 | if [ -f $BINDIR/$PKG ] 17 | then 18 | rm -fv $ETCDIR/$ALT 19 | rm -fv $BINDIR/$ALT 20 | mv -fv $BINDIR/$PKG $BINDIR/$ALT 21 | fi 22 | 23 | if [ -f $MANDIR/$PKG.1.gz ] 24 | then 25 | rm -fv $ETCDIR/$ALT.1.gz 26 | rm -fv $MANDIR/$ALT.1.gz 27 | mv -fv $MANDIR/$PKG.1.gz $MANDIR/$ALT.1.gz 28 | fi 29 | fi 30 | 31 | #DEBHELPER# 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /package/debian/preinst: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | echo "** preinst script for mawk: $*" 3 | 4 | set -e 5 | 6 | PRI=10 7 | ALT=mawk 8 | PKG=mawk-base 9 | 10 | BINDIR=/usr/bin 11 | MANDIR=/usr/share/man/man1 12 | 13 | if [ ! -f /usr/bin/mawk-base ] 14 | then 15 | mv -fv $BINDIR/$ALT $BINDIR/$PKG 16 | mv -fv $MANDIR/$ALT.1.gz $MANDIR/$PKG.1.gz 17 | fi 18 | 19 | update-alternatives \ 20 | --force \ 21 | --install \ 22 | $BINDIR/$ALT $ALT \ 23 | $BINDIR/$PKG $PRI \ 24 | --slave $MANDIR/$ALT.1.gz $ALT.1.gz \ 25 | $MANDIR/$PKG.1.gz 26 | 27 | 28 | #DEBHELPER# 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /package/debian/prerm: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | echo "** prerm script for mawk: $*" 3 | 4 | set -e 5 | 6 | if [ "x$1" != "xupgrade" ]; then 7 | update-alternatives --remove mawk /usr/bin/mawk-cur 8 | fi 9 | 10 | #DEBHELPER# 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /package/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # MAde with the aid of dh_make, by Craig Small 3 | # Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. 4 | # Some lines taken from debmake, by Cristoph Lameter. 5 | 6 | # Uncomment this to turn on verbose mode. 7 | #export DH_VERBOSE=1 8 | 9 | # These are used for cross-compiling and for saving the configure script 10 | # from having to guess our platform (since we know it already) 11 | DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) 12 | DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) 13 | 14 | CFLAGS = $(shell dpkg-buildflags --get CFLAGS) 15 | CXXFLAGS = $(shell dpkg-buildflags --get CXXFLAGS) 16 | CPPFLAGS = $(shell dpkg-buildflags --get CPPFLAGS) 17 | LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS) 18 | 19 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) 20 | CFLAGS += -O0 21 | else 22 | CFLAGS += -O2 23 | endif 24 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) 25 | INSTALL_PROGRAM += -s 26 | endif 27 | 28 | 29 | configure: configure-stamp 30 | configure-stamp: 31 | dh_testdir 32 | 33 | CFLAGS="$(CFLAGS)" \ 34 | CPPFLAGS="$(CPPFLAGS) -DLCOV_UNUSED" \ 35 | LDFLAGS="$(LDFLAGS)" ./configure \ 36 | --host=$(DEB_HOST_GNU_TYPE) \ 37 | --build=$(DEB_BUILD_GNU_TYPE) \ 38 | --program-suffix=-cur \ 39 | --prefix=/usr \ 40 | --mandir=\$${prefix}/share/man \ 41 | --sysconfdir=/etc 42 | 43 | touch configure-stamp 44 | 45 | build: build-stamp 46 | build-stamp: configure-stamp 47 | dh_testdir 48 | 49 | $(MAKE) 50 | 51 | touch build-stamp 52 | 53 | clean: 54 | dh_testdir 55 | dh_testroot 56 | 57 | [ ! -f Makefile ] || $(MAKE) clean 58 | 59 | rm -f configure-stamp build-stamp install-stamp \ 60 | config.cache config.h config.status config.log makefile 61 | 62 | rm -f *.o mawk 63 | 64 | dh_clean 65 | 66 | install: install-stamp 67 | install-stamp: build-stamp 68 | dh_testdir 69 | dh_testroot 70 | dh_prep 71 | dh_installdirs 72 | 73 | $(MAKE) install DESTDIR=$(CURDIR)/debian/mawk-cur 74 | 75 | touch install-stamp 76 | 77 | # Build architecture-independent files here. 78 | binary-indep: build install 79 | # No binary-indep target. 80 | 81 | # Build architecture-dependent files here. 82 | binary-arch: build install 83 | dh_testdir 84 | dh_testroot 85 | dh_installdocs 86 | dh_installexamples 87 | dh_installchangelogs CHANGES 88 | dh_strip 89 | dh_compress 90 | dh_fixperms 91 | dh_installdeb 92 | dh_shlibdeps 93 | dh_gencontrol 94 | dh_md5sums 95 | dh_builddeb 96 | 97 | binary: binary-indep binary-arch 98 | .PHONY: build clean binary-indep binary-arch binary install install-stamp 99 | -------------------------------------------------------------------------------- /package/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /package/debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | 3 | opts=passive https://invisible-island.net/archives/mawk/mawk-(\d.\d.\d)-(\d+)\.tgz \ 4 | debian uupdate 5 | -------------------------------------------------------------------------------- /package/freebsd/Makefile: -------------------------------------------------------------------------------- 1 | # Created by: Pedro F. Giffuni 2 | # $FreeBSD: head/lang/mawk/Makefile 516890 2019-11-06 14:17:48Z wen $ 3 | 4 | PORTNAME= mawk 5 | DISTVERSION= 1.3.4.20250131 6 | CATEGORIES= lang 7 | MASTER_SITES= https://invisible-island.net/archives/${PORTNAME}/ \ 8 | https://invisible-mirror.net/archives/${PORTNAME}/ 9 | 10 | MAINTAINER= wen@FreeBSD.org 11 | COMMENT= Interpreter for the AWK Programming Language 12 | 13 | LICENSE= GPLv2 14 | 15 | GNU_CONFIGURE= yes 16 | USES= tar:tgz 17 | 18 | PLIST_FILES= bin/mawk \ 19 | man/man1/mawk.1.gz 20 | 21 | .include 22 | -------------------------------------------------------------------------------- /package/freebsd/distinfo: -------------------------------------------------------------------------------- 1 | TIMESTAMP = 1573049632 2 | SHA256 (mawk-1.3.4-20190203.tgz) = daacb314029185bbef86b0df5627ad8591378d420fc32236f99f15a9a8a6b840 3 | SIZE (mawk-1.3.4-20190203.tgz) = 466481 4 | -------------------------------------------------------------------------------- /package/freebsd/pkg-descr: -------------------------------------------------------------------------------- 1 | mawk is an interpreter for the AWK Programming Language. The AWK language is 2 | useful for manipulation of data files, text retrieval and processing, and for 3 | prototyping and experimenting with algorithms. mawk is a new awk meaning it 4 | implements the AWK language as defined in Aho, Kernighan and Weinberger, The 5 | AWK Programming Language, Addison-Wesley Publishing, 1988 (hereafter referred 6 | to as the AWK book.) mawk conforms to the Posix 1003.2 (draft 11.3) definition 7 | of the AWK language which contains a few features not described in the AWK 8 | book, and mawk provides a small number of extensions. 9 | 10 | WWW: https://invisible-island.net/mawk/ 11 | -------------------------------------------------------------------------------- /package/mawk.spec: -------------------------------------------------------------------------------- 1 | Summary: mawk - pattern scanning and text processing language 2 | %global AppProgram mawk 3 | %global AppVersion 1.3.4 4 | %global AppPatched 20250131 5 | %global MySite https://invisible-island.net 6 | # $MawkId: mawk.spec,v 1.140 2025/01/31 22:21:11 tom Exp $ 7 | Name: %{AppProgram} 8 | Version: %{AppVersion} 9 | Release: %{AppPatched} 10 | License: GPLv2 11 | Group: Applications/Development 12 | URL: %{MySite}/%{AppProgram} 13 | Source0: %{MySite}/archives/%{AppProgram}-%{AppVersion}-%{AppPatched}.tgz 14 | Packager: Thomas Dickey 15 | 16 | %description 17 | mawk is an interpreter for the AWK Programming Language. The AWK language is 18 | useful for manipulation of data files, text retrieval and processing, and for 19 | prototyping and experimenting with algorithms. 20 | 21 | %prep 22 | 23 | %define debug_package %{nil} 24 | %setup -q -n %{AppProgram}-%{AppVersion}-%{AppPatched} 25 | 26 | %build 27 | 28 | INSTALL_PROGRAM='${INSTALL}' \ 29 | %configure \ 30 | --target %{_target_platform} \ 31 | --prefix=%{_prefix} \ 32 | --bindir=%{_bindir} \ 33 | --libdir=%{_libdir} \ 34 | --mandir=%{_mandir} 35 | 36 | make 37 | 38 | %install 39 | [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT 40 | 41 | make install DESTDIR=$RPM_BUILD_ROOT 42 | 43 | strip $RPM_BUILD_ROOT%{_bindir}/%{AppProgram} 44 | 45 | %clean 46 | [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT 47 | 48 | %files 49 | %defattr(-,root,root) 50 | %{_prefix}/bin/%{AppProgram} 51 | %{_mandir}/man1/%{AppProgram}.* 52 | %{_mandir}/man7/%{AppProgram}-*.* 53 | 54 | %changelog 55 | # each patch should add its ChangeLog entries here 56 | 57 | * Wed Aug 02 2023 Thomas Dickey 58 | - add man7-pages for array/code 59 | 60 | * Thu Dec 29 2022 Thomas Dickey 61 | - update URLs 62 | 63 | * Mon Jan 06 2020 Thomas Dickey 64 | - use hardening flags 65 | 66 | * Sat Oct 27 2012 Thomas Dickey 67 | - cancel any debug-rpm 68 | 69 | * Sun Jun 20 2010 Thomas Dickey 70 | - initial version 71 | -------------------------------------------------------------------------------- /parse.h: -------------------------------------------------------------------------------- 1 | #ifndef _yy_defines_h_ 2 | #define _yy_defines_h_ 3 | 4 | #define UNEXPECTED 257 5 | #define BAD_DECIMAL 258 6 | #define NL 259 7 | #define SEMI_COLON 260 8 | #define LBRACE 261 9 | #define RBRACE 262 10 | #define LBOX 263 11 | #define RBOX 264 12 | #define COMMA 265 13 | #define IO_OUT 266 14 | #define ASSIGN 267 15 | #define ADD_ASG 268 16 | #define SUB_ASG 269 17 | #define MUL_ASG 270 18 | #define DIV_ASG 271 19 | #define MOD_ASG 272 20 | #define POW_ASG 273 21 | #define QMARK 274 22 | #define COLON 275 23 | #define OR 276 24 | #define AND 277 25 | #define IN 278 26 | #define MATCH 279 27 | #define EQ 280 28 | #define NEQ 281 29 | #define LT 282 30 | #define LTE 283 31 | #define GT 284 32 | #define GTE 285 33 | #define CAT 286 34 | #define GETLINE 287 35 | #define PLUS 288 36 | #define MINUS 289 37 | #define MUL 290 38 | #define DIV 291 39 | #define MOD 292 40 | #define NOT 293 41 | #define UMINUS 294 42 | #define IO_IN 295 43 | #define PIPE 296 44 | #define POW 297 45 | #define INC_or_DEC 298 46 | #define DOLLAR 299 47 | #define FIELD 300 48 | #define LPAREN 301 49 | #define RPAREN 302 50 | #define DOUBLE 303 51 | #define STRING_ 304 52 | #define RE 305 53 | #define ID 306 54 | #define D_ID 307 55 | #define FUNCT_ID 308 56 | #define BUILTIN 309 57 | #define LENGTH 310 58 | #define PRINT 311 59 | #define PRINTF 312 60 | #define SPLIT 313 61 | #define MATCH_FUNC 314 62 | #define SUB 315 63 | #define GSUB 316 64 | #define DO 317 65 | #define WHILE 318 66 | #define FOR 319 67 | #define BREAK 320 68 | #define CONTINUE 321 69 | #define IF 322 70 | #define ELSE 323 71 | #define DELETE 324 72 | #define BEGIN 325 73 | #define END 326 74 | #define EXIT 327 75 | #define NEXT 328 76 | #define NEXTFILE 329 77 | #define RETURN 330 78 | #define FUNCTION 331 79 | #ifdef YYSTYPE 80 | #undef YYSTYPE_IS_DECLARED 81 | #define YYSTYPE_IS_DECLARED 1 82 | #endif 83 | #ifndef YYSTYPE_IS_DECLARED 84 | #define YYSTYPE_IS_DECLARED 1 85 | typedef union YYSTYPE{ 86 | CELL *cp ; 87 | SYMTAB *stp ; 88 | int start ; /* code starting address as offset from code_base */ 89 | PF_CP fp ; /* ptr to a (print/printf) or (sub/gsub) function */ 90 | const BI_REC *bip ; /* ptr to info about a builtin */ 91 | FBLOCK *fbp ; /* ptr to a function block */ 92 | ARG2_REC *arg2p ; 93 | CA_REC *ca_p ; 94 | int ival ; 95 | PTR ptr ; 96 | } YYSTYPE; 97 | #endif /* !YYSTYPE_IS_DECLARED */ 98 | extern YYSTYPE yylval; 99 | 100 | #endif /* _yy_defines_h_ */ 101 | -------------------------------------------------------------------------------- /patchlev.h: -------------------------------------------------------------------------------- 1 | /* 2 | patchlev.h 3 | copyright 2009-2024,2025, Thomas E. Dickey 4 | copyright 1991-1996,2014, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | */ 12 | 13 | /* 14 | * $MawkId: patchlev.h,v 1.168 2025/01/31 22:21:11 tom Exp $ 15 | */ 16 | #define PATCH_BASE 1 17 | #define PATCH_LEVEL 3 18 | #define PATCH_STRING ".4" 19 | #define DATE_STRING "20250131" 20 | -------------------------------------------------------------------------------- /regexp.c: -------------------------------------------------------------------------------- 1 | /* 2 | regexp_system.c 3 | copyright 2009-2020,2024, Thomas E. Dickey 4 | copyright 2005, Aleksey Cheusov 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | */ 12 | 13 | /* $MawkId: regexp.c,v 1.17 2024/12/31 15:13:35 tom Exp $ */ 14 | 15 | #include 16 | 17 | #define Visible_CELL 18 | 19 | #ifdef LOCAL_REGEXP 20 | #define REGEXP_INTERNALS 21 | #define Visible_MACHINE 22 | #define Visible_RE_DATA 23 | #define Visible_RT_POS_ENTRY 24 | #define Visible_RT_STATE 25 | #define Visible_STATE 26 | # include 27 | 28 | #define RE_FILL() do { TRACE2((rt_form "refill...\n", rt_args)); goto refill; } while (0) 29 | #define RE_CASE() do { goto reswitch; } while (0) 30 | 31 | #define rt_form "[%s@%d] %d:%03d " 32 | #define rt_args __FILE__, __LINE__, \ 33 | (int)(run_entry - RE_run_stack_base), \ 34 | (int)(m - machine) 35 | 36 | #define TR_AT(what) \ 37 | TRACE2((rt_form "%s\n", rt_args, what)) 38 | 39 | # include 40 | # include 41 | # include 42 | # include 43 | # include 44 | # include 45 | #else 46 | #define Visible_RE_DATA 47 | #define Visible_RE_NODE 48 | #define Visible_STRING 49 | # include 50 | # include 51 | #endif 52 | 53 | #ifdef NO_LEAKS 54 | void 55 | rexp_leaks(void) 56 | { 57 | TRACE(("rexp_leaks\n")); 58 | #ifdef LOCAL_REGEXP 59 | lookup_cclass(0); 60 | if (bv_base) { 61 | BV **p = bv_base; 62 | while (p != bv_next) { 63 | RE_free(*p); 64 | ++p; 65 | } 66 | RE_free(bv_base); 67 | bv_base = 0; 68 | bv_limit = 0; 69 | bv_next = 0; 70 | } 71 | if (RE_run_stack_base) { 72 | RE_free(RE_run_stack_base); 73 | RE_run_stack_base = 0; 74 | } 75 | if (RE_pos_stack_base) { 76 | RE_free(RE_pos_stack_base); 77 | RE_pos_stack_base = 0; 78 | } 79 | #endif 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /regexp.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | regexp.h 3 | copyright 2009-2020,2024, Thomas E. Dickey 4 | copyright 2005, Aleksey Cheusov 5 | copyright 1991,1993, Michael D. Brennan 6 | 7 | This is a source file for mawk, an implementation of 8 | the AWK programming language. 9 | 10 | Mawk is distributed without warranty under the terms of 11 | the GNU General Public License, version 2, 1991. 12 | ********************************************/ 13 | 14 | /* 15 | * $MawkId: regexp.h,v 1.17 2024/08/25 17:15:43 tom Exp $ 16 | */ 17 | #ifndef MAWK_REPL_H 18 | #define MAWK_REPL_H 19 | 20 | #include 21 | #include 22 | 23 | const char *REerror(void); 24 | 25 | #ifdef LOCAL_REGEXP 26 | #include 27 | STATE *REcompile(char *, size_t); 28 | void REdestroy(STATE *); 29 | int REtest(char *, size_t, STATE *); 30 | char *REmatch(char *, size_t, STATE *, size_t *, int); 31 | void REmprint(STATE *, FILE *); 32 | #else 33 | PTR REcompile(char *, size_t); 34 | void REdestroy(PTR); 35 | int REtest(char *, size_t, PTR); 36 | char *REmatch(char *, size_t, PTR, size_t *, int); 37 | void REmprint(PTR, FILE *); 38 | #endif 39 | 40 | #endif /* MAWK_REPL_H */ 41 | -------------------------------------------------------------------------------- /repl.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | repl.h 3 | copyright 2009-2023,2024, Thomas E. Dickey 4 | copyright 1991,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: repl.h,v 1.14 2024/09/05 17:24:56 tom Exp $ 15 | */ 16 | 17 | /* repl.h */ 18 | 19 | #ifndef REPL_H 20 | #define REPL_H 21 | 22 | #include 23 | 24 | typedef struct _re_data 25 | #ifdef Visible_RE_DATA 26 | { 27 | PTR compiled; /* must be first... */ 28 | int anchored; /* use to limit recursion in gsub */ 29 | int is_empty; /* check if pattern is empty */ 30 | } 31 | #endif 32 | RE_DATA; 33 | 34 | typedef struct _re_node 35 | #ifdef Visible_RE_NODE 36 | { 37 | RE_DATA re; /* keep this first, for re_destroy() */ 38 | STRING *sval; 39 | struct _re_node *link; 40 | } 41 | #endif 42 | RE_NODE; 43 | 44 | /* 45 | * re_compile returns a RE_DATA*, but mawk handles it as a PTR thereafter. 46 | */ 47 | #define isAnchored(ptr) (((RE_DATA *)(ptr))->anchored) 48 | #define isEmpty_RE(ptr) (((RE_DATA *)(ptr))->is_empty) 49 | #define cast_to_re(ptr) (((RE_DATA *)(ptr))->compiled) 50 | 51 | RE_NODE *re_compile(STRING *); 52 | STRING *re_uncompile(PTR); 53 | 54 | CELL *repl_compile(STRING *); 55 | const STRING *repl_uncompile(CELL *); 56 | void re_destroy(PTR); 57 | void repl_destroy(CELL *); 58 | CELL *replv_cpy(CELL *, CELL *); 59 | CELL *replv_to_repl(CELL *, STRING *); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /rexp4.c: -------------------------------------------------------------------------------- 1 | /* 2 | rexp4.c 3 | copyright 2024 Thomas E. Dickey 4 | 5 | This is a source file for mawk, an implementation of 6 | the AWK programming language. 7 | 8 | Mawk is distributed without warranty under the terms of 9 | the GNU General Public License, version 2, 1991. 10 | */ 11 | 12 | /* 13 | * $MawkId: rexp4.c,v 1.12 2024/09/05 17:44:48 tom Exp $ 14 | */ 15 | #include 16 | 17 | char * 18 | is_string_split(PTR q, size_t *lenp) 19 | { 20 | if (q != NULL) { 21 | STRING *s = ((RE_NODE *) q)->sval; 22 | char *result = s->str; 23 | 24 | /* if we have only one character, it cannot be a regex */ 25 | if (s->len == 1) { 26 | *lenp = s->len; 27 | return result; 28 | } else { 29 | size_t n; 30 | for (n = 0; n < s->len; ++n) { 31 | /* if we have a meta character, it probably is a regex */ 32 | switch (result[n]) { 33 | case '\\': 34 | case '$': 35 | case '(': 36 | case ')': 37 | case '*': 38 | case '+': 39 | case '.': 40 | case '?': 41 | case '[': 42 | case ']': 43 | case '^': 44 | case '|': 45 | #ifndef NO_INTERVAL_EXPR 46 | case L_CURL: 47 | case R_CURL: 48 | #endif 49 | return NULL; 50 | } 51 | } 52 | *lenp = s->len; 53 | return result; 54 | } 55 | } 56 | return NULL; 57 | } 58 | -------------------------------------------------------------------------------- /rexpdb.c: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | rexpdb.c 3 | copyright 2008-2024,2025, Thomas E. Dickey 4 | copyright 1991,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: rexpdb.c,v 1.33 2025/01/20 20:16:06 tom Exp $ 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | 21 | /* print a machine for debugging */ 22 | 23 | static const char xlat[][12] = 24 | { 25 | "M_STR", 26 | "M_CLASS", 27 | "M_ANY", 28 | "M_START", 29 | "M_END", 30 | "M_U", 31 | "M_1J", 32 | "M_2JA", 33 | "M_2JB", 34 | "M_SAVE_POS", 35 | "M_2JC", 36 | #ifndef NO_INTERVAL_EXPR 37 | "M_ENTER", 38 | "M_LOOP", 39 | #endif 40 | "M_ACCEPT" 41 | }; 42 | 43 | static const char * 44 | REs_type(STATE * p) 45 | { 46 | return (xlat[((UChar) (p->s_type)) % U_ON]); 47 | } 48 | 49 | void 50 | REmprint(STATE * m, FILE *f) 51 | { 52 | STATE *base = m; 53 | STATE *p = base; 54 | const char *end_on_string; 55 | 56 | while (1) { 57 | int line = (int) (p - base); 58 | fprintf(f, "%03d ", line); 59 | fprintf(f, ".\t"); 60 | if (p->s_type >= END_ON) { 61 | p->s_type = (SType) (p->s_type - END_ON); 62 | end_on_string = "$"; 63 | } else 64 | end_on_string = ""; 65 | 66 | if (p->s_type < 0 || p->s_type >= END_ON) { 67 | fprintf(f, "unknown STATE type %d\n", (int) (p->s_type)); 68 | return; 69 | } 70 | 71 | fprintf(f, "%s", REs_type(p)); 72 | switch (p->s_type) { 73 | case M_STR: 74 | fprintf(f, "\t"); 75 | da_string2(f, p->s_data.str, (size_t) p->s_len, '"'); 76 | break; 77 | 78 | case M_1J: 79 | case M_2JA: 80 | case M_2JB: 81 | case M_2JC: 82 | fprintf(f, "\t%03d", line + p->s_data.jump); 83 | break; 84 | #ifndef NO_INTERVAL_EXPR 85 | case M_ENTER: 86 | fprintf(f, "\t%03d\t# level %d", 87 | line + p->s_data.jump, 88 | (int) p->it_cnt); 89 | break; 90 | case M_LOOP: 91 | fprintf(f, "\t%03d", line + p->s_data.jump); 92 | fprintf(f, " %c", L_CURL); 93 | if (p->it_min != 0) 94 | fprintf(f, INT_FMT, p->it_min); 95 | if (p->it_max != p->it_min) { 96 | fprintf(f, ","); 97 | if (p->it_max != MAX__INT) 98 | fprintf(f, INT_FMT, p->it_max); 99 | } 100 | fprintf(f, "%c", R_CURL); 101 | fprintf(f, "\t# level %d", (int) (p + p->s_enter)->it_cnt); 102 | break; 103 | #endif 104 | case M_CLASS: 105 | { 106 | UChar *q = (UChar *) p->s_data.bvp; 107 | UChar *r = q + sizeof(BV); 108 | unsigned bitnum = 0; 109 | fprintf(f, "\t["); 110 | while (q < r) { 111 | unsigned bits = *q++; 112 | if (bits != 0) { 113 | unsigned b; 114 | for (b = 0; b < 8; ++b) { 115 | if (bits & (unsigned) (1 << b)) { 116 | int ch = (int) (bitnum + b); 117 | if (ch < 32 || ch >= 128) { 118 | fprintf(f, "\\%03o", ch); 119 | } else { 120 | if (strchr("\\[]", ch)) 121 | fprintf(f, "\\"); 122 | fprintf(f, "%c", ch); 123 | } 124 | } 125 | } 126 | } 127 | bitnum += 8; 128 | } 129 | fprintf(f, "]"); 130 | } 131 | break; 132 | } 133 | if (end_on_string[0]) 134 | fprintf(f, "\t%s", end_on_string); 135 | fprintf(f, "\n"); 136 | if (end_on_string[0]) 137 | p->s_type = (SType) (p->s_type + END_ON); 138 | if (p->s_type == M_ACCEPT) 139 | return; 140 | p++; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /scan.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | scan.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 2009, Jonathan Nieder 5 | copyright 1991-1994,1995, Michael D. Brennan 6 | 7 | This is a source file for mawk, an implementation of 8 | the AWK programming language. 9 | 10 | Mawk is distributed without warranty under the terms of 11 | the GNU General Public License, version 2, 1991. 12 | ********************************************/ 13 | 14 | /* 15 | * $MawkId: scan.h,v 1.8 2024/08/25 17:17:41 tom Exp $ 16 | */ 17 | 18 | /* scan.h */ 19 | 20 | #ifndef MAWK_SCAN_H 21 | #define MAWK_SCAN_H 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | extern double double_zero; 30 | extern double double_one; 31 | 32 | extern void eat_nl(void); 33 | 34 | /* in error.c */ 35 | extern void unexpected_char(void); 36 | 37 | #endif /* MAWK_SCAN_H */ 38 | -------------------------------------------------------------------------------- /scancode.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | scancode.h 3 | copyright 2023, Thomas E. Dickey 4 | copyright 2009, Jonathan Nieder 5 | copyright 1991, Michael D. Brennan 6 | 7 | This is a source file for mawk, an implementation of 8 | the AWK programming language. 9 | 10 | Mawk is distributed without warranty under the terms of 11 | the GNU General Public License, version 2, 1991. 12 | ********************************************/ 13 | 14 | /* 15 | * $MawkId: scancode.h,v 1.3 2023/07/22 22:31:02 tom Exp $ 16 | */ 17 | 18 | /* scancode.h */ 19 | 20 | #ifndef SCANCODE_H_INCLUDED 21 | #define SCANCODE_H_INCLUDED 1 22 | 23 | extern char scan_code[256]; 24 | 25 | /* the scan codes to compactify the main switch */ 26 | 27 | typedef enum { 28 | SC_SPACE = 1 29 | ,SC_NL 30 | ,SC_SEMI_COLON 31 | ,SC_FAKE_SEMI_COLON 32 | ,SC_LBRACE 33 | ,SC_RBRACE 34 | ,SC_QMARK 35 | ,SC_COLON 36 | ,SC_OR 37 | ,SC_AND 38 | ,SC_PLUS 39 | ,SC_MINUS 40 | ,SC_MUL 41 | ,SC_DIV 42 | ,SC_MOD 43 | ,SC_POW 44 | ,SC_LPAREN 45 | ,SC_RPAREN 46 | ,SC_LBOX 47 | ,SC_RBOX 48 | ,SC_IDCHAR 49 | ,SC_DIGIT 50 | ,SC_DQUOTE 51 | ,SC_ESCAPE 52 | ,SC_COMMENT 53 | ,SC_EQUAL 54 | ,SC_NOT 55 | ,SC_LT 56 | ,SC_GT 57 | ,SC_COMMA 58 | ,SC_DOT 59 | ,SC_MATCH 60 | ,SC_DOLLAR 61 | ,SC_UNEXPECTED 62 | } SCAN_CODES; 63 | 64 | #endif /* SCANCODE_H_INCLUDED */ 65 | -------------------------------------------------------------------------------- /sizes.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | sizes.h 3 | copyright 2009-2020,2024 Thomas E. Dickey 4 | copyright 1991-1995,2014. Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: sizes.h,v 1.25 2024/08/25 17:16:24 tom Exp $ 15 | */ 16 | 17 | /* sizes.h */ 18 | 19 | #ifndef SIZES_H 20 | #define SIZES_H 21 | /* *INDENT-OFF* */ 22 | 23 | #include 24 | 25 | #ifndef SIZEOF_LONG 26 | #define SIZEOF_LONG 4 27 | #endif 28 | 29 | #ifndef SIZEOF_LONG_LONG 30 | #define SIZEOF_LONG_LONG 4 31 | #endif 32 | 33 | #if defined(HAVE_STDINT_H) && defined(HAVE_INT64_T) && defined(HAVE_UINT64_T) 34 | 35 | #include 36 | #include 37 | 38 | #if defined(INT64_MAX) 39 | #define MAX__INT INT64_MAX 40 | #elif defined(LLONG_MAX) 41 | #define MAX__INT LLONG_MAX 42 | #elif defined(LONG_LONG_MAX) 43 | #define MAX__INT LONG_LONG_MAX 44 | #endif 45 | 46 | #if defined(UINT64_MAX) 47 | #define MAX__UINT UINT64_MAX 48 | #elif defined(LLONG_MAX) 49 | #define MAX__UINT ULLONG_MAX 50 | #elif defined(LONG_LONG_MAX) 51 | #define MAX__UINT ULONG_LONG_MAX 52 | #endif 53 | 54 | #define MAX__LONG MAX__INT 55 | #define MAX__ULONG MAX__UINT 56 | 57 | typedef int64_t Int; 58 | typedef int64_t Long; 59 | #define Max_Int MAX__INT 60 | #define Max_Long MAX__LONG 61 | 62 | typedef uint64_t UInt; 63 | typedef uint64_t ULong; 64 | #define Max_UInt MAX__UINT 65 | #define Max_ULong MAX__ULONG 66 | 67 | #if (SIZEOF_LONG_LONG > SIZEOF_LONG) || defined(__APPLE__) || defined(__OpenBSD__) 68 | #define INT_FMT "%lld" 69 | #define UINT_FMT "%llu" 70 | #define LONG_FMT "%lld" 71 | #define ULONG_FMT "%llu" 72 | #define USE_LL_FORMAT 1 73 | #else 74 | #define INT_FMT "%ld" 75 | #define UINT_FMT "%lu" 76 | #define LONG_FMT "%ld" 77 | #define ULONG_FMT "%lu" 78 | #endif 79 | 80 | #else /* !defined(HAVE_STDINT_H), etc */ 81 | 82 | #ifndef MAX__INT 83 | #include 84 | #define MAX__INT INT_MAX 85 | #define MAX__LONG LONG_MAX 86 | #define MAX__UINT UINT_MAX 87 | #define MAX__ULONG ULONG_MAX 88 | #endif /* MAX__INT */ 89 | 90 | #if MAX__INT <= 0x7fff 91 | #define SHORT_INTS 92 | #define INT_FMT "%ld" 93 | typedef long Int; 94 | typedef long Long; 95 | #define Max_Int MAX__LONG 96 | #define Max_Long MAX__LONG 97 | #else 98 | #define INT_FMT "%d" 99 | typedef int Int; 100 | typedef long Long; 101 | #define Max_Int MAX__INT 102 | #define Max_Long MAX__LONG 103 | #endif 104 | 105 | #if MAX__UINT <= 0xffff 106 | #define SHORT_UINTS 107 | #define UINT_FMT "%lu" 108 | typedef unsigned long UInt; 109 | typedef unsigned long ULong; 110 | #define Max_UInt MAX__ULONG 111 | #define Max_ULong MAX__ULONG 112 | #else 113 | #define UINT_FMT "%u" 114 | typedef unsigned int UInt; 115 | typedef unsigned long ULong; 116 | #define Max_UInt MAX__UINT 117 | #define Max_ULong MAX__ULONG 118 | #endif 119 | 120 | #define LONG_FMT "%ld" 121 | #define ULONG_FMT "%lu" 122 | 123 | #endif /* HAVE_STDINT_H */ 124 | 125 | #define EVAL_STACK_SIZE 1024 /* initial size , can grow */ 126 | 127 | /* 128 | * FBANK_SZ, the number of fields at startup, must be a power of 2. 129 | * 130 | */ 131 | #ifndef FB_SHIFT 132 | #define FB_SHIFT 10 /* lg(FBANK_SZ) */ 133 | #endif 134 | #define FBANK_SZ (1 << FB_SHIFT) 135 | 136 | /* 137 | * hardwired limit on sprintf size, can be overridden with -Ws=xxx 138 | * TBD to remove hard wired limit 139 | */ 140 | #ifndef SPRINTF_LIMIT 141 | #define SPRINTF_LIMIT 8192 142 | #endif 143 | 144 | #define BUFFSZ (SPRINTF_LIMIT / 2) 145 | /* starting buffer size for input files, grows if 146 | necessary */ 147 | 148 | #ifdef MSDOS 149 | /* trade some space for IO speed */ 150 | #undef BUFFSZ 151 | #define BUFFSZ 8192 152 | /* maximum input buffers that will fit in 64K */ 153 | #define MAX_BUFFS ((int)(0x10000L/BUFFSZ) - 1) 154 | #endif 155 | 156 | #define HASH_PRIME 53 157 | #define A_HASH_PRIME 199 158 | 159 | #define MAX_COMPILE_ERRORS 5 /* quit if more than 4 errors */ 160 | 161 | /* *INDENT-ON* */ 162 | 163 | #endif /* SIZES_H */ 164 | -------------------------------------------------------------------------------- /split.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | split.h 3 | copyright 2014,2023 Thomas E. Dickey 4 | copyright 2014, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: split.h,v 1.4 2023/07/23 08:58:07 tom Exp $ 15 | */ 16 | 17 | /* split.h */ 18 | 19 | #ifndef MAWK_SPLIT_H 20 | #define MAWK_SPLIT_H 21 | 22 | extern size_t null_split(const char *s, size_t slen); 23 | extern size_t re_split(char *s, size_t slen, PTR re); 24 | extern size_t space_split(const char *s, size_t slen); 25 | extern void transfer_to_array(CELL cp[], size_t cnt); 26 | extern void transfer_to_fields(size_t cnt); 27 | 28 | #endif /* MAWK_SPLIT_H */ 29 | -------------------------------------------------------------------------------- /symtype.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | symtype.h 3 | copyright 2009-2023,2024, Thomas E. Dickey 4 | copyright 1991, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: symtype.h,v 1.30 2024/09/05 11:40:11 tom Exp $ 15 | */ 16 | 17 | /* types related to symbols are defined here */ 18 | 19 | #ifndef SYMTYPE_H 20 | #define SYMTYPE_H 21 | 22 | #include 23 | 24 | #define MAX_ARGS 255 25 | typedef unsigned char NUM_ARGS; 26 | typedef unsigned char SYM_TYPE; 27 | 28 | /* struct to hold info about builtins */ 29 | typedef struct _bi_rec 30 | #ifdef Visible_BI_REC 31 | { 32 | const char name[12]; 33 | PF_CP fp; /* ptr to function that does the builtin */ 34 | NUM_ARGS min_args, max_args; 35 | /* info for parser to check correct number of arguments */ 36 | } 37 | #endif 38 | BI_REC; 39 | 40 | /*--------------------------- 41 | structures and types for arrays 42 | *--------------------------*/ 43 | 44 | #include 45 | 46 | extern ARRAY Argv; 47 | 48 | /* for parsing (i,j) in A */ 49 | typedef struct arg2_rec 50 | #ifdef Visible_ARG2_REC 51 | { 52 | int start; /* offset to code_base */ 53 | int cnt; 54 | } 55 | #endif 56 | ARG2_REC; 57 | 58 | /*------------------------ 59 | user defined functions 60 | ------------------------*/ 61 | 62 | typedef struct _fblock 63 | #ifdef Visible_FBLOCK 64 | { 65 | const char *name; 66 | INST *code; 67 | size_t size; 68 | NUM_ARGS nargs; 69 | SYM_TYPE *typev; /* array of size nargs holding types */ 70 | } 71 | #endif 72 | FBLOCK; /* function block */ 73 | 74 | extern void add_to_fdump_list(FBLOCK *); 75 | extern void dump_funcs(void); 76 | extern void dump_regex(void); 77 | 78 | /*------------------------- 79 | elements of the symbol table 80 | -----------------------*/ 81 | 82 | typedef enum { 83 | ST_NONE = 0 84 | ,ST_KEYWORD 85 | ,ST_BUILTIN /* a pointer to a builtin record */ 86 | ,ST_FIELD /* a cell ptr to a field */ 87 | ,ST_FUNCT 88 | ,ST_NR /* NR is special */ 89 | ,ST_ENV /* and so is ENVIRON */ 90 | ,ST_VAR = 8 /* a scalar variable (bits from here) */ 91 | ,ST_ARRAY = 16 /* a void * ptr to a hash table */ 92 | ,ST_LOCAL_NONE = 32 93 | ,ST_LOCAL_VAR = (ST_LOCAL_NONE | ST_VAR) 94 | ,ST_LOCAL_ARRAY = (ST_LOCAL_NONE | ST_ARRAY) 95 | } SYMTAB_TYPES; 96 | 97 | #define is_array(stp) (((stp)->type & ST_ARRAY) != 0) 98 | #define is_local(stp) (((stp)->type & ST_LOCAL_NONE) != 0) 99 | 100 | typedef struct _symtab 101 | #ifdef Visible_SYMTAB 102 | { 103 | const char *name; 104 | SYM_TYPE type; 105 | unsigned char offset; /* offset in stack frame for local vars */ 106 | #ifdef NO_LEAKS 107 | char free_name; 108 | #endif 109 | union { 110 | CELL *cp; 111 | int kw; 112 | PF_CP fp; 113 | const BI_REC *bip; 114 | ARRAY array; 115 | FBLOCK *fbp; 116 | } stval; 117 | } 118 | #endif 119 | SYMTAB; 120 | 121 | /***************************** 122 | structures for type checking function calls 123 | ******************************/ 124 | 125 | typedef struct _ca_rec 126 | #ifdef Visible_CA_REC 127 | { 128 | struct _ca_rec *link; 129 | SYM_TYPE type; 130 | NUM_ARGS arg_num; /* position in callee's stack */ 131 | /*--------- this data only set if we'll need to patch -------*/ 132 | /* happens if argument is an ID or type ST_NONE or ST_LOCAL_NONE */ 133 | 134 | int call_offset; 135 | unsigned call_lineno; 136 | /* where the type is stored */ 137 | SYMTAB *sym_p; /* if type is ST_NONE */ 138 | SYM_TYPE *type_p; /* if type is ST_LOCAL_NONE */ 139 | } 140 | #endif 141 | CA_REC; /* call argument record */ 142 | 143 | /* type field of CA_REC matches with ST_ types */ 144 | #define CA_EXPR ST_LOCAL_VAR 145 | #define CA_ARRAY ST_LOCAL_ARRAY 146 | 147 | typedef struct _fcall 148 | #ifdef Visible_FCALL_REC 149 | { 150 | struct _fcall *link; 151 | FBLOCK *callee; 152 | short call_scope; 153 | short move_level; 154 | FBLOCK *call; /* only used if call_scope == SCOPE_FUNCT */ 155 | INST *call_start; /* computed later as code may be moved */ 156 | CA_REC *arg_list; 157 | NUM_ARGS arg_cnt_checked; 158 | } 159 | #endif 160 | FCALL_REC; 161 | 162 | /* defer analysis from length() parameter for forward-references */ 163 | typedef struct _defer_len 164 | #ifdef Visible_DEFER_LEN 165 | { 166 | short offset; 167 | FBLOCK *fbp; 168 | } 169 | #endif 170 | DEFER_LEN; 171 | 172 | extern FCALL_REC *resolve_list; 173 | 174 | extern void resolve_fcalls(void); 175 | extern void check_fcall(FBLOCK * callee, int call_scope, int move_level, 176 | FBLOCK * call, CA_REC * arg_list); 177 | extern void relocate_resolve_list(int, int, const FBLOCK *, int, unsigned, int); 178 | 179 | /* hash.c */ 180 | extern unsigned hash(const char *); 181 | extern unsigned hash2(const char *, size_t); 182 | extern SYMTAB *insert(const char *); 183 | extern SYMTAB *find(const char *); 184 | extern const char *reverse_find(int, PTR); 185 | extern SYMTAB *save_id(const char *); 186 | extern void restore_ids(void); 187 | 188 | /* error.c */ 189 | extern const char *type_to_str(int); 190 | extern void type_error(SYMTAB *); 191 | 192 | #ifdef NO_LEAKS 193 | extern void no_leaks_array(ARRAY); 194 | #else 195 | #define no_leaks_array(a) /* nothing */ 196 | #endif 197 | 198 | #endif /* SYMTYPE_H */ 199 | -------------------------------------------------------------------------------- /test/cclass.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: cclass.awk,v 1.3 2024/07/24 08:10:05 tom Exp $ 2 | # count character-classes 3 | 4 | function count_one(s,r, rc,regex) { 5 | rc = 0; 6 | regex = "[[:" r ":]]+"; 7 | while (match(s,regex)) { 8 | # printf "\t%s: %s\n", regex, substr(s, RSTART, RLENGTH); 9 | rc += RLENGTH; 10 | s = substr(s,RSTART + RLENGTH); 11 | } 12 | return rc; 13 | } 14 | 15 | function count_all(s) { 16 | total += length(s); 17 | _alnum += count_one(s, "alnum"); 18 | _alpha += count_one(s, "alpha"); 19 | _blank += count_one(s, "blank"); 20 | _cntrl += count_one(s, "cntrl"); 21 | _digit += count_one(s, "digit"); 22 | _graph += count_one(s, "graph"); 23 | _lower += count_one(s, "lower"); 24 | _print += count_one(s, "print"); 25 | _punct += count_one(s, "punct"); 26 | _space += count_one(s, "space"); 27 | _upper += count_one(s, "upper"); 28 | _xdigit += count_one(s, "xdigit"); 29 | } 30 | function report(name,value) { 31 | printf("%-8s %*d %5.1f%%\n", name ":", width, value, 100 * value / total); 32 | } 33 | BEGIN{ 34 | total = 0; 35 | _alnum = 0; 36 | } 37 | /./{ count_all($0); } 38 | /$/{ count_all(RS); } 39 | END{ 40 | if (total == 0) { 41 | for (c = 0; c < 255; ++c) { 42 | count_all(sprintf("%c", c)); 43 | } 44 | } 45 | printf "total: %d\n", total; 46 | scale = total; 47 | width = 1; 48 | while (scale > 1) { 49 | scale /= 10; 50 | width++; 51 | } 52 | report("alnum", _alnum); 53 | report("alpha", _alpha); 54 | report("blank", _blank); 55 | report("cntrl", _cntrl); 56 | report("digit", _digit); 57 | report("graph", _graph); 58 | report("lower", _lower); 59 | report("print", _print); 60 | report("punct", _punct); 61 | report("space", _space); 62 | report("upper", _upper); 63 | report("xdigit", _xdigit); 64 | } 65 | -------------------------------------------------------------------------------- /test/cclass.out: -------------------------------------------------------------------------------- 1 | total: 2715 2 | alnum: 1443 53.1% 3 | alpha: 1427 52.6% 4 | blank: 777 28.6% 5 | cntrl: 107 3.9% 6 | digit: 16 0.6% 7 | graph: 1831 67.4% 8 | lower: 1241 45.7% 9 | print: 2608 96.1% 10 | punct: 388 14.3% 11 | space: 884 32.6% 12 | upper: 186 6.9% 13 | xdigit: 509 18.7% 14 | -------------------------------------------------------------------------------- /test/decl-awk.out: -------------------------------------------------------------------------------- 1 | hash: function returning unsigned (extern) 2 | last_dhash: unsigned (static) 3 | A: ARRAY 4 | sval: pointer to STRING 5 | cflag: int 6 | A: ARRAY 7 | d: double 8 | cflag: int 9 | ap: pointer to ANODE 10 | signal: function returning pointer to function returning void 11 | -------------------------------------------------------------------------------- /test/fpe_test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $MawkId: fpe_test,v 1.10 2023/11/02 23:20:31 tom Exp $ 3 | ############################################################################### 4 | # copyright 2009-2022,2023, Thomas E. Dickey 5 | # copyright 2010, Guido Berhoerster 6 | # copyright 1994,1995, Michael D. Brennan 7 | # 8 | # This is a source file for mawk, an implementation of 9 | # the AWK programming language. 10 | # 11 | # Mawk is distributed without warranty under the terms of 12 | # the GNU General Public License, version 2, 1991. 13 | ############################################################################### 14 | 15 | # tests if mawk has been compiled to correctly handle 16 | # floating point exceptions 17 | 18 | PROG="${MAWK:-../mawk}" 19 | 20 | : "${EGREP:=grep -E}" 21 | : "${FGREP:=grep -F}" 22 | 23 | echo "testing floating point exception handling" 24 | 25 | STDOUT=${TMPDIR-/tmp}/mawktest$$ 26 | 27 | test1='BEGIN{ print 4/0 }' 28 | 29 | 30 | test2='BEGIN { 31 | x = 100 32 | do { y = x ; x *= 1000 } while ( y != x ) 33 | print "loop terminated" 34 | }' 35 | 36 | # this used to test log(-8), but that was too challenging for cygwin hackers 37 | test3='BEGIN{ print sqrt(-8) }' 38 | 39 | 40 | echo "testing division by zero" 41 | echo "$PROG" "$test1" 42 | $PROG "$test1" 43 | ret1=$? 44 | echo 45 | 46 | echo "testing overflow" 47 | echo "$PROG" "$test2" 48 | $PROG "$test2" 49 | ret2=$? 50 | echo 51 | 52 | echo "testing domain error" 53 | echo "$PROG" "$test3" 54 | $PROG "$test3" > "$STDOUT" 55 | ret3=$? 56 | cat "$STDOUT" 57 | echo 58 | 59 | 60 | # the returns should all be zero or all 2 61 | # core dumps not allowed 62 | 63 | trap ' 64 | echo compilation defines for floating point are incorrect 65 | rm -f $STDOUT 66 | exit 1' 0 67 | 68 | echo 69 | echo ============================== 70 | 71 | echo return1 = $ret1 72 | echo return2 = $ret2 73 | echo return3 = $ret3 74 | 75 | 76 | [ $ret1 -gt 128 ] && { echo test1 failed ; exception=1 ; } 77 | [ $ret2 -gt 128 ] && { echo test2 failed ; exception=1 ; } 78 | [ $ret3 -gt 128 ] && { echo test3 failed ; exception=1 ; } 79 | 80 | [ "$exception" = 1 ] && { rm -f ./*core* "$STDOUT" ; exit 1 ; } 81 | 82 | 83 | same=0 84 | 85 | [ $ret1 = $ret2 ] && [ $ret2 = $ret3 ] && same=1 86 | 87 | 88 | if [ $same = 1 ] 89 | then 90 | if [ $ret1 = 0 ] 91 | then 92 | echo "results consistent: ignoring floating exceptions" 93 | # some versions of hpux print NAN as ? 94 | if $EGREP '[nN][aA][nN]|\?' "$STDOUT" > /dev/null 95 | then 96 | : 97 | # MSYS / MinGW uses a different string... 98 | elif $FGREP '#IND' "$STDOUT" > /dev/null 99 | then 100 | echo "found MinGW hack for NaN..." 101 | else 102 | echo "but the library is not IEEE754 compatible" 103 | echo "test 3 failed" 104 | exit 1 105 | fi 106 | else echo "results consistent: trapping floating exceptions" 107 | fi 108 | 109 | trap 0 110 | rm -f "$STDOUT" 111 | exit 0 112 | 113 | else 114 | cat <<-EOF 115 | results are not consistent 116 | return values should all be 0 if ignoring FPEs (e.g. with IEEE754) 117 | or all 2 if trapping FPEs 118 | EOF 119 | 120 | exit 1 121 | fi 122 | # vile: ts=4 sw=4 123 | -------------------------------------------------------------------------------- /test/fpe_test.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | rem $MawkId: fpe_test.bat,v 1.2 2010/12/10 17:00:00 tom Exp $ 3 | rem vile:rs=lf 4 | rem 5 | rem ########################################################################## 6 | rem copyright 1996, Michael D. Brennan 7 | rem 8 | rem This is a source file for mawk, an implementation of 9 | rem the AWK programming language. 10 | rem 11 | rem Mawk is distributed without warranty under the terms of 12 | rem the GNU General Public License, version 2, 1991. 13 | rem ########################################################################## 14 | rem 15 | rem tests if mawk has been compiled to correctly handle 16 | rem floating point exceptions 17 | 18 | echo testing division by zero 19 | type fpetest1.awk 20 | ..\mawk -f fpetest1.awk 21 | if errorlevel 128 goto :test1_128 22 | if errorlevel 3 goto :test1_3 23 | if errorlevel 2 goto :test1_2 24 | if errorlevel 1 goto :test1_1 25 | set ret1=0 26 | goto :test2 27 | :test1_128 28 | set ret1=128 29 | goto :test2 30 | :test1_3 31 | set ret1=3 32 | goto :test2 33 | :test1_2 34 | set ret1=2 35 | goto :test2 36 | :test1_1 37 | set ret1=1 38 | 39 | :test2 40 | echo testing overflow 41 | type fpetest2.awk 42 | ..\mawk -f fpetest2.awk 43 | if errorlevel 128 goto :test2_128 44 | if errorlevel 3 goto :test2_3 45 | if errorlevel 2 goto :test2_2 46 | if errorlevel 1 goto :test2_1 47 | set ret2=0 48 | goto :test3 49 | :test2_128 50 | set ret2=128 51 | goto :test3 52 | :test2_3 53 | set ret2=3 54 | goto :test3 55 | :test2_2 56 | set ret2=2 57 | goto :test3 58 | :test2_1 59 | set ret2=1 60 | 61 | :test3 62 | echo testing domain error 63 | type fpetest3.awk 64 | ..\mawk -f fpetest3.awk > temp$$ 65 | if errorlevel 128 goto :test3_128 66 | if errorlevel 3 goto :test3_3 67 | if errorlevel 2 goto :test3_2 68 | if errorlevel 1 goto :test3_1 69 | set ret3=0 70 | goto :type3 71 | :test3_128 72 | set ret3=128 73 | goto :type3 74 | :test3_3 75 | set ret3=3 76 | goto :type3 77 | :test3_2 78 | set ret3=2 79 | goto :type3 80 | :test3_1 81 | set ret3=1 82 | 83 | :type3 84 | type temp$$ 85 | 86 | rem the returns should all be zero or all 2 87 | 88 | echo ************************************* 89 | echo return1 = %ret1% 90 | echo return2 = %ret2% 91 | echo return3 = %ret3% 92 | 93 | set exception=0 94 | if %ret1% == 2 goto :okay1 95 | if %ret1% == 0 goto :okay1 96 | echo test1 failed 97 | set exception=1 98 | :okay1 99 | if %ret2% == 2 goto :okay2 100 | if %ret2% == 0 goto :okay2 101 | echo test2 failed 102 | set exception=1 103 | :okay2 104 | if %ret3% == 2 goto :okay3 105 | if %ret3% == 0 goto :okay3 106 | echo test3 failed 107 | set exception=1 108 | :okay3 109 | 110 | if %exception% == 1 goto :done 111 | 112 | set same=1 113 | if %ret1% == %ret2% goto :same12 114 | set same=0 115 | :same12 116 | if %ret2% == %ret3% goto :same23 117 | set same=0 118 | :same23 119 | 120 | if %same% == 1 goto :same123 121 | echo results are not consistent 122 | echo return values should all be 0 if ignoring FPEs (e.g. with IEEE754) 123 | echo or all 2 if trapping FPEs 124 | goto :cleanup 125 | 126 | :same123 127 | if %ret1% == 0 goto :allzero 128 | echo results consistent: trapping floating exceptions 129 | goto :cleanup 130 | 131 | :allzero 132 | echo results consistent: ignoring floating exceptions 133 | grep -i nan temp$$ >NUL 134 | if not errorlevel 1 goto :cleanup 135 | echo but the library is not IEEE754 compatible 136 | echo test 3 failed 137 | 138 | :cleanup 139 | del temp$$ 140 | 141 | :done 142 | set ret1= 143 | set ret2= 144 | set ret3= 145 | set same= 146 | if %exception% == 1 goto :done1 147 | set exception= 148 | exit 0 149 | :done1 150 | set exception= 151 | exit 1 152 | exit %exception% 153 | -------------------------------------------------------------------------------- /test/fpetest1.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: fpetest1.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN{ print 4/0 } 13 | -------------------------------------------------------------------------------- /test/fpetest2.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: fpetest2.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN { 13 | x = 100 14 | do { y = x ; x *= 1000 } while ( y != x ) 15 | print "loop terminated" 16 | } 17 | -------------------------------------------------------------------------------- /test/fpetest3.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: fpetest3.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN{ print log(-8) } 13 | -------------------------------------------------------------------------------- /test/full-awk.dat: -------------------------------------------------------------------------------- 1 | This has to be a small file to check if mawk handles write errors correctly 2 | even on a full disk. It has to be smaller than the write buffer of the 3 | C library. 4 | -------------------------------------------------------------------------------- /test/hashbang-S.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S mawk -Wv 2 | # On some systems, the "env" utility adds a "-S" option which lets the above 3 | # line run mawk and pass following tokens as options rather than as part of 4 | # the command-name. 5 | # 6 | # The "-S" option came from FreeBSD in 2005, was adopted by coreutils in 2018. 7 | # 8 | # As of August 2024, it is also recognized by MacOS (seen in its manpage for 9 | # March 2021), but not NetBSD, OpenBSD, or busybox. 10 | # 11 | # FreeBSD: 12 | # commit 8fbe7ebf7d04da629529ae7d2f662a2c46d61b97 13 | # Author: Garance A Drosehn 14 | # Date: Mon Jun 20 03:43:25 2005 +0000 15 | # 16 | # Add the '-S' and '-P' options. The '-S' option can be used to split 17 | # apart a string, and supports some text substitutions. This can be 18 | # used to provide all the flexibility (and more!) that was lost by recent 19 | # changes to how the kernel parses #!-lines in shell scripts. 20 | # 21 | # The '-P' option provides a way to specify an alternate set of directories 22 | # to use when searching for the 'utility' program to run. This way you can 23 | # be sure what directories are used for that search, without changing the 24 | # value of PATH that the user has set. Note that on FreeBSD 6.0, this 25 | # option is worthless unless the '-S' option is also used. 26 | # 27 | # Approved by: re (blanket `env') 28 | # 29 | # coreutils: 30 | # commit 668306ed86c8c79b0af0db8b9c882654ebb66db2 31 | # Author: Assaf Gordon 32 | # Date: Fri Apr 20 20:58:28 2018 -0600 33 | # 34 | # env: add -S/--split-string option 35 | # 36 | # Adopted from FreeBSD's env(1), useful for specifing multiple 37 | # parameters on a shebang (#!) script line, e.g: 38 | # 39 | # #!/usr/bin/env -S perl -w -T 40 | # 41 | # Discussed in https://lists.gnu.org/r/coreutils/2018-04/msg00011.html 42 | # 43 | # * src/env.c (valid_escape_sequence,escape_char,scan_varname, 44 | # extract_varname,validate_split_str,build_argv, 45 | # parse_split_string): New functions. 46 | # (main): Process new option and call parse_split_string. 47 | # (usage): Mention new option. 48 | # * tests/misc/env-S.pl: Test new option from the command line. 49 | # * tests/misc/env-S-script.sh: Test new option from shebang scripts. 50 | # * tests/local.mk (all_tests): Add new tests. 51 | # * man/env.x (OPTIONS): Show a brief example of -S usage and point to 52 | # the full documentation for more information. 53 | # * doc/coreutils.texi (env invocation): Detail usage of -S/--split-string 54 | # option. 55 | # * NEWS: Mention new option. 56 | -------------------------------------------------------------------------------- /test/interval0.awk: -------------------------------------------------------------------------------- 1 | # Test-script for MAWK 2 | ############################################################################### 3 | # copyright 2016, jlp765 4 | # 5 | # This is a source file for mawk, an implementation of 6 | # the AWK programming language. 7 | # 8 | # Mawk is distributed without warranty under the terms of 9 | # the GNU General Public License, version 2, 1991. 10 | ############################################################################### 11 | /b{0,0}/ 12 | /b{0}/ 13 | /b{,0}/ 14 | /ab{0,0}c/ 15 | /ab{0}c/ 16 | /^ab{0,1}c/ 17 | /ab{0,1}c/ 18 | /ab{0,3}c/ 19 | /ab{0,}c/ 20 | /b{0,1}c/ 21 | /b{0,2}c/ 22 | /b{0,3}c/ 23 | /b{0,3}/ 24 | /b{0}c/ 25 | /b{0,}/ 26 | /b{0}/ 27 | /(bbb){0,}/ 28 | -------------------------------------------------------------------------------- /test/longline.out: -------------------------------------------------------------------------------- 1 | 424488 35374 2 | -------------------------------------------------------------------------------- /test/longline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $MawkId: longline.sh,v 1.6 2024/08/25 21:45:19 tom Exp $ 3 | ############################################################################### 4 | # copyright 2024, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | : "${AWK=./mawk}" 14 | case $AWK in 15 | *mawk*) 16 | OPT_O=-Ws=0x20000 17 | OPT_I=-Wi 18 | ;; 19 | *) 20 | OPT_O= 21 | OPT_I= 22 | ;; 23 | esac 24 | $AWK $OPT_O 'BEGIN { 25 | chunk = sprintf("%*s", 2 * 769, "#"); 26 | gsub(" ","#",chunk); 27 | for ( p = 0; p < 23; ++p) { 28 | record = record chunk; 29 | printf "%s\n", record; 30 | } 31 | }' | \ 32 | $AWK $OPT_O $OPT_I 'BEGIN { 33 | widest = total = 0; 34 | } 35 | { 36 | this = length($0); 37 | total += this; 38 | if (this > widest) widest = this; 39 | } 40 | END { 41 | print total, widest 42 | }' 43 | -------------------------------------------------------------------------------- /test/mawknull.dat: -------------------------------------------------------------------------------- 1 | -r--r--r--1tomusers191993-07-0314:58fpetest1.awk 2 | -r--r--r--1tomusers911993-07-0314:58fpetest2.awk 3 | -r--r--r--1tomusers231993-07-0314:58fpetest3.awk 4 | -r--r--r--1tomusers1402009-07-2612:16null-rs.awk 5 | -r--r--r--1tomusers331993-07-0314:58reg0.awk 6 | -r--r--r--1tomusers411993-07-0314:58reg1.awk 7 | -r--r--r--1tomusers621993-07-0314:58reg2.awk 8 | -r--r--r--1tomusers4102009-09-1719:29reg4.awk 9 | -r--r--r--1tomusers7272009-09-1620:51reg5.awk 10 | -r--r--r--1tomusers331993-07-0314:58wc.awk 11 | -r--r--r--1tomusers16891993-07-0314:58wfrq0.awk 12 | -------------------------------------------------------------------------------- /test/mawktest.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem $MawkId: mawktest.bat,v 1.18 2024/08/12 23:57:28 tom Exp $ 3 | rem vile:rs=lf 4 | rem 5 | rem ########################################################################## 6 | rem copyright 2010-2020,2024 Thomas E. Dickey 7 | rem copyright 1996, Michael D. Brennan 8 | rem 9 | rem This is a source file for mawk, an implementation of 10 | rem the AWK programming language. 11 | rem 12 | rem Mawk is distributed without warranty under the terms of 13 | rem the GNU General Public License, version 2, 1991. 14 | rem ########################################################################## 15 | rem 16 | rem This is a simple test check if a newly built mawk is working properly. 17 | rem It's certainly not exhaustive! 18 | rem 19 | rem It must be run from mawk/test. 20 | rem You also need a binary-compare utility, e.g., "cmp". 21 | setlocal 22 | 23 | set dat=mawktest.dat 24 | if %CMP%.==. set CMP=cmp 25 | 26 | set PROG=..\mawk 27 | set MAWKBINMODE=7 28 | 29 | set STDOUT=temp$$ 30 | 31 | rem find out which mawk we're testing 32 | %PROG% -Wv 33 | 34 | rem ################################ 35 | 36 | call :begin testing input and field splitting 37 | 38 | %PROG% -f null-rs.awk null-rs.dat > %STDOUT% 39 | call :compare "null-rs.awk" %STDOUT% null-rs.out 40 | 41 | %PROG% -f wc.awk %dat% > %STDOUT% 42 | call :compare "wc.awk" %STDOUT% wc-awk.out 43 | 44 | call :cmpsp2 "(a?)*b" "a*b" 45 | call :cmpsp2 "(a?)+b" "a*b" 46 | call :cmpsp2 "[^^]" "(.)" 47 | rem call :cmpsp2 "[^]]" "[[#a-zA-Z0-9/*!=<>+,;.&_%(){}" -]" 48 | call :cmpsp2 "[a[]" "[[a]" 49 | rem call :cmpsp2 "(])" "[]]" 50 | call :chkone "[\" 51 | rem call :cmpsp2 "(^)?)" ")" 52 | call :cmpsp3 "a*+" "a*" 53 | 54 | %PROG% -F "\000" -f nulls0.awk mawknull.dat > %STDOUT% 55 | %PROG% -F "[\000 ]" -f nulls0.awk mawknull.dat >> %STDOUT% 56 | call :compare "nulls" %STDOUT% nulls.out 57 | 58 | rem #################################### 59 | 60 | call :begin testing regular expression matching 61 | %PROG% -f reg0.awk %dat% > %STDOUT% 62 | %PROG% -f reg1.awk %dat% >> %STDOUT% 63 | %PROG% -f reg2.awk %dat% >> %STDOUT% 64 | %PROG% -f reg3.awk %dat% >> %STDOUT% 65 | %PROG% -f reg4.awk %dat% >> %STDOUT% 66 | %PROG% -f reg5.awk %dat% >> %STDOUT% 67 | %PROG% -f reg6.awk %dat% >> %STDOUT% 68 | %PROG% -f reg7.awk %dat% >> %STDOUT% 69 | call :compare "reg0-reg7" %STDOUT% reg-awk.out 70 | 71 | echo ''Italics with an apostrophe' embedded'' | %PROG% -f noloop.awk 72 | echo ''Italics with an apostrophe'' embedded'' | %PROG% -f noloop.awk 73 | 74 | %PROG% "/^[^^]*$/" %dat% > %STDOUT% 75 | call :compare "case 1" %STDOUT% %dat% 76 | 77 | rem call :cmpsp0 "!/^[^]]*$/" "/]/" 78 | rem call :cmpsp0 "/[a[]/" "/[[a]/" 79 | rem call :cmpsp0 "/]/" "/[]]/" 80 | 81 | rem ###################################### 82 | 83 | call :begin testing arrays and flow of control 84 | %PROG% -f wfrq0.awk %dat% > %STDOUT% 85 | call :compare "array-test" %STDOUT% wfrq-awk.out 86 | 87 | rem ###################################### 88 | 89 | call :begin testing nextfile 90 | %PROG% -f nextfile.awk full-awk.dat %dat% > %STDOUT% 91 | call :compare "nextfile-test" %STDOUT% nextfile.out 92 | 93 | rem ###################################### 94 | 95 | call :begin testing interval-expressions 96 | %PROG% -f repetitions.awk repetitions.dat > %STDOUT% 97 | call :compare "repetitions-test" %STDOUT% repetitions.out 98 | 99 | %PROG% -f interval0.awk repetitions.dat > %STDOUT% 100 | call :compare "empty-intervals-test" %STDOUT% interval0.out 101 | 102 | rem ################################ 103 | 104 | call :begin testing function calls and general stress test 105 | %PROG% -f ../examples/decl.awk %dat% > %STDOUT% 106 | call :compare "general" %STDOUT% decl-awk.out 107 | 108 | rem ###################################### 109 | 110 | call :begin testing character classes 111 | %PROG% -f cclass.awk mawktest.dat > %STDOUT% 112 | call :compare "character-classes" %STDOUT% cclass.out 113 | 114 | rem ###################################### 115 | 116 | echo. 117 | echo if %CMP% always encountered "no differences", then the tested mawk seems OK 118 | 119 | del %STDOUT% 120 | 121 | endlocal 122 | goto :eof 123 | 124 | :cmpsp0 125 | echo ...checking %1 vs %2 126 | %PROG% -F "%1" %dat% > %STDOUT% 127 | %PROG% -F "%2" %dat% | cmp -s - %STDOUT% 128 | if errorlevel 1 goto :errsp0 129 | echo ...ok 130 | goto :eof 131 | :errsp0 132 | echo ...fail 133 | goto :eof 134 | 135 | :chkone 136 | echo ...checking %1 137 | %PROG% -F "%1" 2> %STDOUT% 138 | if errorlevel 1 goto :errsp1 139 | echo ...ok 140 | goto :eof 141 | :errsp1 142 | echo ...fail 143 | goto :eof 144 | 145 | :cmpsp2 146 | echo ...checking %1 vs %2 147 | %PROG% -F "%1" -f wc.awk %dat% > %STDOUT% 148 | %PROG% -F "%2" -f wc.awk %dat% | cmp -s - %STDOUT% 149 | if errorlevel 1 goto :errsp2 150 | echo ...ok 151 | goto :eof 152 | :errsp2 153 | echo ...fail 154 | goto :eof 155 | 156 | :cmpsp3 157 | echo ...checking %1 vs %2 158 | %PROG% -F "%1" "{print NF}" > %STDOUT% 159 | %PROG% -F "%2" "{print NF}" | cmp -s - %STDOUT% 160 | if errorlevel 1 goto :errsp3 161 | echo ...ok 162 | goto :eof 163 | :errsp3 164 | echo ...fail 165 | goto :eof 166 | 167 | :begin 168 | echo. 169 | echo %* 170 | goto :eof 171 | 172 | :compare 173 | set TESTNAME=%1 174 | echo ...checking %2 %3 175 | %CMP% %2 %3 176 | if errorlevel 1 goto :failed 177 | echo ...ok 178 | goto :eof 179 | :failed 180 | echo ...fail 181 | goto :eof 182 | -------------------------------------------------------------------------------- /test/mawktest.dat: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | extern unsigned hash() ; 5 | 6 | /* An array A is a pointer to an array of struct array, 7 | which is two hash tables in one. One for strings 8 | and one for doubles. 9 | 10 | each array is of size A_HASH_PRIME. 11 | 12 | When an index is deleted via delete A[i], the 13 | ANODE is not removed from the hash chain. A[i].cp 14 | and A[i].sval are both freed and sval is set NULL. 15 | This method of deletion simplifies for( i in A ) loops. 16 | 17 | On the D_ANODE list, we use real deletion and move to the 18 | front on access. 19 | 20 | Separate nodes (as opposed to one type of node on two lists) 21 | to 22 | (1) d1 != d2, but sprintf(A_FMT,d1) == sprintf(A_FMT,d1) 23 | so two dnodes can point at the same anode. 24 | (2) Save a little data space(64K PC mentality). 25 | 26 | the cost is an extra level of indirection. 27 | 28 | Some care is needed so that things like 29 | A[1] = 2 ; delete A["1"] work . 30 | */ 31 | 32 | #define _dhash(d) (((int)(d)&0x7fff)%A_HASH_PRIME) 33 | #define DHASH(d) (last_dhash=_dhash(d)) 34 | static unsigned last_dhash ; 35 | 36 | /* switch =======;;;;;;hhhh */ 37 | 38 | static ANODE *find_by_sval(A, sval, cflag) 39 | ARRAY A ; 40 | STRING *sval ; 41 | int cflag ; /* create if on */ 42 | { 43 | char *s = sval->str ; 44 | unsigned h = hash(s) % A_HASH_PRIME ; 45 | register ANODE *p = A[h].link ; 46 | ANODE *q = 0 ; /* holds first deleted ANODE */ 47 | 48 | while ( p ) 49 | { 50 | if ( p->sval ) 51 | { if ( strcmp(s,p->sval->str) == 0 ) return p ; } 52 | else /* its deleted, mark with q */ 53 | if ( ! q ) q = p ; 54 | 55 | p = p->link ; 56 | } 57 | 58 | /* not there */ 59 | if ( cflag ) 60 | { 61 | if ( q ) p = q ; /* reuse the deleted node q */ 62 | else 63 | { p = (ANODE *)zmalloc(sizeof(ANODE)) ; 64 | p->link = A[h].link ; A[h].link = p ; 65 | } 66 | 67 | p->sval = sval ; 68 | sval->ref_cnt++ ; 69 | p->cp = (CELL *) zmalloc(sizeof(CELL)) ; 70 | p->cp->type = C_NOINIT ; 71 | } 72 | return p ; 73 | } 74 | 75 | 76 | /* on the D_ANODE list, when we find a node we move it 77 | to the front of the hash chain */ 78 | 79 | static D_ANODE *find_by_dval(A, d, cflag) 80 | ARRAY A ; 81 | double d ; 82 | int cflag ; 83 | { 84 | unsigned h = DHASH(d) ; 85 | register D_ANODE *p = A[h].dlink ; 86 | D_ANODE *q = 0 ; /* trails p for move to front */ 87 | ANODE *ap ; 88 | 89 | while ( p ) 90 | if ( p->dval == d ) 91 | { /* found */ 92 | if ( ! p->ap->sval ) /* but it was deleted by string */ 93 | { if ( q ) q->dlink = p->dlink ; 94 | else A[h].dlink = p->dlink ; 95 | zfree(p, sizeof(D_ANODE)) ; 96 | break ; 97 | } 98 | /* found */ 99 | if ( !q ) return p ; /* already at front */ 100 | else /* delete to put at front */ 101 | { q->dlink = p->dlink ; goto found ; } 102 | } 103 | else 104 | { q = p ; p = p->dlink ; } 105 | 106 | void (*signal())() ; 107 | 108 | -------------------------------------------------------------------------------- /test/nextfile.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: nextfile.awk,v 1.1 2012/06/27 13:53:45 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2012, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | {printf "%s(%d):", FILENAME, FNR; print $0; } 13 | /I/ {nextfile;} 14 | -------------------------------------------------------------------------------- /test/nextfile.out: -------------------------------------------------------------------------------- 1 | full-awk.dat(1):This has to be a small file to check if mawk handles write errors correctly 2 | full-awk.dat(2):even on a full disk. It has to be smaller than the write buffer of the 3 | mawktest.dat(1): 4 | mawktest.dat(2):#include 5 | mawktest.dat(3): 6 | mawktest.dat(4):extern unsigned hash() ; 7 | mawktest.dat(5): 8 | mawktest.dat(6):/* An array A is a pointer to an array of struct array, 9 | mawktest.dat(7): which is two hash tables in one. One for strings 10 | mawktest.dat(8): and one for doubles. 11 | mawktest.dat(9): 12 | mawktest.dat(10): each array is of size A_HASH_PRIME. 13 | -------------------------------------------------------------------------------- /test/noloop.awk: -------------------------------------------------------------------------------- 1 | # From jhart@avcnet.bates.edu Sun Oct 6 16:05:21 2002 2 | # Date: Sun, 6 Oct 2002 08:36:54 -0400 3 | # Subject: Infinite loop in sub/gsub 4 | # From: jhart@avcnet.bates.edu 5 | # To: bug-gawk@gnu.org 6 | # Message-Id: <4BC4A4F0-D928-11D6-8E78-00039384A9CC@mail.avcnet.org> 7 | # 8 | # This command line: 9 | # 10 | # echo "''Italics with an apostrophe'' embedded''"|gawk -f test.awk 11 | # 12 | # where test.awk contains this instruction: 13 | # 14 | /''/ { sub(/''(.?[^']+)*''/, "&"); } 15 | # 16 | # puts gawk 3.11 into an infinite loop. Whereas, this command works: 17 | # 18 | # echo "''Italics with an apostrophe' embedded''"|gawk -f test.awk 19 | # 20 | # 21 | # 22 | # Platform: Mac OS X 10.1.5/Darwin Kernel Version 5.5: Thu May 30 14:51:26 23 | # PDT 2002; root:xnu/xnu-201.42.3.obj~1/RELEASE_PPC 24 | # 25 | # 26 | -------------------------------------------------------------------------------- /test/null-rs.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: null-rs.awk,v 1.3 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2009, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | # the test-data was generated on Linux using bash: 13 | #for ((i = 1; i <= 10; ++i)) ;do echo -ne "$i\0"; done 14 | BEGIN {RS = "\0"}; END {print NR} 15 | -------------------------------------------------------------------------------- /test/null-rs.dat: -------------------------------------------------------------------------------- 1 | 12345678910 -------------------------------------------------------------------------------- /test/null-rs.out: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/nulls.out: -------------------------------------------------------------------------------- 1 | 1: 8 - 1993-07-03 fpetest1.awk 2 | 2: 8 - 1993-07-03 fpetest2.awk 3 | 3: 8 - 1993-07-03 fpetest3.awk 4 | 4: 8 - 2009-07-26 null-rs.awk 5 | 5: 8 - 1993-07-03 reg0.awk 6 | 6: 8 - 1993-07-03 reg1.awk 7 | 7: 8 - 1993-07-03 reg2.awk 8 | 8: 8 - 2009-09-17 reg4.awk 9 | 9: 8 - 2009-09-16 reg5.awk 10 | 10: 8 - 1993-07-03 wc.awk 11 | 11: 8 - 1993-07-03 wfrq0.awk 12 | 1: 8 - 1993-07-03 fpetest1.awk 13 | 2: 8 - 1993-07-03 fpetest2.awk 14 | 3: 8 - 1993-07-03 fpetest3.awk 15 | 4: 8 - 2009-07-26 null-rs.awk 16 | 5: 8 - 1993-07-03 reg0.awk 17 | 6: 8 - 1993-07-03 reg1.awk 18 | 7: 8 - 1993-07-03 reg2.awk 19 | 8: 8 - 2009-09-17 reg4.awk 20 | 9: 8 - 2009-09-16 reg5.awk 21 | 10: 8 - 1993-07-03 wc.awk 22 | 11: 8 - 1993-07-03 wfrq0.awk 23 | -------------------------------------------------------------------------------- /test/nulls0.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: nulls0.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2009, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | { 13 | printf "%3d: %2d - %s %s\n", NR, NF, $6, $8; 14 | } 15 | -------------------------------------------------------------------------------- /test/reg-awk.out: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 | 1 4 | 0 -1 5 | reg4.1<<: >> 6 | reg4.2<<: >> 7 | reg4.3<<: >> 8 | reg4.4<<: >> 9 | reg4.5<<: >> 10 | reg4.1<<: >> 11 | reg4.2<<: >> 12 | reg4.3<<: >> 13 | reg4.4<<: >> 14 | reg4.5<<: >> 15 | reg4.1<<: >> 16 | reg4.2<<: >> 17 | reg4.3<<: >> 18 | reg4.4<<: >> 19 | reg4.5<<: >> 20 | reg4.1<<: >> 21 | reg4.2<<: >> 22 | reg4.3<<: >> 23 | reg4.4<<: >> 24 | reg4.5<<: >> 25 | reg4.1<<: >> 26 | reg4.2<<: >> 27 | reg4.3<<: >> 28 | reg4.4<<: >> 29 | reg4.5<<: >> 30 | reg4.1<<: >> 31 | reg4.2<<: >> 32 | reg4.3<<: >> 33 | reg4.4<<: >> 34 | reg4.5<<: >> 35 | reg4.1<<: >> 36 | reg4.2<<: >> 37 | reg4.3<<: >> 38 | reg4.4<<: >> 39 | reg4.5<<: >> 40 | reg4.3<<: to >> 41 | reg4.5<<: to >> 42 | reg4.1<<: >> 43 | reg4.2<<: >> 44 | reg4.3<<: >> 45 | reg4.4<<: >> 46 | reg4.5<<: >> 47 | reg4.1<<: >> 48 | reg4.2<<: >> 49 | reg4.3<<: >> 50 | reg4.4<<: >> 51 | reg4.5<<: >> 52 | reg4.3<<: Some care is needed so that things like >> 53 | reg4.5<<: Some care is needed so that things like >> 54 | reg4.1<<: >> 55 | reg4.2<<: >> 56 | reg4.3<<: >> 57 | reg4.4<<: >> 58 | reg4.5<<: >> 59 | reg4.3<<: static unsigned last_dhash ; >> 60 | reg4.5<<: static unsigned last_dhash ; >> 61 | reg4.1<<: >> 62 | reg4.2<<: >> 63 | reg4.3<<: >> 64 | reg4.4<<: >> 65 | reg4.5<<: >> 66 | reg4.1<<: >> 67 | reg4.2<<: >> 68 | reg4.3<<: >> 69 | reg4.4<<: >> 70 | reg4.5<<: >> 71 | reg4.3<<: ARRAY A ; >> 72 | reg4.5<<: ARRAY A ; >> 73 | reg4.3<<: STRING *sval ; >> 74 | reg4.5<<: STRING *sval ; >> 75 | reg4.3<<: { >> 76 | reg4.1<<: >> 77 | reg4.2<<: >> 78 | reg4.3<<: >> 79 | reg4.4<<: >> 80 | reg4.5<<: >> 81 | reg4.3<<: { >> 82 | reg4.1<<: >> 83 | reg4.2<<: >> 84 | reg4.3<<: >> 85 | reg4.4<<: >> 86 | reg4.5<<: >> 87 | reg4.3<<: } >> 88 | reg4.1<<: >> 89 | reg4.2<<: >> 90 | reg4.3<<: >> 91 | reg4.4<<: >> 92 | reg4.5<<: >> 93 | reg4.3<<: { >> 94 | reg4.3<<: else >> 95 | reg4.5<<: else >> 96 | reg4.3<<: } >> 97 | reg4.1<<: >> 98 | reg4.2<<: >> 99 | reg4.3<<: >> 100 | reg4.4<<: >> 101 | reg4.5<<: >> 102 | reg4.3<<: } >> 103 | reg4.3<<: return p ; >> 104 | reg4.5<<: return p ; >> 105 | reg4.3<<: } >> 106 | reg4.4<<: } >> 107 | reg4.1<<: >> 108 | reg4.2<<: >> 109 | reg4.3<<: >> 110 | reg4.4<<: >> 111 | reg4.5<<: >> 112 | reg4.1<<: >> 113 | reg4.2<<: >> 114 | reg4.3<<: >> 115 | reg4.4<<: >> 116 | reg4.5<<: >> 117 | reg4.1<<: >> 118 | reg4.2<<: >> 119 | reg4.3<<: >> 120 | reg4.4<<: >> 121 | reg4.5<<: >> 122 | reg4.3<<: ARRAY A ; >> 123 | reg4.5<<: ARRAY A ; >> 124 | reg4.3<<: double d ; >> 125 | reg4.5<<: double d ; >> 126 | reg4.3<<: int cflag ; >> 127 | reg4.5<<: int cflag ; >> 128 | reg4.3<<: { >> 129 | reg4.4<<: { >> 130 | reg4.3<<: ANODE *ap ; >> 131 | reg4.5<<: ANODE *ap ; >> 132 | reg4.1<<: >> 133 | reg4.2<<: >> 134 | reg4.3<<: >> 135 | reg4.4<<: >> 136 | reg4.5<<: >> 137 | reg4.3<<: break ; >> 138 | reg4.5<<: break ; >> 139 | reg4.3<<: } >> 140 | reg4.3<<: } >> 141 | reg4.3<<: else >> 142 | reg4.5<<: else >> 143 | reg4.1<<: >> 144 | reg4.2<<: >> 145 | reg4.3<<: >> 146 | reg4.4<<: >> 147 | reg4.5<<: >> 148 | reg4.1<<: >> 149 | reg4.2<<: >> 150 | reg4.3<<: >> 151 | reg4.4<<: >> 152 | reg4.5<<: >> 153 | 26..12: each array is of size A_HASH_PRIME. 154 | reg5.1<> 155 | 26..12: each array is of size A_HASH_PRIME. 156 | reg5.2<> 157 | 11..7: On the D_ANODE list, we use real deletion and move to the 158 | reg5.1<> 159 | 11..7: On the D_ANODE list, we use real deletion and move to the 160 | reg5.2<> 161 | 32..5: (1) d1 != d2, but sprintf(A_FMT,d1) == sprintf(A_FMT,d1) 162 | reg5.1<> 163 | 32..5: (1) d1 != d2, but sprintf(A_FMT,d1) == sprintf(A_FMT,d1) 164 | reg5.2<> 165 | 42..12:#define _dhash(d) (((int)(d)&0x7fff)%A_HASH_PRIME) 166 | reg5.1<> 167 | 42..12:#define _dhash(d) (((int)(d)&0x7fff)%A_HASH_PRIME) 168 | reg5.2<> 169 | 34..6:#define _dhash(d) (((int)(d)&0x7fff)%A_HASH_PRIME) 170 | reg5.3<<0x7fff>> 171 | 27..12: unsigned h = hash(s) % A_HASH_PRIME ; 172 | reg5.1<> 173 | 27..12: unsigned h = hash(s) % A_HASH_PRIME ; 174 | reg5.2<> 175 | 22..8: p->cp->type = C_NOINIT ; 176 | reg5.1<> 177 | 22..8: p->cp->type = C_NOINIT ; 178 | reg5.2<> 179 | 11..7:/* on the D_ANODE list, when we find a node we move it 180 | reg5.1<> 181 | 11..7:/* on the D_ANODE list, when we find a node we move it 182 | reg5.2<> 183 | 8..7:static D_ANODE *find_by_dval(A, d, cflag) 184 | reg5.1<> 185 | 8..7:static D_ANODE *find_by_dval(A, d, cflag) 186 | reg5.2<> 187 | 12..7: register D_ANODE *p = A[h].dlink ; 188 | reg5.1<> 189 | 12..7: register D_ANODE *p = A[h].dlink ; 190 | reg5.2<> 191 | 3..7: D_ANODE *q = 0 ; /* trails p for move to front */ 192 | reg5.1<> 193 | 3..7: D_ANODE *q = 0 ; /* trails p for move to front */ 194 | reg5.2<> 195 | 28..7: zfree(p, sizeof(D_ANODE)) ; 196 | reg5.1<> 197 | 28..7: zfree(p, sizeof(D_ANODE)) ; 198 | reg5.2<> 199 | 1..1:extern unsigned hash() ; 200 | reg6.2<> 201 | 23..6: which is two hash tables in one. One for strings 202 | reg6.1<> 203 | 23..2: which is two hash tables in one. One for strings 204 | reg6.3<> 205 | 19..5: and one for doubles. 206 | reg6.4<> 207 | 1 aFOOc 208 | 4 XaXbXcX 209 | 3 XaXcX 210 | 1 abX 211 | 1 abX 212 | 1 abcX 213 | 2 aXcX 214 | 1 aFOOc 215 | 4 XaXbXcX 216 | 3 XaXcX 217 | 1 abX 218 | 1 abX 219 | 1 abcX 220 | 1 a(b)c 221 | 4 {}a{}b{}c{} 222 | 3 {}a{b}c{} 223 | 3 {}a{bb}c{b} 224 | 2 a(bb)c(b) 225 | 1 a b c 226 | 1 a b c 227 | -------------------------------------------------------------------------------- /test/reg0.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg0.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | /return/ {cnt++} 14 | END{print cnt} 15 | -------------------------------------------------------------------------------- /test/reg1.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg1.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | /return|switch/ {cnt++} 14 | END{print cnt} 15 | -------------------------------------------------------------------------------- /test/reg2.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg2.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | /[A-Za-z_][A-Za-z0-9_]*\[.*\][ \t]*=/ {cnt++} 14 | END{print cnt} 15 | -------------------------------------------------------------------------------- /test/reg3.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg3.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2010, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN { 13 | test = "MFG" 14 | match(test, "[^0-9A-Za-z]") 15 | print RSTART, RLENGTH 16 | } 17 | -------------------------------------------------------------------------------- /test/reg4.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg4.awk,v 1.9 2016/09/05 17:06:35 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2009,2016 Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | { 13 | if ($0 ~/^[-+()0-9.,$%\/'"]*$/) 14 | { 15 | print ("reg4.1<<:",$0,">>") 16 | } 17 | if ($0 ~/^[]+()0-9.,$%\/'"-]*$/) 18 | { 19 | print ("reg4.2<<:",$0,">>") 20 | } 21 | if ($0 ~/^[^]+()0-9.,$%\/'"-]*$/) 22 | { 23 | print ("reg4.3<<:",$0,">>") 24 | } 25 | if ($0 ~/^[[+(){}0-9.,$%\/'"-]*$/) 26 | { 27 | print ("reg4.4<<:",$0,">>") 28 | } 29 | if ($0 ~/^[^[+(){}0-9.,$%\/'"-]*$/) 30 | { 31 | print ("reg4.5<<:",$0,">>") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/reg5.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg5.awk,v 1.3 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2009, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN { 13 | pat1="([[:upper:][:digit:]])+(_[[:upper:][:digit:]]+)+" 14 | pat2="0x[[:xdigit:]]+" 15 | } 16 | { 17 | if ($0 ~ /[^[:alnum:]]([[:upper:][:digit:]])+(_[[:upper:][:digit:]]+)+[^[:alnum:]]/) 18 | { 19 | match($0,pat1) 20 | printf "%d..%d:%s\n", RSTART, RLENGTH, $0 21 | printf ("reg5.1<<%s>>\n",substr($0,RSTART,RLENGTH)) 22 | } 23 | if ($0 ~ pat1 ) 24 | { 25 | match($0,pat1) 26 | printf "%d..%d:%s\n", RSTART, RLENGTH, $0 27 | printf ("reg5.2<<%s>>\n",substr($0,RSTART,RLENGTH)) 28 | } 29 | if ($0 ~ pat2 ) 30 | { 31 | match($0,pat2) 32 | printf "%d..%d:%s\n", RSTART, RLENGTH, $0 33 | printf ("reg5.3<<%s>>\n",substr($0,RSTART,RLENGTH)) 34 | } 35 | # add patterns like those in reg4.awk which exercise [, ] at beginning 36 | } 37 | -------------------------------------------------------------------------------- /test/reg6.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg6.awk,v 1.3 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2010, Jonathan Nieder 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN { 13 | patterns = "(a?)+bles /(^)+e/a(a?)*b/(a?)+*bles\\." 14 | n = split(patterns, pattern, "/") 15 | } 16 | { 17 | for (i = 1; i <= n; i++) { 18 | if ($0 ~ pattern[i]) { 19 | match($0, pattern[i]) 20 | printf "%d..%d:%s\n", RSTART, RLENGTH, $0 21 | printf "reg6.%d<<%s>>\n", i, substr($0,RSTART,RLENGTH) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/reg7.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: reg7.awk,v 1.1 2014/08/20 20:00:15 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2014, Thomas E. Dickey 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | BEGIN { 13 | str = "abc"; print gsub("b+", "FOO", str), str 14 | str = "abc"; print gsub("x*", "X", str), str 15 | str = "abc"; print gsub("b*", "X", str), str 16 | str = "abc"; print gsub("c", "X", str), str 17 | str = "abc"; print gsub("c+", "X", str), str 18 | str = "abc"; print gsub("x*$", "X", str), str 19 | str = "abc"; print gsub("b|$", "X", str), str 20 | str = "abc"; print gsub("b+", "FOO", str), str 21 | str = "abc"; print gsub("x*", "X", str), str 22 | str = "abc"; print gsub("b*", "X", str), str 23 | str = "abc"; print gsub("c", "X", str), str 24 | str = "abc"; print gsub("c+", "X", str), str 25 | str = "abc"; print gsub("x*$", "X", str), str 26 | str = "abc"; print gsub("b+", "(&)", str), str 27 | str = "abc"; print gsub("x*", "{&}", str), str 28 | str = "abc"; print gsub("b*", "{&}", str), str 29 | str = "abbcb"; print gsub("b*", "{&}", str), str 30 | str = "abbcb"; print gsub("b+", "(&)", str), str 31 | str = "a b c"; print gsub(/^[ ]*/, "", str), str 32 | str = " a b c"; print gsub(/^[ ]*/, "", str), str 33 | } 34 | -------------------------------------------------------------------------------- /test/repetitions.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: repetitions.awk,v 1.3 2020/07/25 14:55:28 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 2016, jlp765 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | /b{,1}/ 13 | /ab{1,3}c/ 14 | /^ab{1,}c/ 15 | /ab{1,}c/ 16 | /ab{1}c/ 17 | /ab{2,3}c/ 18 | /a(b){2}c/ 19 | /a(b{2})c/ 20 | /ab{2}c/ 21 | /(ab){2,}c/ 22 | /ab{2,}c/ 23 | /ab{3}c/ 24 | /ab{3,5}c/ 25 | /(abb){1,}/ 26 | /b{1,}/ 27 | /b{2,}c/ 28 | /(b){2,}c/ 29 | /b{6,}c/ 30 | /b{7,}c/ 31 | /(bb){1,}c/ 32 | /(bb){1}c/ 33 | /bb{1}c/ 34 | /(bb){2,}c/ 35 | /(bb){2}c/ 36 | /bb{2}c/ 37 | /(bbb){1,}/ 38 | /(qwerty){4}/ 39 | /(qwerty){5}/ 40 | /(wabxcz){220}w/ 41 | /(wabxcz){220}/ 42 | /(wabxcz){221}/ 43 | /wabxcz{219}w/ 44 | -------------------------------------------------------------------------------- /test/repetitions.dat: -------------------------------------------------------------------------------- 1 | abc 2 | ac 3 | abbc 4 | bbbbbbc 5 | bbcab 6 | cabac 7 | cababac 8 | cababc 9 | cabc 10 | xyz 11 | wabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxcz 12 | qwertyqwertyqwertyqwerty 13 | -------------------------------------------------------------------------------- /test/repetitions.out: -------------------------------------------------------------------------------- 1 | abc 2 | abc 3 | abc 4 | abc 5 | abc 6 | abc 7 | ac 8 | abbc 9 | abbc 10 | abbc 11 | abbc 12 | abbc 13 | abbc 14 | abbc 15 | abbc 16 | abbc 17 | abbc 18 | abbc 19 | abbc 20 | abbc 21 | abbc 22 | abbc 23 | abbc 24 | bbbbbbc 25 | bbbbbbc 26 | bbbbbbc 27 | bbbbbbc 28 | bbbbbbc 29 | bbbbbbc 30 | bbbbbbc 31 | bbbbbbc 32 | bbbbbbc 33 | bbbbbbc 34 | bbbbbbc 35 | bbbbbbc 36 | bbcab 37 | bbcab 38 | bbcab 39 | bbcab 40 | bbcab 41 | bbcab 42 | bbcab 43 | cabac 44 | cabac 45 | cababac 46 | cababac 47 | cababc 48 | cababc 49 | cababc 50 | cababc 51 | cababc 52 | cababc 53 | cabc 54 | cabc 55 | cabc 56 | cabc 57 | cabc 58 | xyz 59 | wabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxcz 60 | wabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxcz 61 | wabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxczwabxcz 62 | qwertyqwertyqwertyqwerty 63 | qwertyqwertyqwertyqwerty 64 | -------------------------------------------------------------------------------- /test/wc-awk.out: -------------------------------------------------------------------------------- 1 | 107 479 2 | -------------------------------------------------------------------------------- /test/wc.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: wc.awk,v 1.2 2010/12/10 17:00:00 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | {sum += NF} 14 | END{ print NR, sum} 15 | -------------------------------------------------------------------------------- /test/wfrq-awk.out: -------------------------------------------------------------------------------- 1 | 29 p 2 | 21 A 3 | 14 ANODE 4 | 13 q 5 | 12 d 6 | 12 sval 7 | 10 if 8 | 10 the 9 | 8 dlink 10 | 8 h 11 | 8 is 12 | 7 to 13 | 6 D 14 | 6 of 15 | 5 cflag 16 | 5 deleted 17 | 5 else 18 | 5 front 19 | 5 hash 20 | 5 link 21 | -------------------------------------------------------------------------------- /test/wfrq0.awk: -------------------------------------------------------------------------------- 1 | # $MawkId: wfrq0.awk,v 1.3 2020/01/20 11:52:06 tom Exp $ 2 | # Test-script for MAWK 3 | ############################################################################### 4 | # copyright 1993, Michael D. Brennan 5 | # 6 | # This is a source file for mawk, an implementation of 7 | # the AWK programming language. 8 | # 9 | # Mawk is distributed without warranty under the terms of 10 | # the GNU General Public License, version 2, 1991. 11 | ############################################################################### 12 | 13 | # this program finds the twenty most frequent 14 | # words in document using a heap sort at the end 15 | # 16 | # 17 | 18 | function down_heap(i, k,hold) 19 | { 20 | while ( 1 ) 21 | { 22 | if ( compare(heap[2*i], heap[2*i+1]) <= 0 ) k = 2*i 23 | else k = 2*i + 1 24 | 25 | if ( compare(heap[i],heap[k]) <= 0 ) return 26 | 27 | hold = heap[k] ; heap[k] = heap[i] ; heap[i] = hold 28 | i = k 29 | } 30 | } 31 | 32 | # compares two values of form "number word" 33 | # by number and breaks ties by word (reversed) 34 | 35 | function compare(s1, s2, t, X) 36 | { 37 | t = (s1+0) - (s2+0) # forces types to number 38 | 39 | if ( t == 0 ) 40 | { 41 | split(s1, X); s1 = X[2] 42 | split(s2, X); s2 = X[2] 43 | if ( s2 < s1 ) return -1 44 | return s1 < s2 45 | } 46 | 47 | return t 48 | } 49 | 50 | 51 | BEGIN { RS = "[^a-zA-Z]+" ; BIG = "999999:" } 52 | 53 | { cnt[$0]++ } 54 | 55 | END { delete cnt[ "" ] 56 | 57 | # load twenty values 58 | j = 1 59 | for( i in cnt ) 60 | { 61 | heap[j] = num_word( cnt[i] , i ) 62 | delete cnt[i] ; 63 | if ( ++j == 21 ) break ; 64 | } 65 | 66 | # make some sentinels 67 | for( i = j ; i < 43 ; i++ ) heap[i] = BIG 68 | 69 | h_empty = j # save the first empty slot 70 | # make a heap with the smallest in slot 1 71 | for( i = h_empty - 1 ; i > 0 ; i-- ) down_heap(i) 72 | 73 | # examine the rest of the values 74 | for ( i in cnt ) 75 | { 76 | j = num_word(cnt[i], i) 77 | if ( compare(j, heap[1]) > 0 ) 78 | { # its bigger 79 | # take the smallest out of the heap and readjust 80 | heap[1] = j 81 | down_heap(1) 82 | } 83 | } 84 | 85 | h_empty-- ; 86 | 87 | # what's left are the twenty largest 88 | # smallest at the top 89 | # 90 | 91 | i = 20 92 | while ( h_empty > 1 ) 93 | { 94 | buffer[i--] = heap[1] 95 | heap[1] = heap[h_empty] 96 | heap[h_empty] = BIG 97 | down_heap(1) 98 | h_empty-- 99 | } 100 | buffer[i--] = heap[1] 101 | 102 | for(j = 1 ; j <= 20 ; j++ ) print buffer[j] 103 | } 104 | 105 | 106 | function num_word(num, word) 107 | { 108 | return sprintf("%3d %s", num, word) 109 | } 110 | -------------------------------------------------------------------------------- /types.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | types.h 3 | copyright 2009-2023,2024 Thomas E. Dickey 4 | copyright 1991-1993,2014 Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: types.h,v 1.16 2024/08/25 19:36:05 tom Exp $ 15 | */ 16 | 17 | /* types.h */ 18 | 19 | #ifndef MAWK_TYPES_H 20 | #define MAWK_TYPES_H 21 | 22 | #include 23 | #include 24 | 25 | /* CELL types */ 26 | 27 | typedef enum { 28 | C_NOINIT 29 | ,C_DOUBLE 30 | ,C_STRING 31 | ,C_STRNUM 32 | ,C_MBSTRN /*could be STRNUM, has not been checked */ 33 | ,C_RE 34 | ,C_SPACE /* split on space */ 35 | ,C_SNULL /* split on the empty string */ 36 | ,C_REPL /* a replacement string '\&' changed to & */ 37 | ,C_REPLV /* a vector replacement -- broken on & */ 38 | ,NUM_CELL_TYPES 39 | } MAWK_CELL_TYPES; 40 | 41 | /* these defines are used to check types for two 42 | CELLs which are adjacent in memory */ 43 | 44 | #define TWO_NOINITS (2*(1< 18 | #include 19 | #include 20 | 21 | #define VERSION_STRING \ 22 | "mawk %d.%d%s %s\n\ 23 | Copyright 2008-2024,2025, Thomas E. Dickey\n\ 24 | Copyright 1991-1996,2014, Michael D. Brennan\n\n" 25 | 26 | #define FMT_N "%-20s%.0f\n" 27 | #define FMT_S "%-20s%s\n" 28 | 29 | /* print VERSION and exit */ 30 | void 31 | print_version(FILE *fp) 32 | { 33 | fprintf(fp, VERSION_STRING, PATCH_BASE, PATCH_LEVEL, PATCH_STRING, DATE_STRING); 34 | fflush(fp); 35 | 36 | #define SHOW_RANDOM "random-funcs:" 37 | #if defined(NAME_RANDOM) 38 | fprintf(fp, FMT_S, SHOW_RANDOM, NAME_RANDOM); 39 | #else 40 | fprintf(fp, FMT_S, SHOW_RANDOM, "internal"); 41 | #endif 42 | 43 | #define SHOW_REGEXP "regex-funcs:" 44 | #ifdef LOCAL_REGEXP 45 | fprintf(fp, FMT_S, SHOW_REGEXP, "internal"); 46 | #else 47 | fprintf(fp, FMT_S, SHOW_REGEXP, "external"); 48 | #endif 49 | 50 | fprintf(fp, "\ncompiled limits:\n"); 51 | fprintf(fp, FMT_N, "sprintf buffer", (double) SPRINTF_LIMIT); 52 | fprintf(fp, FMT_N, "maximum-integer", (double) MAX__INT); 53 | #if defined(VERBOSE_VERSION) 54 | /* we could show these, but for less benefit: */ 55 | fprintf(fp, FMT_N, "maximum-unsigned", (double) MAX__UINT); 56 | fprintf(fp, FMT_N, "maximum-long", (double) MAX__LONG); 57 | fprintf(fp, "\nactual limits:\n"); 58 | fprintf(fp, FMT_N, "sprintf buffer", (double) (sprintf_limit - sprintf_buff)); 59 | #endif 60 | mawk_exit(0); 61 | } 62 | -------------------------------------------------------------------------------- /vs6.mak: -------------------------------------------------------------------------------- 1 | # $MawkId: vs6.mak,v 1.3 2012/10/27 10:55:58 tom Exp $ 2 | # Microsoft C makefile for mawk, 3 | # 4 | # Tested with Microsoft Visual Studio 6 using nmake. 5 | ############################################################################### 6 | # copyright 2010,2012 Thomas E. Dickey 7 | # 8 | # This is a source file for mawk, an implementation of 9 | # the AWK programming language. 10 | # 11 | # Mawk is distributed without warranty under the terms of 12 | # the GNU General Public License, version 2, 1991. 13 | ############################################################################### 14 | 15 | !include 16 | 17 | #======================================================================== 18 | 19 | CFLAGS = -I. -DLOCAL_REGEXP $(cflags) 20 | 21 | .c.obj: 22 | $(CC) $(CFLAGS) -c $< 23 | 24 | OBJ1 = parse.obj array.obj bi_funct.obj bi_vars.obj cast.obj code.obj \ 25 | da.obj error.obj execute.obj fcall.obj 26 | 27 | OBJ2 = field.obj files.obj fin.obj hash.obj jmp.obj init.obj \ 28 | kw.obj main.obj matherr.obj 29 | 30 | OBJ3 = memory.obj print.obj re_cmpl.obj scan.obj scancode.obj split.obj \ 31 | zmalloc.obj version.obj regexp.obj dosexec.obj 32 | 33 | MAWK_OBJ = $(OBJ1) $(OBJ2) $(OBJ3) 34 | 35 | mawk.exe : $(MAWK_OBJ) 36 | $(link) $(LDFLAGS) $(MAWK_OBJ) $(LIBS) -out:mawk.exe -map:mawk.map 37 | 38 | config.h : msdos/vs6.h 39 | copy msdos\vs6.h config.h 40 | 41 | dosexec.c : msdos/dosexec.c 42 | copy msdos\dosexec.c dosexec.c 43 | 44 | mawk_test : mawk.exe # test that we have a sane mawk 45 | @echo you may have to run the test manually 46 | cd test && mawktest.bat 47 | 48 | fpe_test : mawk.exe # test FPEs are handled OK 49 | @echo testing floating point exception handling 50 | @echo you may have to run the test manually 51 | cd test && fpe_test.bat 52 | 53 | check : mawk_test fpe_test 54 | 55 | ################################################### 56 | # FIXME 57 | # parse.c is provided 58 | # so you don't need to make it. 59 | # 60 | # But if you do: here's how: 61 | # To make it with byacc 62 | # YACC=byacc 63 | # parse.c : parse.y 64 | # $(YACC) -d parse.y 65 | # rename y_tab.h parse.h 66 | # rename y_tab.c parse.c 67 | ######################################## 68 | 69 | scancode.c : makescan.c scan.h 70 | $(CC) -o makescan.exe makescan.c 71 | makescan.exe > scancode.c 72 | del makescan.exe 73 | 74 | clean : 75 | -del *.bak 76 | -del *.exe 77 | -del *.ilk 78 | -del *.map 79 | -del *.pdb 80 | -del *.obj 81 | 82 | distclean : clean 83 | -del dosexec.c 84 | -del scancode.c 85 | -del config.h 86 | 87 | # dependencies of .objs on .h 88 | array.obj : array.h bi_vars.h config.h field.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 89 | bi_funct.obj : array.h bi_funct.h bi_vars.h config.h field.h files.h fin.h init.h mawk.h memory.h nstd.h regexp.h repl.h sizes.h symtype.h types.h zmalloc.h 90 | bi_vars.obj : array.h bi_vars.h config.h field.h init.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 91 | cast.obj : array.h config.h field.h mawk.h memory.h nstd.h parse.h repl.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 92 | code.obj : array.h code.h config.h field.h init.h jmp.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 93 | da.obj : array.h bi_funct.h code.h config.h field.h mawk.h memory.h nstd.h repl.h sizes.h symtype.h types.h zmalloc.h 94 | error.obj : array.h bi_vars.h config.h mawk.h nstd.h parse.h scan.h scancode.h sizes.h symtype.h types.h 95 | execute.obj : array.h bi_funct.h bi_vars.h code.h config.h field.h fin.h mawk.h memory.h nstd.h regexp.h repl.h sizes.h symtype.h types.h zmalloc.h 96 | fcall.obj : array.h code.h config.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 97 | field.obj : array.h bi_vars.h config.h field.h init.h mawk.h memory.h nstd.h parse.h regexp.h repl.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 98 | files.obj : array.h config.h files.h fin.h init.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 99 | fin.obj : array.h bi_vars.h config.h field.h fin.h mawk.h memory.h nstd.h parse.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 100 | hash.obj : array.h config.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 101 | init.obj : array.h bi_vars.h code.h config.h field.h init.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 102 | jmp.obj : array.h code.h config.h init.h jmp.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 103 | kw.obj : array.h config.h init.h mawk.h nstd.h parse.h sizes.h symtype.h types.h 104 | main.obj : array.h code.h config.h files.h init.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 105 | makescan.obj : config.h nstd.h scancode.h 106 | matherr.obj : array.h config.h init.h mawk.h nstd.h sizes.h symtype.h types.h 107 | memory.obj : config.h mawk.h memory.h nstd.h sizes.h types.h zmalloc.h 108 | parse.obj : array.h bi_funct.h bi_vars.h code.h config.h field.h files.h jmp.h mawk.h memory.h nstd.h sizes.h symtype.h types.h zmalloc.h 109 | print.obj : array.h bi_funct.h bi_vars.h config.h field.h files.h mawk.h memory.h nstd.h parse.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 110 | re_cmpl.obj : array.h config.h mawk.h memory.h nstd.h parse.h regexp.h repl.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 111 | scan.obj : array.h code.h config.h field.h files.h fin.h init.h mawk.h memory.h nstd.h parse.h repl.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 112 | split.obj : array.h bi_funct.h bi_vars.h config.h field.h mawk.h memory.h nstd.h parse.h regexp.h repl.h scan.h scancode.h sizes.h symtype.h types.h zmalloc.h 113 | version.obj : array.h config.h init.h mawk.h nstd.h patchlev.h sizes.h symtype.h types.h 114 | zmalloc.obj : config.h mawk.h nstd.h sizes.h types.h zmalloc.h 115 | regexp.obj : rexpdb.c rexp4.c rexp2.c regexp_system.c sizes.h mawk.h rexp0.c rexp1.c config.h rexp.h regexp.h nstd.h rexp3.c rexp.c field.h 116 | -------------------------------------------------------------------------------- /zmalloc.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | zmalloc.h 3 | copyright 2009-2010,2023 Thomas E. Dickey 4 | copyright 1991,1993, Michael D. Brennan 5 | 6 | This is a source file for mawk, an implementation of 7 | the AWK programming language. 8 | 9 | Mawk is distributed without warranty under the terms of 10 | the GNU General Public License, version 2, 1991. 11 | ********************************************/ 12 | 13 | /* 14 | * $MawkId: zmalloc.h,v 1.8 2023/07/25 21:20:54 tom Exp $ 15 | */ 16 | 17 | #ifndef ZMALLOC_H 18 | #define ZMALLOC_H 19 | 20 | #include 21 | 22 | extern PTR zmalloc(size_t); 23 | extern void zfree(PTR, size_t); 24 | extern PTR zrealloc(PTR, size_t, size_t); 25 | 26 | #define ZMALLOC(type) ((type*)zmalloc(sizeof(type))) 27 | #define ZFREE(p) zfree(p,sizeof(*(p))) 28 | 29 | #endif /* ZMALLOC_H */ 30 | --------------------------------------------------------------------------------