Codebase list libmawk / b761e9e
New upstream version 1.0.0 Bdale Garbee 4 years ago
518 changed file(s) with 57054 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 Changelog for libmawk
1 ~~~~~~~~~~~~~~~~~~~~~
2 libmawk 1.0.0 (released: 2018-11-11, r1276)
3 [API] -Change: resume capable function call entries
4 [build] -Fix: make clean should remove custom C test objects and executables
5 [build] -Fix: incomplete install headers list
6 [build] -Add: Makefile variable for selecting zmalloc alternatives
7 [build] -Add: optional DESTDIR for debian
8 [build] -Add: --prefix, --debug, --symbols
9 [build] -Add: help
10 [build] -Chnage: upgrade to tmpasm and latest version of scconfig
11 [build] -Add: optional support for soname
12 [build] -Change: use $(MAKE) instead of make in central Makefiles for parallel build
13 [build] -Add: detect -rdynamic
14 [core] -Change: extend mpow2 for covering new celltypes
15 [core] -Cleanup: rename _STOP and _RANGE to _RANGE_STOP and _RANGE_CHK to make their purpose more clear
16 [core] -Fix: return read error in getline doesn't fall in infinite loop in fill buff anymore
17 [core] -Add: MAWK_MEM_PEDANTIC compile time option; when set, try to free all allocation instead of letting zmalloc catch them all
18 [core] -Fix: don't free the hash before freeing argv and others
19 [core] -Fix: make sure code blocks are free'd only once, but are really free'd
20 [core] -Fix: memory leak when initializing argv
21 [core] -Fix: let mawk_delete() free arrays, don't manually do that on argv
22 [core] -Change: let mawk_delete() free user function
23 [core] -Change: fin is under files - higher level code should do all access through the file infra
24 [core] -Fix: FIN is only about buffering, no open/close should go through that API
25 [core] -Fix: reference count vf structs since one vf might be open multiple times from FILE_NODEs (for input and output) and should be destroyed only once
26 [core] -Fix: closing all files, not only output files, is not a pedantic-mem feature - not doig it could lead to leaking fds and other resources even if zmalloc pools are freed centrally
27 [core] -Fix: there is only one way files are closed, only one code is needed
28 [core] -Fix: mawk_fill_buff returns a signed long for indicating temporary error (fixed for 64 bit)
29 [core] -Fix: rename state field userdata to func_userdata to make the purpose more clear
30 [core] -Add: ctx_userdata intended for the host app for storing whatever data, per context
31 [core] -Add: have a field in the state struct for the C function being called back so that subsequent execute()s may know about that
32 [core] -Fix: memory leak: free data of c function calls compiled into the code at uninit
33 [core] -Fix: C89 fixes (func-data ptr conv through union, don't use strcasemp(), strdup, snprintf, //, vararg macros)
34 [core] -Fix: wrong arg passed to isnan - cell instead fo double value
35 [core] -Fix: vio fclose survives if there's no close function available (double close?)
36 [doc] -Add: short desc about the vm
37 [doc] -Add: explain how execution/resume works
38 [doc] -Add: describe deep recursion
39 [doc] -Add: minimalistic install
40 [example_apps] -Add: blocking fifo test also tests bifunct getline in an user function
41 [example_apps] -Add: make sure to demonstrate how the code is suspended even in user functions
42 [example_apps] -Update: 15_call for the new function call API
43 [example_apps] -Add: example on run limit resume
44 [example_apps] -Add: central Makefile that runs all examples
45 [example_apps] -Add: call a c function from c using awk's func call (demonstrate that awk and c functions should not make any difference)
46 [example_apps] -Fix: hash_re won't init std pipes twice
47 [example_apps] -Fix: custom vio test sets up pipes correctly and closes the hass from the app's end of the deal at the end
48 [example_apps] -Add: better explanation of the c_func_call example and hook it in the all-test-chain
49 [libmawk] -Fix: C function call from execute with new function call conventions
50 [libmawk] -Fix: call_functionp increases sp before push else the stack pointer points to the wrong place
51 [libmawk] -Fix: restore sp on function call failure
52 [libmawk] -Fix: before closing stdio on awk side, close stdin on app side to make sure both ends can be closed
53 [libmawk] -Fix: do not leak function arguments already pushed on stack if an awk function call fails due to bad arguments
54 [libmawk] -Fix: allow c functions to be called using mawk_call_function*()
55 [libmawk] -Fix: don't close stdin if it's not open
56 [libmawk] -Fix: don't use strdup() for c function reg
57 [libmawk] -Fix: don't close non-fifo stdin as fifo
58 [libmawk] -Fix: priting uninitialized cell should work and should result in empty string
59 [libmawk] -Add: wants_to_exit flag so that a libmawk caller knows a script wants to exit
60 [libmawk] -Add: function call API with cell argc/argv
61 [parser] -Fix: really reset the parser stack when it gets freed - used to segfault for two includes on the topmost level
62 [parser] -Fix: allow excess newlines in the main context - this fixes a corner case around multiple includes
63 [regression] -Add: test for bifunct call()
64 [regression] -Add: test for acall() (dynamic call with array as argument)
65 [regression] -Add: test for stack grow on deep recursion
66 [regression] -Add: test program for awk function call corner cases
67 [regression] -Add: libmawk corner case test base
68 [regression] -Fix: libmawk func call test diag messages are more clear on what's wrong or good
69 [rexp] -Fix: infinite loop bug (gawk test noloop1 and noloop2) - contributed by Thomas E. Dickey as a mawk fix
70 [vio] -Fix: set eof flags on fifo creation (fixes a conditional jump on uninited var bug)
71 [vio] -Fix: closing FIN closes the vio layer even if fin buffer had not been initialized
72 [vio] -Fix: close vf throug FIN to make sure buffers are also freed
73 [vio] -Fix: simpler common header with refco and who-knows-what in the future
74 [vio] -Fix: initialize refco to 0
75 [vm] -Change: avoid recursive calls to execute() on plain hardwired awk function calls
76 [vm] -Change: wants_to_ret is execution state instead - need to remember whether we are running range1 or range2
77 [vm] -Fix: leak in function return value stack handling
78 [vm] -Add: new convention in bi_funct calling: return stack may be a directive for executing an user functioin (for bi_call and bi_acall)
79 [vm] -Fix: mawk_bi_call() and bifunct acall() follow the new no-recurse calling convention
80 [vm] -Add: new low level c->awk call functions trying to follow the no-recurse execute_() conventions
81 [vm] -Move: execute API into new execute.h
82 [vm] -Add: a separate execution exit status for exit()
83 [vm] -Add: execution run limit and resume
84 [vm] -Fix: bi_funct getline can indicate 'nomore' instead of eof
85 [vm] -Fix: properly save and restore old_stack_base and old_sp on stack danger (stack growth)
86 [vm] -Cleanup: remumber types (continous numbering)
87 [vm] -Add: more stack-related cell types and make room for future non-string additions
88 [vm] -Fix: compare() returns double so that nan-checks can be performed
89 [vm] -Fix: error return with value from execute()
90 [vm] -Fix: make MAWK->pow big enough and make it safe (need to be unsigned long for these values and for the bit ops)
91
92
93 libmawk 0.10.1 (released: 2014-07-11, r1056)
94 [compiler] -Fix: zero-offset bug in jmp push (xref test crash)
95 [build] -Add: make test should run the standard regression tests; do not run tests automatically on build
96 [core] -Add: zfifo: generic fifo implemented using zmalloc/zfree
97 [core] -Add: mawk_file_find() has a create flag that can disable creating a new file node - useful for forcing existing/open files
98 [core] -Cleanup: move fin struct to fin.h
99 [core] -Cleanup: rename FIN to mawk_input_t for naming consistency
100 [core] -Fix: rewritten mawk_FINgets - cleaner code that is non-blocking-safe
101 [core] -Fix: zrealloc() should not crash if old ptr is NULL
102 [core] -Fix: safer vf close, close outputs only in uninit, when EXIT has finished for sure
103 [vio] -Fix: input is always fd, output is always FILE *; remove fgets and stdin related API
104 [vio] -Clenaup: cleaner ways recognizing "/dev/std*"
105 [vio] -Add: support for /dev/fd/xxx (fdopen() wrapper)
106 [vio] -Add: an extra layer to dispatch vio calls - multiple vio implementations can coexist
107 [vio] -Add: virtualize vio init (non-per-file vio hooks); use MAWK->vio_init instead of hardwired vio_orig (so that vio_orig can be omitted)
108 [vio] -Del: setbuf from API - this callback was a hack, now all done by the call that sets up stdio
109 [vio] -Change: replace is_stdouts with a more generic mark_no_close hook
110 [vio] -Fix: use zmalloc/zfree for the mawk_vio_t allocations
111 [vio] -Add: a generic fifo implementation that also replaces the artificial FIN buf
112 [regression] -Cleanup: remove test/ and convert all shell script based tests to make-based tests in regression/
113 [tools] -Fix: find_globals uses the right dir
114 [tools] -Fix: sym prefix validator won't complain for main()
115 [API] -Add: file name validation hook
116 [API] -Add: call to register a file by name:type and vio handle in the high level list of files; also sets up input buffering as needed
117 [API] -Add: call to close the default input fifo (sending eof to the script)
118 [API] -Add: convenient stdio-init call for multi-staged init
119 [example_app] -Add: custom output pipe hack examples and update pipe in buffer fill examples with all possible corner cases
120 [example_app] -Add: file name validation and vio hook examples
121
122
123 libmawk 0.10.0 (released: 2014-06-26, r937)
124 Major changes in core, mostly for virtual arrays:
125 [array] -Add: introduce new VM instructions for all array-element-write operations and split the lvalue rule of the grammar; besides being new instructions, they do the same in the execution switch as before
126 [array] -Add: virtualize array operations
127 [array] -Add: virtual, per instance ENVIRON[] that copies environ[] upon the first access and affects exec()
128 [array] -Del: ST_ENV: ENVIRON[] is not a global special case anymore, just a builtin array with a different implementation
129 [core] -Fix: replace "short int type" and a bunch of C_ macros for cell type with a proper enum
130 [core] -Add: macro option for cell operators for speed
131 [core] -Fix: set ERRNO in fin after a read error
132 [core] -Cleanup: mawk_ prefix zmalloc, zfree, ZMALLOC, ZFREE and a lot of other constants and macros
133 [init] -Add: a flag for indicating that it is ok for initialize_argv() to end up without a script
134 [dump] -Fix: print the code of illegal instructions
135 [dump] -Add: da_text: use blank lines to separate blocks: functions, BEGIN, MAIN, END
136 [dump] -Change: da_text: after user functions, dump code in BEGIN-MAIN-END order - it is more intuitive this way
137 [dump] -Add: text dump includes a summary of the global symbol table
138 [dump] -Change: introduce -W dumpsym for dumping symbols independently of dumping code
139 [da_bin] -Fix: properly save/load C_SNULL and C_SPACE (special split argument types) to/from binary dump
140 API CHANGES affecting libmawk:
141 [core] -Clenaup: rename STRING to mawk_string_t
142 [core] -Clenaup: rename CELL to libmawk_cell_t
143 [core] -Change: use an union instead of dval in CELL, to make room for other data types
144 [core] -Add: new cell type C_ARR_REF (should be execute()-internal); an array reference by name and index (instead of pointer to a cell)
145 [API] -move parsing the script from init stage1 to stage2 to give the host app a chance to inject things into the context before any code is parsed
146 [API] -Change: get_var should return a read-only CELL - direct modification of the cell is a bad idea due to possible side effects required at write
147 [API] -Fix: libmawk_print_cell shall be called with the context (mawk_state_t) as any other call in the API
148 [API] -Change: new, easier-to-use c-func calling conventions and helpers
149 [array] -Cleanup: rename ARRAY to mawk_array_t
150 New libmawk API features:
151 [API] -Add: helper functions to return the numeric value of a cell
152 [API] -Add: an easy way to set a cell to empty
153 [API] -Add: high level array set_at calls and scalar set calls
154
155 libmawk 0.9.7 (released: 2014-05-17, r732)
156 Major code structure changes:
157 [vio] -Split: file/pipe open/close operations to virtual IO (vio)
158 [linux] -Add: initial linux kernel module effort (defunct yet)
159 [array] -Add: virtualized array access (except for write) with callback functions
160 [libmawk] -Split: lmawk-comp and lmawk-exec frames - most code is in common yet
161 [libmawk] -Add: MAWK_NO_FORK for configuring against system() and fork()
162 Code cleanup:
163 [da_bin] -Cleanup: compiler warnings around da_bin (binary script save/load)
164 [da_bin] -Split: da_bin and da_bin_helper: precompiled binary script load doesn't directly call read() but an user provided callback for virtualization
165 [da_bin] -Fix: array creation on binary load
166 [da_bin] -Fix: when resetting code base size for loading binary, use zmalloc for proper allocation size
167 [build] -Fix: Makefile cleanup for portability
168 [libmawk] -Fix: prefix NF, RS and other similar macro names with MAWK_ - they collide in the Linux kernel
169 [test_3rd] -Add: scripts for running optional 3rd party tests from vendor/ (for the gawk set, without much configuration or filtering)
170 [regex] -Change: error handling without setjmp/longjmp (return values and a bunch of checks)
171 [regex] -Fix: regex lib uses zmalloc memory allocation to ensure all memory is free'd after a context is destroyed
172 [regex] -Add: tiny test program to trigger almost all possible error conditions in the regex lib
173 [regex] -Fix: move runtime states of the regex lib in the mawk struct to make it reentrant
174 [regex] -Fix: bi_vars are part of the mawk struct because parallel scripts may have different values for the same variables or even modify them from script
175 More portable doubles (and numeric):
176 [numeric] -Add: use porty's math_wrap for log() to get rid of undeterministic fpe
177 [numeric] -Add: use PM math protection copied from libporty
178 [numeric] -Add: new builtin function isnan()
179 [numeric] -Fix: virtualize strtod int strtonum: on a real int-only platform (e.g. Linux kernel) there won't be strtod at all
180 Fixes of the core functionality:
181 [libmawk] -Fix: make sure runtime error exit code takes over in final_error_code
182 [bi_func] -Fix: substr for start indices less than 1 behave similar to how substr() handles length overruns (silently truncate) - gawk has the same behavior
183 [bi_func] -Fix: gsub() patch for the ^ bug
184 [io] -Fix: redirection conditions messed up in r349
185 [libmawk] -Fix: disable -v only when MAWK_NO_EXEC is set, and don't even consider MAWK_NO_COMP
186 [libmawk] -Fix: fin_exec should respect a MAWK exit request and not retry reading
187 [libmawk] -Fix: if FIN can not be open (invalid file name, nonexisting file), don't segfault but return error
188
189 libmawk 0.9.6 (missed)
190
191 libmawk 0.9.5 (released: 2012-10-13, r527)
192 [libmawk] -Add: memory usage accounting figures; -Wmaxmem=size sets maximum
193 memory allocation in bytes (optional suffixes: k and m)
194 [libmawk] -Add: binary save/load functionality (-Wcompile and -b)
195 works on 32 bit systems only (will be fixed later)
196 [libmawk] -Change: replace hardwired double references with generin numeric
197 (C_NUM, num_t) - libmawk can be configured to use int or
198 double as numeric format (./configure --numeric=)
199 [libmawk] -Cleanup: (portability tweak) const correctness in mawk_reverse_find
200 [libmawk] -Add: (portability tweak) _POSIX_SOURCE
201 [libmawk] -Fix: (portability tweak) explicit rules for rexp/*.o incuding
202 $(CC) command line for old fashioned make having the wrong
203 implicit rule
204 [libmawk] -Cleanup: (portability tweak) k&r style function
205 declarations/definitions removed from rexp lib
206 [libmawk] -Fix: (portability tweak) missing prototypes to avoid implicit
207 declaration warning
208 [libmawk] -Change: disable two zfree() calls that would free main code to
209 avoid double frees
210 [libmawk] -Add: compile with app clfags
211 [libmawk] -Cleanup: move scconfig'd -D options to conf.h from Makefile.conf
212 to make compiler command lines shorter
213 [libmawk] -Cleanup: new vars.[ch] for collecting variable-related code
214 [libmawk] -Fix: mawk_mm (aka free_later) mechanism memory handling erros
215 when realloc()'d
216 [doc] -Add: explain design decisions behind our two gnu-dependencies
217 [doc] -Add: portability table (per system: compiles out of the box, has
218 FPE problems, awklib test ran fine)
219
220 libmawk 0.9.4 (released: 2010-12-26, r392)
221 [scconfig] -Add: detect pipe(2) and set NO_PIPE, replacing HAVE_REAL_PIPES
222 [scconfig] -Add: detect size_t include file (removes the ifdef mess)
223 [scconfig] -Add: require detection of cc/fpic (fixes compilation on amd64)
224 [libmawk] -Cleanup: del PROTO() macro: libmawk requires at least C89 compiler
225 [libmawk] -Cleanup: remove revision history and file name comments from *.[ch]
226 copyright notice above all mawk copyright notices
227 [libmawk] -Cleanup: version to clearly indicate that this is lmawk
228 [libmawk] -Cleanup: unified indentation in all .c and .h files
229 [libmawk] -Cleanup: remove a lot of compiler warnings, fix const correctness
230 [libmawk] -Cleanup: Makefile.dep generation rule; proper, up-to-date Makefile.dep
231 [libmawk] -Del: remove FAKE_PIPES support (was only for DOS anyway)
232 [libmawk] -Del: void * is a must, PTR should not fall back to char *
233 [libmawk] -Del: cut out MSDOS support with all its "dreaded segment nonsense"
234 [libmawk] -Fix: get bison to generate a reentrant parser
235 [libmawk] -Fix: move static globals to mawk state struct
236 [libmawk] -Fix: memory leaks
237
238
239 libmawk 0.9.3 (released: 2010-12-21, r307)
240 [libmawk] -Fix: use -fPIC for compiling (helps on amd64)
241 [libmawk] -Add: new builtin variable ERRNO with a different error code for each corner case in extension calls
242 [libmawk] -Add: new built-in variable LIBPATH for library search path
243 - skip loading a script if name started with '+' and the script was already loaded
244 - if script file name starts with '/', assume it to be an absolute path and skip LIBPATH search
245 [scconfig] -Add: scconfig configures/generates Makefiles of libmawk after autodetecting system features
246 [scconfig] -Del: config-user, v7, atarist: scconfig should take care of all supported systems
247 [scconfig] -Add: central ./configure and Makefile
248 [libmawk] -Fix: order of running BEGINs with "include"
249 [libmawk] -Fix: memory leaks around parser state
250 [awklib] -Add: three awk libraries:
251 - lib_rand for reproducible pseudo random numbers
252 - lib_array for packing/unpacking/printing arrays
253 - lib_ascii for converting characters to ASCII codes
254
255
256 libmawk 0.9.2 (released: 2010-12-12, r229)
257 [libmawk] -Fix: invalid memory handling around cells
258 [libmawk] -Fix: manual page dates and author and project/executable name
259 [libmawk] -Add: dynamic awk function calls (call() and acall())
260 [libmawk] -Add: dynamic awk variable value fetch (valueof())
261 [libmawk] -Add: include
262
263 libmawk 0.9.1 (released: 2009-08-14, r198)
264 [API] -Add: remember userdata when registering and calling back c functions
265 [API] -Add: option to suppress undefined function calls
266 [API] -Add: new call allowing awk function calls without varargs
267 [API] -Change: split up libmawk_initialize in 3 stages (optional)
268 [libmawk] -Del: autotools, keep last generated Makefile for hand editing
269 [libmawk] -Del: config.h (merged in Makefile.conf.in)
270 [libmawk] -Rename: mawk -> lmawk (the binary)
271 [libmawk] -Change: print cell prints integers without .000000
272 [testapp] -Move: testapp out from libmawk (new dir structure)
273 [testapp] -Fix: stack handling bug
274 [doc] -Add: manual pages for libmawk calls
275
276 libmawk 0.9.0 (released: 2009-07-22, r146)
277 * Initial release, based on mawk 1.3.3
278 * r3...r8 Separate libmawk_call() from execute(); allow undefined functions
279 * r9...r42 globals to struct (reentrant)
280 * r43...r92 rename non-static functions to have a mawk_ prefix
281 * r92...r145 libmawk
282
0 all: src/libmawk/Makefile.conf
1 cd src && $(MAKE)
2
3 install: src/libmawk/Makefile.conf
4 cd src && $(MAKE) install
5 cd doc && $(MAKE) install
6
7 uninstall:
8 cd src && $(MAKE) uninstall
9
10 linstall: src/libmawk/Makefile.conf
11 cd src && $(MAKE) linstall
12
13 clean:
14 cd src && $(MAKE) clean
15
16 distclean:
17 cd src && $(MAKE) distclean
18 cd scconfig && $(MAKE) clean
19
20 test:
21 cd src && $(MAKE) test
22
23 src/libmawk/Makefile.conf:
24 @echo "Please run ./configure first."; false
0 1. Introduction
1
2 Libmawk is a fork of mawk 1.3.3, restructured for embedding. This means the
3 user gets libmawk.h and libmawk.so and can embed awk scripting language
4 in any application written in C. For more information, check out the web page
5 at http://repo.hu/projects/libmawk and the documentation in doc/.
6
7 2. Requirements and compiling
8
9 ANSI C compiler, POSIX shell and make are required for compiling libmawk.
10 Bison should be installed for developing libmawk; if it is not installed,
11 local changes to the grammar will be ingored.
12
13 ./configure; make
14
15 On top of usual scconfig arguments, ./configure accepts --numeric=TYPE,
16 where TYPE is int or double. Default is double. This switch affects
17 what type libmawk stores numbers in.
18
19 3. installation
20
21 Run "make install" or "make linstall". The linstall version
22 will use symlinks instead of actual copying of files which is useful if
23 you develop libmawk, the library itself.
24
25 Debian package can be installed from http://repo.hu/debian.
26
27 4. Compatibility with mawk
28
29 Compatibility with mawk is maintained to some degree. Currently libmawk
30 offers a small set of extra features on awk level while providing
31 everything that mawk provides. A valid mawk script will work with
32 libmawk/lmawk without modification. However, the new features will work
33 only with libmawk/lmawk and not mawk, so portable scripts shouldn't
34 depend on them. All extensions are clearly marked in the manual.
35
36 Conclusion: libmawk will compile and install mawk executable, which is
37 backward compatible with mawk executable but also adds some extension
38 features.
39
40 Awklib depends on one of the libmawk features (include), thus awklib
41 scripts won't work with other awk implementations without tweaking.
0 Release notes for libmawk 1.0.0
1
2 This release introduces runlimits, better floating point handling on
3 corner cases (i.e. NaN) and memory leak cleanups.
4
0 #!/bin/sh
1 cd scconfig && make && ./configure "$@"
2
0 all:
1
2 include ../src/libmawk/Makefile.conf
3
4 install:
5 $(MKDIR) $(DOCDIR)
6 $(CP) $(PWD)/*.html $(DOCDIR)
0 1. update the changelog
1 2. update the release notes
2 3. change the version number in src/scconfig/hooks.c
3 4. test a fresh checkout
4 5. svn tag
0 000. full doc rewrite
1
2 Features:
3 - c->awk func call should be able to pass arrays
4
5 00. vio rewrite
6 - add all vio in a linked list in MAWK for garbage collection at mawk_uninit
7 - add a force-clenup hook for this; but also replace mawk_close_out_pipes()
8 - hooks? wrapper?
9 - document file_name_rewrite
10 - document vio
11
12 0. bugs
13 - string ref crash:
14 for(n = 0; n < 1000000; n++) A[n] = "foo"
15 if refcount of "foo" reaches 65535, it crashes
16 - mpow2 should be static
17
18 1. restrictions
19 - detect and use LDFLAGS -dynamic
20 - split compile and run into separate libs:
21 - implement a Single Safe number->string converter;
22 grep for OFMT and CONVFMT and INT_FMT to find all the buggy sprintf based
23 implementations
24 - split da_bin to exec and comp
25 - fix error.c: it shouldn't depend on stdio.h and it shouldn't print
26 to stderr anyway (incompatible with the lib idea)
27 - check whether int-compiled lmawk handles OFMT/CONVFMT properly
28 - floating point:
29 - try to find a platform with FPE for overflow and test
30 - consider a -W nandebug option so that the user knows where the script
31 went wrong; but he could also just check from the script
32 - if isinf() is avaialable, check for inf() result and convert them to nan
33
34
35 1.5.
36 - check all zmalloc() and zrealloc() calls - they may return NULL and callers
37 should return in that case so that runtime error takes over
38
39 2. porting
40 - test on UNIX
41 - provide a real alternative to realpath()
42
43 3.0 extend arrays
44 - array copy
45 - array in array (for orig implementation only?)
46 - length(array) as in gawk? POSIX: length() works on strings only
47 update test_3rd funlen accordingly!
48
49 3.1 features, minor bugs
50 - debugging (gdb scripts); location-file instruction to track src file changes
51 - consider printf with no arg to work like in gawk; also check posix about this
52 test_3rd: printf0
53 - decide whether regex "^+" (and "^*"?) should be accepted and treated as
54 plain + and * at the beginning of the string; update test_3rd reindops
55 (check posix regex)
56 - decide whether regex should support binary; related tests to update:
57 test_3rd jared, regx8bit
58 - posix FS point 3. requires that ^ work in FS; check test_3rd uparrfs
59 - introduce a new symtab flag for remembering builtin vars and arrays;
60 when -W dumpsym, do not dump these unless verbose
61 - introduce a -W dumpallsym (for verbose symdumps)
62 - write regression test for flush() (it used to pass the wrong pointer)
63
64 4. lib fineprint
65 - expose mawk_append_input_file
66
67 5. optimization
68 - mawk_find_bi_ptr(): use perfect hash instead of linear search
69 does it really matter?
70 - peephole:
71 - 'print "a", a, "b", b, "c", c' results in push/cat pairs;
72 make the parser emit a lot of pushes and replace cat with catN
73 - 'expr = 1' will add a pop; there should be another type of assignment
74 that doesn't push anything
75 - replace tail recursion (call+ret)
76
0 <HTML>
1 <BODY>
2 <H1> Why not using autotools </H1>
3 <P>
4 I believe autotools is the wrong designed and poor implementation, partly
5 trying to solve the wrong problem. The fix for this is a better design.
6 For example scconfig - which is the system that configures libmawk. It
7 can do everything it needs to do (yes, including cross compilation).
8 <P>
9 Mawk generally dosn't require too many special things and should compile
10 fine on POSIX systems. If it doesn't compile for you, you have the following
11 choices:
12 <OL>
13 <LI> you can contact me, report bugs, so I can fix scconfig
14 <LI> you can bypass scconfig and manually create Makefile.conf
15 and conf.h for your system yourself (won't help much in
16 fixing scconfig, tho)
17 <LI> you can create and maintain your own autotools version (but official
18 libmawk will not include support for autotools)
19 </OL>
20 </BODY>
21 </HTML>
0 This directory hosts documentation about libmawk internals.
1
2 These files are useful for developers of libmawk and in some specail
3 case for application developers if they plan to use advanced features
4 of libmawk.
5
0 API: Virtual array vs. function
1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
3 1. Introduction: virtual arrays
4
5 Libmawk implements support for virtual arrays: arrays that do not simply
6 store data in a hash. This feature is designed for maximal flexibility:
7 awk arrays have a set of hooks (function pointers) and whenever the
8 bytecode interpreter has to read, list or modify an array, it will
9 call the hook functions. The original array implementation is just
10 a set of hooks simply storing data without side effects. The ENVIRON[]
11 array is set up with another set of hooks that syncs the environment
12 with awk array (and calls the original hooks for the actual data storage).
13
14
15 2. API: arrays are function calls at the end of the day
16
17 This also means that an application developer has two alternative paths
18 to provide bindings to the application code:
19 - explicit function calls
20 - implicit function calls through an awk array
21
22 For example if the application wants to expose direct I/O port access,
23 it may:
24 - implement functions io_out(port, value) and io_in(port)
25 - implement an array IO[port]
26
27 However, having side effects is usually not desirable. An awk program that
28 uses functions not declared in the awk code makes it clear that these functions
29 are external, whereas an array may be just a global awk variable, side effects
30 are not obvious.
31
32
33 3. how to chose?
34
35 While technically the two ways of the API design are equivalent in the sense
36 that both end up in function calls, there are always considerations that
37 may make one better than the other for a specific application. Below are
38 the pros and cons:
39
40 Function calls, pro:
41 - easy to recognize external calls in the awk code
42 - can implement much more than lookup, set and list
43 - may provide faster listing
44
45 Function calls, con:
46 - longer awk source
47 - when there are multiple different implementations under different names,
48 an awk function that needs to operate on all may need to get a function
49 name prefix and do dynamic function calls that makes the awk
50 code look more complicated
51
52 Array, pro:
53 - simple and short awk code, especially for listing ("for in")
54 - when there are multiple different implementation, passing one of them
55 to an awk function (by reference) hides the differences, keeping awk
56 function code simple
57 - the whole set of data can be handled together: output of split, generic
58 array print or load functions
59
60 Array, con:
61 - hidden side effects (risks awk source readability)
62 - always have to implement lookup, set and list
63
64 NOTE: a major advantage of arrays is listing (the "for in" construction).
65 In mawk this is implemented by saving a list of all indices that exist at
66 the time of entering the loop. While most of the time this means duplicating
67 string references only, it may still be slow and may take considerable amount
68 of memory if the array is large. What counts as large may vary, but generally
69 a 10^6 indices may cause memory allocations in the megabyte range already.
70
71 In practice the following considerations could easily decide the question:
72 A. if there are more operations than lookup/set/list, use functions
73 B. if only set/get is required, check if listing looks useful or not;
74 if useful, go for arrays (where listing is done via "for in");
75 similarly: if there's a function based API for set/get/list, reconsider
76 using an array instead of custom listing. Unless arrays are large!
77 C. are generic array functions useful in common applications? If so, arrays
78 may be better. Generic array functions include:
79 - awk function that prints all indices of an array
80 - awk function doing some complex lookup, e.g. regex search on all indices
81 - loading the array from a string using split(); useful when indices
82 are small integers, typically counting from 0 or 1
83 D. would there be alternative implementations and generic awk functions
84 operating on them depending on their arguments? If so, arrays may be better
85 as they can be passed as reference
86
87 4. examples
88
89 According to these, the I/O port example is better implemented with functions
90 as arrays offer no benefit in any of the above points:
91 A. has only set and get, at this point arrays are as good as functions
92 B. "for in" listing is not a typical application: array has no benefit
93 C. printing all ports is rarely useful; complex lookups are not common;
94 loading I/O space with split() is not useful;
95 no obvious example of generic array code being useful on an IO array:
96 array has no benefit
97 D. having multiple alternative I/O spaces and passing one of these
98 to an awk function as array is not probable: array has no benefit
99
100 An example where array is more suitable is an interface for network interfaces
101 (ifconfig): arrays NIC_IP[], NIC_NETMASK[], NIC_MTU[], etc, indexed by
102 the name of the nic:
103 A. has lookup, set and list; array is as good as functions
104 B. it's a reasonable application to list all interfaces: "for in" is useful,
105 array looks better
106 C. printing all interfaces makes sense; complex lookup
107 (e.g. "all alias interfaces") makes sense; loading the array may make
108 sense (e.g. restoring network settings); split wouldn't work, tho; array
109 looks better
110 D. no obvious alternative arrays to be passed in arg; array has no benefit
111
112 In point A. and D. arrays are not better than functions (but not worse either),
113 but in B. and C. arrays definitely have an advantage for this app.
0 <HTML>
1 <BODY>
2 <h1> The Virtual Machine (VM) </h1>
3
4 The VM lives in execute.c function mawk_execute_().
5 <p>
6 In principle it takes an array of instructions (INST), executing them
7 one by one, operating on the current <a href="stack.html"> evaluation
8 stack</a> (or stack for short). Most of the execution really goes in
9 order as the compiler prepares up everything to achieve linearity.
10 This makes the execution loop relatively simple and efficient: it is
11 just a large <i>while(dont_need_to_exit) execute_next_instruction;</i>.
12 The actual instruction execution is a real large switch on the instruction
13 opcode.
14 <p>
15 An usual example on how this is implemented in practice can be
16 obtained by <i>lmawk -Wdump -f test.awk</i> on some simple arithmetic
17 script:
18 <table border=1>
19 <tr><th> awk <th> asm (VM instructions)
20 <tr>
21 <td>
22 <pre>
23 BEGIN { a = 3 + 4 * 5 }
24 </pre>
25 <td>
26 <pre>
27 BEGIN
28 000 pusha a
29 002 pushd 3
30 004 pushd 4
31 006 pushd 5
32 008 mul
33 009 add
34 010 assign
35 011 pop
36 012 exit0
37 </pre>
38 </table>
39 <p>
40 First the lvalue (target variable, left side) of the assignment is pushed,
41 then the expression (right side). The stack is, from top to down: {5, 4, 3, a}.
42 The top of the stack is 5, the second element is 4 by the time <i>mul</i> runs.
43 <i>Mul</i> will replace these two elements by 20, decreasing the stack size by
44 one, leaving the result on the top. Next <i>add</i> does a similar job,
45 replacing the top two items of the stack {20, 3} with their sum, 23. At
46 the end <i>assign</i> runs on the stack {23, a}, removing both items, copying
47 the value 23 to the global variable <i>a</i>. At the end it also puts
48 the result on the top of the stack, leaving the stack as {23} - this is
49 the result (output) of the assignment operation. Since the script doesn't
50 need to use the result, it runs a <i>pop</i> that removes and discards
51 the top item, leaving the stack empty. Since the script didn't have main
52 or END parts, the script can quit at this point, executing the <i>exit0</i>
53 instruction (exiting with value 0 - the implicit exit).
54 <p>
55 NOTE: currently there's absolutely no optimization in the parser: everything
56 is calculated as written in the script and some values are saved just to be
57 discarded by the next instruction.
58 <p>
59 An interesting and important feature of execute_() is that it can save all
60 states and return to the caller <b>at any point</b> of the execution, i.e.
61 between any two instruction in the code. It can also resume execution from
62 the next instruction. This provides the host application full control over
63 scheduling the script, while the script can be built of sequential, blocking
64 instructions.
65
66 <h2> Jumps and conditions </h2>
67
68 There are a few instructions that have to break linear execution flow, tho:
69 <ul>
70 <li> <a href="parser_if.html"> if()</a> needs to make a jump depending on some condition
71 <li> conditional code (e.g. <i>/^A/ { ... }</i>) is the same
72 <li> range conditional code (e.g. <i>/^A/,/^B/ { ... }</i>) is still the same with some extra complications (internal state tracking whether the script is within the range)
73 <li> <a href="parser_for.html">loops</a> obviously need to do a similar conditional jump back
74 <li> function calls have to temporarily suspend executing the current code and jump to the function code from which a <i>ret</i> or <i>ret0</i> instruction jumps back
75 </ul>
76 <p>
77 Some of the above are implemented using conditional and unconditional jumps
78 to direct addresses (first column on the asm). For example a simple if
79 is compiled to contain 2 jumps:
80 <table border=1>
81 <tr><th> awk <th> asm (VM instructions)
82 <tr>
83 <td>
84 <pre>
85 BEGIN {
86 if (bool)
87 a = 6
88 else
89 a = 7
90 }
91 </pre>
92 <td>
93 <pre>
94 BEGIN
95 000 pushi bool
96 002 jz 012
97 004 pusha a
98 006 pushd 6
99 008 assign
100 009 pop
101 010 jmp 018
102 012 pusha a
103 014 pushd 7
104 016 assign
105 017 pop
106 018 exit0
107 </pre>
108 </table>
109 <p>
110 The first one is a conditional jump, "jump if [top of the stack is] zero"
111 (<i>jz</i>) - this makes the VM jump to the <i>else</i> branch at address 10.
112 The <i>then</i> branch ends in an unconditional jump to the next instruction
113 after the if (which is the implicit exit in this example), bypassing
114 the code of the <i>else</i> branch.
115 <p>
116 A jump is carried out by a simple modification of the "next instruction"
117 pointer before running the next iteration of the execution loop.
118
119 <h2> Recursion: function calls </h2>
120
121 A slightly more complicated mechanism is used when jumps are of recursive
122 nature: the code has to jump to somewhere to do some work and then
123 return here and continue execution from the next instruction. A typical
124 example on this is executing user functions.
125 <p>
126 The original mawk implementation simply called mawk_execute_() recursively.
127 This meant the C compiler took care of saving all internal states on the
128 C stack for the detour. However, this wouldn't allow the code to be suspended
129 during such detour as it would be problematic to rebuild the C stack on a resume.
130 <p>
131 Thus libmawk's mawk_execute_() does not recurse on C level but on VM level.
132 For example when a function is called (using the <i>call</i> instruction):
133 <ul>
134 <li> 1. prepare the eval stack for the function (as mawk did): push arguments and local variables
135 <li> 2. push execution state on top of the eval stack
136 <li> 3. unconditional jump to the function body
137 </ul>
138 <p>
139 Upon a <i>ret</i> instruction from the function:
140 <ul>
141 <li> 1. save and remove the return value from the top of the stack
142 <li> 2. restore previous execution state from the top of the stack
143 <li> 3. remove all arguments and local variables from the stack (remove the frame)
144 <li> 4. push the return value on top of the stack
145 <li> 5. continue execution normally - because step 2., this will run the instruction right after the <i>call</i>
146 </ul>
147
148 <h3> additional cases of recursion </h3>
149 A range pattern is recursive as well: it needs to evaluate one or two pattern
150 matching before it decides whether to execute the action and/or update
151 the state. The range check starts with instruction _RANGE_CHK which
152 encodes expression code offsets and state in the next few instruction slots. It
153 recurses to evaluate expressions which are terminated by the _RANGE_STOP command.
154 Entering an expression evaluation is similar to a function call while
155 _RANGE_STOP is very similar to a ret.
156
157 <h3> deep recursion </h3>
158 At any time the eval stack has to have enough space after sp for
159 evaluation the longest awk expression. Any user function recursion will
160 bump sp leaving less room for expressions and further recursion. Relocating
161 the stack (with a realloc()) is not a good idea as there might be cell
162 pointers pointing to stack elements all around.
163
164 Instead, mawk limits expression length in compile time to a fixed
165 maximum. If entering a new function would not leave at list this
166 amount of eval stack above sp, "deep recursion" is performed. This
167 starts by allocating an entire new stack for the call. Call stacking
168 saves enough pointers so that the code can switch back to the
169 previous stack easily. The allocation is done using zmalloc(), the overhead
170 is minimal. Since the original stack/stacks is/are kept intact, any
171 pointer stays valid. sp points into the new stack block and will increase
172 there until another deep recursion.
173
174 This wastes some stack space on the old stack (potentially max expression
175 length minus one slot) but guarantees that:
176 - checks and special things need to be done only at entering/leaving functions
177 - even that happens rarely as a stack block is large enough to host
178 many functions besides the longest expression
179 - the stack can grow as big as it likes to, without having to allocate
180 one large block of memory
181 - all allocation is done from normal instance memory - allocation limit,
182 and auto cleanup at the end are granted
183
184 <h2> Resuming execute_() </h2>
185
186 Since the far most common thing in an embedded setup is to resume a
187 code interrupted by execution limit or a blocking getline, mawk_execute_() is
188 doing that by default. The top few slots in the eval stack is always a full
189 state dump, the same thing used in recursion. Entering mawk_execute_() pops this
190 section and initializes all internal states from it. When execution needs
191 to be interrupted, mawk_execute_() saves internal states onto the top
192 of the stack.
193
194 <h2> Entering execute_() (fresh start) </h2>
195
196 Entering in run state involves setting up internal states pointing to
197 the beginning of the code in question, pushing these states on top of
198 the stack and calling mawk_execute_() which will "resume" from these states.
199 Similar thing happens when the application calls an awk function.
200 <p>
201 It may be that the execution is interrupted in the middle of running of
202 a large block of code, for example in BEGIN. The top of the stack holds
203 the current execution state so that mawk_execute_() will be able to
204 continue execution. The application may decide to run an awk
205 function before resuming the code: this operation would push a new
206 set of execution state on top of the stack and call mawk_execute_().
207 When the current state finishes at the _RET instruction, mawk_execute_()
208 would take the next frame from the stack and would automatically resume
209 execution of the interrupted BEGIN block. This would cause the return value
210 of the function to be lost and would attempt to resume BEGIN as a side effect
211 of the function call!
212 <p>
213 To avoid such confusion, any new enter to mawk_execute_() is required to
214 push two sets of states: an EXEST_EXIT and the actual state it wants
215 to "resume" at (start execution at). When mawk_execute_() hits the _RET
216 instruction in the above example, it does pop the next frame, but that
217 frame would be the EXEST_EXIT which would cause it to interrupt immediately.
218 This leaves the stack exactly as it looked like before the function call,
219 and the application later may decide to resume execution.
220 <p>
221 Fresh start entries:
222 <ul>
223 <li> running BEGIN (last stage of initialization)
224 <li> running main on new input, in non-interrupted state
225 <li> running END (first stage of uninitialization)
226 <li> an awk function is called by the application
227 </ul>
228
229
230
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:30 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>EXAMPLE</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">EXAMPLE</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#Example application">Example application</a><br>
26
27 <hr>
28
29
30 <h2>NAME
31 <a name="NAME"></a>
32 </h2>
33
34
35 <p style="margin-left:11%; margin-top: 1em">libmawk example
36 &minus; how to use the library</p>
37
38 <h2>SYNOPSIS
39 <a name="SYNOPSIS"></a>
40 </h2>
41
42
43 <p style="margin-left:11%; margin-top: 1em"><b>#include
44 &lt;libmawk.h&gt;</b></p>
45
46 <h2>DESCRIPTION
47 <a name="DESCRIPTION"></a>
48 </h2>
49
50
51 <p style="margin-left:11%; margin-top: 1em">Libmawk is a
52 library that lets applications to embed awk scripts using
53 the code of the popular implementation <b>mawk.</b> The
54 normal process is to call libmawk_initialize() to set up a
55 new mawk context (with script(s) loaded), then in the main
56 loop feed it using libmawk_append_input(). For &quot;out of
57 band&quot; communication, the program may also call
58 functions implemented in awk and read (or modify) global
59 variables of the awk script. The hos tapplication usally
60 will also bind some of its functions to the context using
61 libmawk_register_function, which allows the awk script to
62 call the host applicaiton&rsquo;s functions directly as they
63 were awk builtins or user defined functions. After the main
64 loop, the application destroys the context freeing up all
65 memory allocated for the script(s).</p>
66
67 <p style="margin-left:11%; margin-top: 1em">One context is
68 for one awk program. One awk program may consist of multiple
69 script files (just as with command line awk, with multiple
70 -f filename arguments). Libmawk is instance safe, the host
71 application may create multiple instances of contexts with
72 the same or with different set of awk scripts loaded. These
73 contexts are totally separate, no variables, functions or
74 any sort of states are shared. However, the host application
75 may provide means of communication between those scripts by
76 custom functions or by copying variable contents between
77 them.</p>
78
79 <h2>Example application
80 <a name="Example application"></a>
81 </h2>
82
83
84 <p style="margin-left:11%; margin-top: 1em">The following
85 example application creates a single context to demonstrate
86 all the above mentioned functionality. <br>
87 #include &lt;stdio.h&gt; <br>
88 #include &lt;libmawk.h&gt;</p>
89
90 <p style="margin-left:11%; margin-top: 1em">CELL
91 *blobb(mawk_state_t *context, CELL * sp, int a_args) <br>
92 {</p>
93
94 <table width="100%" border="0" rules="none" frame="void"
95 cellspacing="0" cellpadding="0">
96 <tr valign="top" align="left">
97 <td width="8%"></td>
98 <td width="7%"></td>
99 <td width="8%">
100
101
102 <p>int n;</p></td>
103 <td width="77%">
104 </td></tr>
105 <tr valign="top" align="left">
106 <td width="8%"></td>
107 <td width="7%"></td>
108 <td width="8%">
109
110
111 <p>char buff[64];</p></td>
112 <td width="77%">
113 </td></tr>
114 <tr valign="top" align="left">
115 <td width="8%"></td>
116 <td width="7%"></td>
117 <td width="8%">
118
119
120 <p>/* do something - print BLOBB and all arguments */</p></td>
121 <td width="77%">
122 </td></tr>
123 <tr valign="top" align="left">
124 <td width="8%"></td>
125 <td width="7%"></td>
126 <td width="8%">
127
128
129 <p>printf(&quot;BLOBB! &quot;);</p></td>
130 <td width="77%">
131 </td></tr>
132 <tr valign="top" align="left">
133 <td width="8%"></td>
134 <td width="7%"></td>
135 <td width="8%">
136
137
138 <p>for(n = a_args-1; n &gt;= 0; n--)</p></td>
139 <td width="77%">
140 </td></tr>
141 <tr valign="top" align="left">
142 <td width="8%"></td>
143 <td width="7%">
144 </td>
145 <td width="8%">
146 </td>
147 <td width="77%">
148
149
150 <p>printf(&quot;%d=&rsquo;%s&rsquo; &quot;, n,
151 libmawk_print_cell((sp-n), buff, sizeof(buff)));</p></td></tr>
152 <tr valign="top" align="left">
153 <td width="8%"></td>
154 <td width="7%"></td>
155 <td width="8%">
156
157
158 <p>printf(&quot;0);</p></td>
159 <td width="77%">
160 </td></tr>
161 <tr valign="top" align="left">
162 <td width="8%"></td>
163 <td width="7%"></td>
164 <td width="8%">
165
166
167 <p>/* restore the stack (remove all arguments) */</p></td>
168 <td width="77%">
169 </td></tr>
170 <tr valign="top" align="left">
171 <td width="8%"></td>
172 <td width="7%"></td>
173 <td width="8%">
174
175
176 <p>sp = sp - a_args;</p></td>
177 <td width="77%">
178 </td></tr>
179 <tr valign="top" align="left">
180 <td width="8%"></td>
181 <td width="7%"></td>
182 <td width="8%">
183
184
185 <p>/* set a return value (find out where the return value
186 is on the stack,</p></td>
187 <td width="77%">
188 </td></tr>
189 <tr valign="top" align="left">
190 <td width="8%"></td>
191 <td width="7%"></td>
192 <td width="8%">
193
194
195 <p>using libmawk_stackret()) */</p></td>
196 <td width="77%">
197 </td></tr>
198 <tr valign="top" align="left">
199 <td width="8%"></td>
200 <td width="7%"></td>
201 <td width="8%">
202
203
204 <p>libmawk_set_cell(context, libmawk_stackret(sp),
205 &rsquo;f&rsquo;, (double)1234);</p></td>
206 <td width="77%">
207 </td></tr>
208 <tr valign="top" align="left">
209 <td width="8%"></td>
210 <td width="7%"></td>
211 <td width="8%">
212
213
214 <p>/* return the new stack pointer - should be the one that
215 it was before</p></td>
216 <td width="77%">
217 </td></tr>
218 <tr valign="top" align="left">
219 <td width="8%"></td>
220 <td width="7%"></td>
221 <td width="8%">
222
223
224 <p>arguments had been pushed on the stack */</p></td>
225 <td width="77%">
226 </td></tr>
227 <tr valign="top" align="left">
228 <td width="8%"></td>
229 <td width="7%"></td>
230 <td width="8%">
231
232
233 <p>return sp;</p></td>
234 <td width="77%">
235 </td></tr>
236 </table>
237
238 <p style="margin-left:11%;">}</p>
239
240 <p style="margin-left:11%; margin-top: 1em">int main(int
241 argc, char **argv) <br>
242 {</p>
243
244 <table width="100%" border="0" rules="none" frame="void"
245 cellspacing="0" cellpadding="0">
246 <tr valign="top" align="left">
247 <td width="8%"></td>
248 <td width="92%">
249
250
251 <p>mawk_state_t *m;</p></td></tr>
252 <tr valign="top" align="left">
253 <td width="8%"></td>
254 <td width="92%">
255
256
257 <p>CELL ret, arrv, *vr;</p></td></tr>
258 <tr valign="top" align="left">
259 <td width="8%"></td>
260 <td width="92%">
261
262
263 <p>char buff[64];</p></td></tr>
264 </table>
265
266 <p style="margin-left:11%; margin-top: 1em">/* the simpler
267 way is:</p>
268
269 <table width="100%" border="0" rules="none" frame="void"
270 cellspacing="0" cellpadding="0">
271 <tr valign="top" align="left">
272 <td width="8%"></td>
273 <td width="92%">
274
275
276 <p>m = libmawk_initialize(argc, argv);</p></td></tr>
277 <tr valign="top" align="left">
278 <td width="8%"></td>
279 <td width="92%">
280
281
282 <p>However, if the application wants to change the
283 environment before</p></td></tr>
284 <tr valign="top" align="left">
285 <td width="8%"></td>
286 <td width="92%">
287
288
289 <p>executing BEGIN, the following, 3 stage initialization
290 should be done:</p></td></tr>
291 </table>
292
293 <p style="margin-left:11%;">*/</p>
294
295 <table width="100%" border="0" rules="none" frame="void"
296 cellspacing="0" cellpadding="0">
297 <tr valign="top" align="left">
298 <td width="8%"></td>
299 <td width="7%"></td>
300 <td width="8%">
301
302
303 <p>m = libmawk_initialize_stage1(); /* set up m */</p></td>
304 <td width="8%"></td>
305 <td width="7%"></td>
306 <td width="62%">
307 </td></tr>
308 <tr valign="top" align="left">
309 <td width="8%"></td>
310 <td width="7%"></td>
311 <td width="8%">
312
313
314 <p>custom_array_init(m); /* set up a new builtin array with
315 side effects, before parsing scripts */</p></td>
316 <td width="8%"></td>
317 <td width="7%"></td>
318 <td width="62%">
319 </td></tr>
320 <tr valign="top" align="left">
321 <td width="8%"></td>
322 <td width="7%"></td>
323 <td width="8%">
324
325
326 <p>m = libmawk_initialize_stage2(m, argc, argv); /* parse
327 args loads the script(s) */</p></td>
328 <td width="8%"></td>
329 <td width="7%"></td>
330 <td width="62%">
331 </td></tr>
332 <tr valign="top" align="left">
333 <td width="8%"></td>
334 <td width="7%"></td>
335 <td width="8%">
336
337
338 <p>m = libmawk_initialize_stage3(m); /* execute BEGIN {}
339 */</p> </td>
340 <td width="8%"></td>
341 <td width="7%"></td>
342 <td width="62%">
343 </td></tr>
344 <tr valign="top" align="left">
345 <td width="8%"></td>
346 <td width="7%"></td>
347 <td width="8%">
348
349
350 <p>ret.type = C_NOINIT;</p></td>
351 <td width="8%"></td>
352 <td width="7%"></td>
353 <td width="62%">
354 </td></tr>
355 <tr valign="top" align="left">
356 <td width="8%"></td>
357 <td width="7%"></td>
358 <td width="8%">
359
360
361 <p>if (m != NULL) {</p></td>
362 <td width="8%"></td>
363 <td width="7%"></td>
364 <td width="62%">
365 </td></tr>
366 <tr valign="top" align="left">
367 <td width="8%"></td>
368 <td width="7%">
369 </td>
370 <td width="8%">
371 </td>
372 <td width="8%">
373
374
375 <p>/* test function call */</p></td>
376 <td width="7%"></td>
377 <td width="62%">
378 </td></tr>
379 <tr valign="top" align="left">
380 <td width="8%"></td>
381 <td width="7%">
382 </td>
383 <td width="8%">
384 </td>
385 <td width="8%">
386
387
388 <p>if (libmawk_call_function(m, &quot;func&quot;, &amp;ret,
389 &quot;dfs&quot;, (int)42, (double)1.234, (char *)&quot;test
390 string.&quot;) == 0) {</p></td>
391 <td width="7%"></td>
392 <td width="62%">
393 </td></tr>
394 <tr valign="top" align="left">
395 <td width="8%"></td>
396 <td width="7%">
397 </td>
398 <td width="8%">
399 </td>
400 <td width="8%">
401 </td>
402 <td width="7%">
403
404
405 <p>printf(&quot;Return value of func is &rsquo;%s&rsquo;0,
406 libmawk_print_cell(&amp;ret, buff, sizeof(buff)));</p></td>
407 <td width="62%">
408 </td></tr>
409 <tr valign="top" align="left">
410 <td width="8%"></td>
411 <td width="7%">
412 </td>
413 <td width="8%">
414 </td>
415 <td width="8%">
416 </td>
417 <td width="7%">
418
419
420 <p>libmawk_cell_destroy(m, &amp;ret);</p></td>
421 <td width="62%">
422 </td></tr>
423 <tr valign="top" align="left">
424 <td width="8%"></td>
425 <td width="7%">
426 </td>
427 <td width="8%">
428 </td>
429 <td width="8%">
430
431
432 <p>}</p></td>
433 <td width="7%"></td>
434 <td width="62%">
435 </td></tr>
436 <tr valign="top" align="left">
437 <td width="8%"></td>
438 <td width="7%">
439 </td>
440 <td width="8%">
441 </td>
442 <td width="8%">
443
444
445 <p>printf(&quot;Failed to call func()0);</p></td>
446 <td width="7%"></td>
447 <td width="62%">
448 </td></tr>
449 <tr valign="top" align="left">
450 <td width="8%"></td>
451 <td width="7%">
452 </td>
453 <td width="8%">
454 </td>
455 <td width="8%">
456
457
458 <p>/* this is the same function call with a different
459 syntax */</p></td>
460 <td width="7%"></td>
461 <td width="62%">
462 </td></tr>
463 <tr valign="top" align="left">
464 <td width="8%"></td>
465 <td width="7%">
466 </td>
467 <td width="8%">
468 </td>
469 <td width="8%">
470
471
472 <p>{</p></td>
473 <td width="7%"></td>
474 <td width="62%">
475 </td></tr>
476 <tr valign="top" align="left">
477 <td width="8%"></td>
478 <td width="7%">
479 </td>
480 <td width="8%">
481 </td>
482 <td width="8%">
483 </td>
484 <td width="7%">
485
486
487 <p>int i = 42;</p></td>
488 <td width="62%">
489 </td></tr>
490 <tr valign="top" align="left">
491 <td width="8%"></td>
492 <td width="7%">
493 </td>
494 <td width="8%">
495 </td>
496 <td width="8%">
497 </td>
498 <td width="7%">
499
500
501 <p>double d = 1.234;</p></td>
502 <td width="62%">
503 </td></tr>
504 <tr valign="top" align="left">
505 <td width="8%"></td>
506 <td width="7%">
507 </td>
508 <td width="8%">
509 </td>
510 <td width="8%">
511 </td>
512 <td width="7%">
513
514
515 <p>char *s = &quot;test string.&quot;;</p></td>
516 <td width="62%">
517 </td></tr>
518 <tr valign="top" align="left">
519 <td width="8%"></td>
520 <td width="7%">
521 </td>
522 <td width="8%">
523 </td>
524 <td width="8%">
525 </td>
526 <td width="7%">
527
528
529 <p>void *args[] = {&amp;i, &amp;d, s};</p></td>
530 <td width="62%">
531 </td></tr>
532 <tr valign="top" align="left">
533 <td width="8%"></td>
534 <td width="7%">
535 </td>
536 <td width="8%">
537 </td>
538 <td width="8%">
539 </td>
540 <td width="7%">
541
542
543 <p>if (libmawk_call_functionp(m, &quot;func&quot;,
544 &amp;ret, &quot;dfs&quot;, args) != 0) {</p></td>
545 <td width="62%">
546 </td></tr>
547 <tr valign="top" align="left">
548 <td width="8%"></td>
549 <td width="7%">
550 </td>
551 <td width="8%">
552 </td>
553 <td width="8%">
554 </td>
555 <td width="7%">
556 </td>
557 <td width="62%">
558
559
560 <p>printf(&quot;Return value of func is &rsquo;%s&rsquo;0,
561 libmawk_print_cell(&amp;ret, buff, sizeof(buff)));</p></td></tr>
562 <tr valign="top" align="left">
563 <td width="8%"></td>
564 <td width="7%">
565 </td>
566 <td width="8%">
567 </td>
568 <td width="8%">
569 </td>
570 <td width="7%">
571 </td>
572 <td width="62%">
573
574
575 <p>libmawk_cell_destroy(m, &amp;ret);</p></td></tr>
576 <tr valign="top" align="left">
577 <td width="8%"></td>
578 <td width="7%">
579 </td>
580 <td width="8%">
581 </td>
582 <td width="8%">
583 </td>
584 <td width="7%">
585
586
587 <p>}</p></td>
588 <td width="62%">
589 </td></tr>
590 <tr valign="top" align="left">
591 <td width="8%"></td>
592 <td width="7%">
593 </td>
594 <td width="8%">
595 </td>
596 <td width="8%">
597
598
599 <p>}</p></td>
600 <td width="7%"></td>
601 <td width="62%">
602 </td></tr>
603 <tr valign="top" align="left">
604 <td width="8%"></td>
605 <td width="7%">
606 </td>
607 <td width="8%">
608 </td>
609 <td width="8%">
610
611
612 <p>/* register a C function (resolved runtime) */</p></td>
613 <td width="7%"></td>
614 <td width="62%">
615 </td></tr>
616 <tr valign="top" align="left">
617 <td width="8%"></td>
618 <td width="7%">
619 </td>
620 <td width="8%">
621 </td>
622 <td width="8%">
623
624
625 <p>if (libmawk_register_function(m, &quot;blobb&quot;,
626 blobb) != 0) {</p></td>
627 <td width="7%"></td>
628 <td width="62%">
629 </td></tr>
630 <tr valign="top" align="left">
631 <td width="8%"></td>
632 <td width="7%">
633 </td>
634 <td width="8%">
635 </td>
636 <td width="8%">
637 </td>
638 <td width="7%">
639
640
641 <p>fprintf(stderr, &quot;ERROR: Unable to register function
642 blobb0);</p> </td>
643 <td width="62%">
644 </td></tr>
645 <tr valign="top" align="left">
646 <td width="8%"></td>
647 <td width="7%">
648 </td>
649 <td width="8%">
650 </td>
651 <td width="8%">
652
653
654 <p>}</p></td>
655 <td width="7%"></td>
656 <td width="62%">
657 </td></tr>
658 <tr valign="top" align="left">
659 <td width="8%"></td>
660 <td width="7%">
661 </td>
662 <td width="8%">
663 </td>
664 <td width="8%">
665
666
667 <p>/* run some data */</p></td>
668 <td width="7%"></td>
669 <td width="62%">
670 </td></tr>
671 <tr valign="top" align="left">
672 <td width="8%"></td>
673 <td width="7%">
674 </td>
675 <td width="8%">
676 </td>
677 <td width="8%">
678
679
680 <p>libmawk_append_input(m, &quot;This is a0ultiline test
681 input0ut in the artificial input buffer.0);</p></td>
682 <td width="7%"></td>
683 <td width="62%">
684 </td></tr>
685 <tr valign="top" align="left">
686 <td width="8%"></td>
687 <td width="7%">
688 </td>
689 <td width="8%">
690 </td>
691 <td width="8%">
692
693
694 <p>libmawk_run_main(m);</p></td>
695 <td width="7%"></td>
696 <td width="62%">
697 </td></tr>
698 <tr valign="top" align="left">
699 <td width="8%"></td>
700 <td width="7%">
701 </td>
702 <td width="8%">
703 </td>
704 <td width="8%">
705
706
707 <p>/* print var: scalar */</p></td>
708 <td width="7%"></td>
709 <td width="62%">
710 </td></tr>
711 <tr valign="top" align="left">
712 <td width="8%"></td>
713 <td width="7%">
714 </td>
715 <td width="8%">
716 </td>
717 <td width="8%">
718
719
720 <p>vr = libmawk_get_var(m, &quot;var&quot;);</p></td>
721 <td width="7%"></td>
722 <td width="62%">
723 </td></tr>
724 <tr valign="top" align="left">
725 <td width="8%"></td>
726 <td width="7%">
727 </td>
728 <td width="8%">
729 </td>
730 <td width="8%">
731
732
733 <p>if (vr != NULL)</p></td>
734 <td width="7%"></td>
735 <td width="62%">
736 </td></tr>
737 <tr valign="top" align="left">
738 <td width="8%"></td>
739 <td width="7%">
740 </td>
741 <td width="8%">
742 </td>
743 <td width="8%">
744 </td>
745 <td width="7%">
746
747
748 <p>printf(&quot;Variable var = &rsquo;%s&rsquo;0,
749 libmawk_print_cell(vr, buff, sizeof(buff)));</p></td>
750 <td width="62%">
751 </td></tr>
752 <tr valign="top" align="left">
753 <td width="8%"></td>
754 <td width="7%">
755 </td>
756 <td width="8%">
757 </td>
758 <td width="8%">
759
760
761 <p>else</p></td>
762 <td width="7%"></td>
763 <td width="62%">
764 </td></tr>
765 <tr valign="top" align="left">
766 <td width="8%"></td>
767 <td width="7%">
768 </td>
769 <td width="8%">
770 </td>
771 <td width="8%">
772 </td>
773 <td width="7%">
774
775
776 <p>printf(&quot;No such variable</p></td>
777 <td width="62%">
778 </td></tr>
779 <tr valign="top" align="left">
780 <td width="8%"></td>
781 <td width="7%">
782 </td>
783 <td width="8%">
784 </td>
785 <td width="8%">
786
787
788 <p>/* print var: array */</p></td>
789 <td width="7%"></td>
790 <td width="62%">
791 </td></tr>
792 </table>
793
794 <p style="margin-left:11%;">#warning TODO</p>
795
796 <table width="100%" border="0" rules="none" frame="void"
797 cellspacing="0" cellpadding="0">
798 <tr valign="top" align="left">
799 <td width="8%"></td>
800 <td width="7%">
801 </td>
802 <td width="8%">
803 </td>
804 <td width="8%">
805
806
807 <p>arrv.type = C_NOINIT;</p></td>
808 <td width="69%">
809 </td></tr>
810 <tr valign="top" align="left">
811 <td width="8%"></td>
812 <td width="7%">
813 </td>
814 <td width="8%">
815 </td>
816 <td width="8%">
817
818
819 <p>if (libmawk_get_array_at(m, &quot;arr&quot;,
820 &quot;hello&quot;, &amp;arrv, 0) &gt; 0)</p></td>
821 <td width="69%">
822 </td></tr>
823 <tr valign="top" align="left">
824 <td width="8%"></td>
825 <td width="7%">
826 </td>
827 <td width="8%">
828 </td>
829 <td width="8%">
830 </td>
831 <td width="69%">
832
833
834 <p>printf(&quot;Variable arr[</p></td></tr>
835 <tr valign="top" align="left">
836 <td width="8%"></td>
837 <td width="7%">
838 </td>
839 <td width="8%">
840 </td>
841 <td width="8%">
842
843
844 <p>else</p></td>
845 <td width="69%">
846 </td></tr>
847 <tr valign="top" align="left">
848 <td width="8%"></td>
849 <td width="7%">
850 </td>
851 <td width="8%">
852 </td>
853 <td width="8%">
854 </td>
855 <td width="69%">
856
857
858 <p>printf(&quot;No such variable</p></td></tr>
859 </table>
860
861 <p style="margin-left:11%; margin-top: 1em">#warning todo:
862 array set</p>
863
864 <table width="100%" border="0" rules="none" frame="void"
865 cellspacing="0" cellpadding="0">
866 <tr valign="top" align="left">
867 <td width="11%"></td>
868 <td width="-3%"></td>
869 <td width="7%">
870 </td>
871 <td width="8%">
872 </td>
873 <td width="8%">
874
875
876 <p>/* set var: array; change the existing
877 (arr[&quot;hello&quot;]) */</p></td>
878 <td width="69%">
879 </td></tr>
880 <tr valign="top" align="left">
881 <td width="11%"></td>
882 <td width="-3%"></td>
883 <td width="7%">
884
885
886 <p>//</p></td>
887 <td width="8%">
888 </td>
889 <td width="8%">
890
891
892 <p>if (ret != NULL)</p></td>
893 <td width="69%">
894 </td></tr>
895 <tr valign="top" align="left">
896 <td width="11%"></td>
897 <td width="-3%"></td>
898 <td width="7%">
899
900
901 <p>//</p></td>
902 <td width="8%">
903 </td>
904 <td width="8%">
905 </td>
906 <td width="69%">
907
908
909 <p>libmawk_set_cell(m, ret, &rsquo;s&rsquo;,
910 &quot;WORLD&quot;);</p> </td></tr>
911 <tr valign="top" align="left">
912 <td width="11%"></td>
913 <td width="-3%"></td>
914 <td width="7%">
915 </td>
916 <td width="8%">
917 </td>
918 <td width="8%">
919
920
921 <p>/* set var: array; create a new index */</p></td>
922 <td width="69%">
923 </td></tr>
924 </table>
925
926 <p style="margin-left:11%;">#warning todo: array set</p>
927
928 <table width="100%" border="0" rules="none" frame="void"
929 cellspacing="0" cellpadding="0">
930 <tr valign="top" align="left">
931 <td width="11%"></td>
932 <td width="-3%"></td>
933 <td width="7%">
934
935
936 <p>//</p></td>
937 <td width="8%">
938 </td>
939 <td width="77%">
940
941
942 <p>libmawk_get_array_at(m, &quot;arr&quot;,
943 &quot;bye&quot;, &amp;arrv, 1);</p></td></tr>
944 <tr valign="top" align="left">
945 <td width="11%"></td>
946 <td width="-3%"></td>
947 <td width="7%">
948
949
950 <p>//</p></td>
951 <td width="8%">
952 </td>
953 <td width="77%">
954
955
956 <p>libmawk_set_cell(m, ret, &rsquo;s&rsquo;,
957 &quot;universe&quot;);</p> </td></tr>
958 <tr valign="top" align="left">
959 <td width="11%"></td>
960 <td width="-3%"></td>
961 <td width="7%">
962 </td>
963 <td width="8%">
964 </td>
965 <td width="77%">
966
967
968 <p>/* run some more data */</p></td></tr>
969 <tr valign="top" align="left">
970 <td width="11%"></td>
971 <td width="-3%"></td>
972 <td width="7%">
973 </td>
974 <td width="8%">
975 </td>
976 <td width="77%">
977
978
979 <p>libmawk_append_input(m, &quot;Second0);</p></td></tr>
980 <tr valign="top" align="left">
981 <td width="11%"></td>
982 <td width="-3%"></td>
983 <td width="7%">
984 </td>
985 <td width="8%">
986 </td>
987 <td width="77%">
988
989
990 <p>libmawk_append_input(m, &quot;run.0);</p></td></tr>
991 <tr valign="top" align="left">
992 <td width="11%"></td>
993 <td width="-3%"></td>
994 <td width="7%">
995 </td>
996 <td width="8%">
997 </td>
998 <td width="77%">
999
1000
1001 <p>libmawk_run_main(m);</p></td></tr>
1002 <tr valign="top" align="left">
1003 <td width="11%"></td>
1004 <td width="-3%"></td>
1005 <td width="7%">
1006 </td>
1007 <td width="8%">
1008 </td>
1009 <td width="77%">
1010
1011
1012 <p>custom_array_print(m);</p></td></tr>
1013 <tr valign="top" align="left">
1014 <td width="11%"></td>
1015 <td width="-3%"></td>
1016 <td width="7%">
1017 </td>
1018 <td width="8%">
1019 </td>
1020 <td width="77%">
1021
1022
1023 <p>/* run end */</p></td></tr>
1024 <tr valign="top" align="left">
1025 <td width="11%"></td>
1026 <td width="-3%"></td>
1027 <td width="7%">
1028 </td>
1029 <td width="8%">
1030 </td>
1031 <td width="77%">
1032
1033
1034 <p>libmawk_uninitialize(m);</p></td></tr>
1035 <tr valign="top" align="left">
1036 <td width="11%"></td>
1037 <td width="-3%"></td>
1038 <td width="7%"></td>
1039 <td width="8%">
1040
1041
1042 <p>}</p></td>
1043 <td width="77%">
1044 </td></tr>
1045 <tr valign="top" align="left">
1046 <td width="11%"></td>
1047 <td width="-3%"></td>
1048 <td width="7%"></td>
1049 <td width="8%">
1050
1051
1052 <p>else {</p></td>
1053 <td width="77%">
1054 </td></tr>
1055 <tr valign="top" align="left">
1056 <td width="11%"></td>
1057 <td width="-3%"></td>
1058 <td width="7%">
1059 </td>
1060 <td width="8%">
1061 </td>
1062 <td width="77%">
1063
1064
1065 <p>printf(&quot;Init failed.0);</p></td></tr>
1066 <tr valign="top" align="left">
1067 <td width="11%"></td>
1068 <td width="-3%"></td>
1069 <td width="7%"></td>
1070 <td width="8%">
1071
1072
1073 <p>}</p></td>
1074 <td width="77%">
1075 </td></tr>
1076 <tr valign="top" align="left">
1077 <td width="11%"></td>
1078 <td width="-3%"></td>
1079 <td width="7%"></td>
1080 <td width="8%">
1081
1082
1083 <p>printf(&quot;END0);</p></td>
1084 <td width="77%">
1085 </td></tr>
1086 <tr valign="top" align="left">
1087 <td width="11%"></td>
1088 <td width="-3%"></td>
1089 <td width="7%"></td>
1090 <td width="8%">
1091
1092
1093 <p>return 0 ;</p></td>
1094 <td width="77%">
1095 </td></tr>
1096 </table>
1097
1098 <p style="margin-left:11%;">}</p>
1099 <hr>
1100 </body>
1101 </html>
0 <HTML>
1 <BODY>
2 <H1> awk script execution </H1>
3 Libmawk runs the bytecode of the script in a <a href="developer/vm">virtual machine</a>.
4 The VM takes the bytecode as a series of instructions that operate on data
5 stored on the execution stack and in global states of the script instance
6 (libmawk_state_t).
7 <p>
8 There is only one thing at a time an instance is doing, however that
9 one thing may be interrupted and resumed any time. This one thing is
10 always one of these:
11 <ul>
12 <li> running BEGIN
13 <li> running END
14 <li> running main (the stdin read and pattern match rules)
15 <li> running an awk function called from the application
16 <li> nothing: empty stack; before starting or after finishing any of the above activities
17 </ul>
18 <p>
19 BEGIN, END, main and awk functions are the four entry points of executing
20 the script. Normally BEGIN is run right after setting up the script, then
21 main is run on all input and END is run when the script exits, right
22 before uninitialization of the script instance. This is a 1:1 copy
23 of the standard way awk works. The fourth, calling awk functions directly
24 from the application is an extra entry point.
25 <p>
26 The script is not doing anything unless the application commands it to. Some
27 of the simplified API does this automatically, but the raw API (staged
28 init/uninit) always lets the app decide when to <b>start</b> running the script.
29 This document calls an <i>execution transaction<i> when the application calls
30 the API to start running a script.
31 <p>
32 Any execution related call is non-blocking, thus it will return after a
33 reasonable time spent running the script and will never stuck running
34 an infinite loop. When such an API call returns, the return value
35 is a mawk_exec_result_t that indicates the reason of the return:
36 <ul>
37 <li> 1. if the script attempts to read a file/pipe that would block, it interrupts execution and returns (with <i>MAWK_EXER_INT_READ</i>) instead
38 <li> 2. when reaching the run limit (a given number of instructions has been executed), the script is interrupted (return value is <i>MAWK_EXER_INT_RUNLIMIT</i>)
39 <li> 3. the script may finish executing the current execution transaction (<i>MAWK_EXER_DONE</i> or <i>MAWK_EXER_FUNCRET</i>)
40 <li> 4. the script may decide to exit
41 </ul>
42 <p>
43 <i>Execution transaction<i> are collected on the evaluation stack. If
44 the application requests an execution and the API call returns before
45 finishing, the transaction is still active. The application is
46 free to initiate a new <i>execution transaction<i>, without
47 first finishing the previous one. However, the VM will always resume and
48 progress running the most recent <i>execution transaction<i>. This means
49 <i>execution transactions<i> are sort of nested. When the top, most recent
50 <i>execution transaction<i> finishes (return 3), the next resume request
51 will go on with the previous transaction.
52 <p>
53 Note, however, that the script has global states. The most obvious state
54 is the exit state: if the script runs exit(), it will discard all open
55 transactions. For example consider a script that is running a main part
56 processing the input. When the application is in this phase, the topmost
57 transaction is always a "running main" transaction that returned
58 previously because there was no more input to be processed. If the
59 application calls an awk function that decides to do an exit(), that will
60 affect not only discard the function transaction but the pending "running main"
61 transaction as well. Whenever the application requests a resume on
62 the code, that will start running the END section.
63
64
65 <h2> return path 1.: MAWK_EXER_INT_READ </h2>
66 Assume stdin is a FIFO between the application and the script. The
67 first script tries to prefix each line:
68 <pre>
69 {
70 print "prefix:", $0
71 }
72 </pre>
73 The application fills the FIFO with some data that may contain one or
74 more full records, potentially ending with a partial (unterminated)
75 record. If the application resumes the script, it will try to
76 read all full records and process them. It will interrupt
77 execution and return MAWK_EXER_INT_READ the first time a full
78 record can't be read. This always happens "before the {}".
79 <p>
80 A slightly more complicated script prefixes odd and even lines differently:
81 <pre>
82 {
83 print "odd:", $0
84 getline
85 print "even:", $0
86 }
87 </pre>
88 This script may return with MAWK_EXER_INT_READ either before {}
89 or in the getline instruction. This means the application should not
90 assume that when main returns it was not in the middle of such
91 a block. (In the actual VM main starts with an implicit getline so
92 there's no difference between the two cases).
93 <p>
94 A similar situation is when an awk function is executing getline on a FIFO:
95 the application that calls the function shall not expect that the function
96 finishes and produces its return value in the initial execution request.
97 Instead the request will create a new <i>execution transaction<i> and
98 multiple resume calls may be needed until the function actually returns.
99 <p>
100 Obviously the application shall fill the FIFO while executing resumes:
101 if there is no new input and the script is waiting for new input, the
102 resume call will return immediately.
103
104
105 <h2> return path 2.: <i>MAWK_EXER_INT_RUNLIMIT</i> </h2>
106 When runlimit is set the VM returns after executing a certain amount of
107 instructions. The application shall decide whether to simply resume or
108 to stop executing the script.
109 <p>
110 This feature is useful when the application is implemented as a single
111 threaded async loop: running a blocking script would block the entire loop.
112
113
114 <h2> return path 3.: <i>MAWK_EXER_DONE</i> or <i>MAWK_EXER_FUNCRET</i> </h2>
115 When BEGIN or main or END finishes <i>MAWK_EXER_DONE</i> is returned. When
116 an awk function called by the application returns, <i>MAWK_EXER_FUNCRET</i>
117 is returned and the retc argument is filled with the return value cell
118 (which may be of cell type NOINIT in case there was no return value).
119 <p>
120 The application <b>shall never</b> expect the initial call that
121 created the new <i>execution transaction<i> will end in
122 <i>MAWK_EXER_DONE</i> or <i>MAWK_EXER_FUNCRET</i>; when it does not,
123 a subsequent resume call eventually will.
124
125 <h2> return path 4.: <i>MAWK_EXER_EXIT</i> </h2>
126 Similar to <i>MAWK_EXER_DONE</i>, but means the script called exit.
127 This is legal from even an awk function call, in which case the
128 function will never have a return value (as the code can not be resumed
129 any more). Normal awk rules apply: calling exit() from BEGIN or main
130 (or subsequent functions, called by the script or the application) puts
131 the script in exit mode and next resume will run END. Calling exit from
132 END will exit immediately leaving the script in non-runnable state.
133
134
135 <h2> conclusion: script execution </h2>
136 It is safe to assume calling any script execution will return with
137 a conclusion if, and only if:
138 <ul>
139 <li> the script is not allowed to use getline on FIFOs (which can not be guaranteed!) or there are no FIFOs or otherwise blocking input (i.e. all files are plain files); and
140 <li> there is no run limit configured
141 </ul>
142 <p>
143 Since these are not guaranteed in most common use cases, the code should prepare
144 to:
145 <ul>
146 <li> start executing the code and check if it's already finished
147 <li> resume until it actually does finish
148 <li> if the script returned <i>MAWK_EXER_INT_READ</i>: fill FIFOs or if that's not possible stop resuming as there won't be any progress
149 </ul>
150 <p>
151 Thus following c-pseudo-code should be used:
152 <pre>
153 TODO
154 </pre>
0 <HTML>
1 <BODY>
2 <H1> Table Of Contents </H1>
3 <H2> Manual pages </H2>
4 <UL>
5 <LI> <a href="lmawk.1.html"> lmawk(1) </a> - command line implementation
6 <LI> <a href="example.7libmawk.html"> example(7libmawk) </a> - example on using the library
7 <LI> <a href="libmawk_append_input.3libmawk.html"> libmawk_append_input(3) </a>
8 <LI> <a href="libmawk_call_function.3libmawk.html"> libmawk_call_function(3) </a>
9 <LI> <a href="libmawk_cell_destroy.3libmawk.html"> libmawk_cell_destroy(3) </a>
10 <LI> <a href="libmawk_get_var.3libmawk.html"> libmawk_get_var(3) </a>
11 <LI> <a href="libmawk_initialize.3libmawk.html"> libmawk_initialize(3) </a>
12 <LI> <a href="libmawk_initialize_stage.3libmawk.html"> libmawk_initialize_stage(3) </a>
13 <LI> <a href="libmawk_register_function.3libmawk.html"> libmawk_register_function(3) </a>
14 <LI> <a href="libmawk_run_main.3libmawk.html"> libmawk_run_main(3) </a>
15 <LI> <a href="libmawk_set_cell.3libmawk.html"> libmawk_set_cell(3) </a>
16 <LI> <a href="libmawk_uninitialize.3libmawk.html"> libmawk_uninitialize(3) </a>
17 </UL>
18 <H2> Design decisions </H2>
19 <UL>
20 <LI> <a href="autotools.html"> why not using autotools in libmawk </a>
21 <LI> <a href="portability.html"> portability with scconfig </a>
22 <LI> <a href="semi-gnu.html"> semi-dependency on GNU utils </a>
23 <LI> <a href="numeric.html"> different numeric types and FPE/NaN </a>
24 </UL>
25 </BODY>
26 </HTML>
27
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:30 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_APPEND_INPUT</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_APPEND_INPUT</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#SEE ALSO">SEE ALSO</a><br>
26
27 <hr>
28
29
30 <h2>NAME
31 <a name="NAME"></a>
32 </h2>
33
34
35
36 <p style="margin-left:11%; margin-top: 1em">libmawk_append_input
37 &minus; append a string to an input buffer</p>
38
39 <h2>SYNOPSIS
40 <a name="SYNOPSIS"></a>
41 </h2>
42
43
44 <p style="margin-left:11%; margin-top: 1em"><b>#include
45 &lt;libmawk.h&gt;</b></p>
46
47 <p style="margin-left:11%; margin-top: 1em"><b>void
48 libmawk_append_input(mawk_state_t *</b><i>m</i><b>, const
49 char *</b><i>input_str</i><b>);</b></p>
50
51 <p style="margin-left:11%; margin-top: 1em"><b>void
52 libmawk_append_ninput(mawk_state_t *</b><i>m</i><b>, const
53 char *</b><i>input</i><b>, int</b><i>len</i><b>);</b></p>
54
55 <h2>DESCRIPTION
56 <a name="DESCRIPTION"></a>
57 </h2>
58
59
60 <p style="margin-left:11%; margin-top: 1em">The
61 <b>libmawk_append_input</b>() and
62 <b>libmawk_append_ninput</b>() functions allow the
63 application to fill the input buffer of a libmawk context.
64 No record separator is appended, only the bytes donated by
65 input_str or input, thus it is possible to append partial
66 records. Appending to the input doesn&rsquo;t have the side
67 effect of any script being run. There may be multiple
68 libmawk_append_input() calls before a call to
69 libmawk_run_main(). The latter all is used to let the script
70 process the input buffer.</p>
71
72 <p style="margin-left:11%; margin-top: 1em">The only
73 difference between the two calls are the input format:
74 <b>libmawk_append_input</b>() expects a nul-terminated
75 string, whereas <b>libmawk_append_ninput</b>() takes an
76 arbitrary binary data and its length.</p>
77
78 <p style="margin-left:11%; margin-top: 1em">Argument m is a
79 libmawk context previously returned by libmawk_initialize()
80 or libmawk_initialize_stage3().</p>
81
82 <h2>SEE ALSO
83 <a name="SEE ALSO"></a>
84 </h2>
85
86
87
88 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
89 <b>libmawk_initialize</b>(3libmawk),
90 <b>libmawk_run_main</b>(3libmawk).</p>
91 <hr>
92 </body>
93 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:31 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_CALL_FUNCTION</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_CALL_FUNCTION</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#RETURN VALUE">RETURN VALUE</a><br>
26 <a href="#SEE ALSO">SEE ALSO</a><br>
27
28 <hr>
29
30
31 <h2>NAME
32 <a name="NAME"></a>
33 </h2>
34
35
36
37 <p style="margin-left:11%; margin-top: 1em">libmawk_call_function
38 &minus; call an user defined (script) function</p>
39
40 <h2>SYNOPSIS
41 <a name="SYNOPSIS"></a>
42 </h2>
43
44
45 <p style="margin-left:11%; margin-top: 1em"><b>#include
46 &lt;libmawk.h&gt;</b></p>
47
48 <p style="margin-left:11%; margin-top: 1em"><b>int
49 libmawk_call_function(mawk_state_t *</b><i>MAWK</i><b>,
50 const char *</b><i>fname</i><b>, CELL *</b><i>res</i><b>,
51 const char *</b><i>argtpes</i><b>, ...); <br>
52 int libmawk_call_functionp(mawk_state_t *</b><i>MAWK</i><b>,
53 const char *</b><i>fname</i><b>, CELL *</b><i>res</i><b>,
54 const char *</b><i>argtpes</i><b>, void **args);</b></p>
55
56 <h2>DESCRIPTION
57 <a name="DESCRIPTION"></a>
58 </h2>
59
60
61 <p style="margin-left:11%; margin-top: 1em">The
62 <b>libmawk_call_function</b>() function looks up an user
63 defined awk function called <i>fname</i> , fills the stack
64 with arguments converted from the varargs and calls the
65 function. The <b>libmawk_call_functionp</b>() performs the
66 same action but avoids using vararg by requiring an array of
67 generic pointers to the function arguments.</p>
68
69 <p style="margin-left:11%; margin-top: 1em">Argtype is a
70 zero terminated string for both functions, each character
71 corresponding to an argument. Type characters are described
72 in libmawk_set_cell() manual page.</p>
73
74 <p style="margin-left:11%; margin-top: 1em">If res is
75 non-NULL, it is cell_destroyed (regardless of errors) and
76 the return value of the user function is copied into it. The
77 caller shall run libmawk_cell_destroy on it.</p>
78
79 <p style="margin-left:11%; margin-top: 1em">Argument m is a
80 libmawk context previously returned by libmawk_initialize()
81 or libmawk_initialize_stage3().</p>
82
83 <h2>RETURN VALUE
84 <a name="RETURN VALUE"></a>
85 </h2>
86
87
88 <p style="margin-left:11%; margin-top: 1em">A pointer to
89 the cell returned by the user function. The cell
90 returnedmust be destroyed by the application using
91 libmawk_cell_destroy.</p>
92
93 <h2>SEE ALSO
94 <a name="SEE ALSO"></a>
95 </h2>
96
97
98
99 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
100 <b>libmawk_initialize</b>(3libmawk),
101 <b>libmawk_cell_destroy</b>(3libmawk),
102 <b>libmawk_set_cell</b>(3libmawk),</p>
103 <hr>
104 </body>
105 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:31 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_CELL_DESTROY</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_CELL_DESTROY</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#SEE ALSO">SEE ALSO</a><br>
26
27 <hr>
28
29
30 <h2>NAME
31 <a name="NAME"></a>
32 </h2>
33
34
35
36 <p style="margin-left:11%; margin-top: 1em">libmawk_cell_destroy
37 &minus; free all memory associated with a cell</p>
38
39 <h2>SYNOPSIS
40 <a name="SYNOPSIS"></a>
41 </h2>
42
43
44 <p style="margin-left:11%; margin-top: 1em"><b>#include
45 &lt;libmawk.h&gt;</b></p>
46
47 <p style="margin-left:11%; margin-top: 1em"><b>void
48 libmawk_cell_destroy(mawk_state_t *</b><i>m</i><b>, CELL
49 *</b><i>c</i><b>);</b></p>
50
51 <h2>DESCRIPTION
52 <a name="DESCRIPTION"></a>
53 </h2>
54
55
56 <p style="margin-left:11%; margin-top: 1em">The
57 <b>libmawk_cell_destroy</b>() function frees all memory
58 allocated to store a mawk cell. It is useful with some of
59 the libmawk calls that return a newly allocated cell, such
60 as the libmawk_call_function() call.</p>
61
62 <p style="margin-left:11%; margin-top: 1em">Argument m is a
63 libmawk context previously returned by libmawk_initialize()
64 or libmawk_initialize_stage3().</p>
65
66 <h2>SEE ALSO
67 <a name="SEE ALSO"></a>
68 </h2>
69
70
71
72 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
73 <b>libmawk_initialize</b>(3libmawk),
74 <b>libmawk_call_function</b>(3libmawk).</p>
75 <hr>
76 </body>
77 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:31 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_GET_VAR</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_GET_VAR</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#SEE ALSO">SEE ALSO</a><br>
26
27 <hr>
28
29
30 <h2>NAME
31 <a name="NAME"></a>
32 </h2>
33
34
35
36 <p style="margin-left:11%; margin-top: 1em">libmawk_get_var
37 &minus; returns a pointer to a mawk variable</p>
38
39 <h2>SYNOPSIS
40 <a name="SYNOPSIS"></a>
41 </h2>
42
43
44 <p style="margin-left:11%; margin-top: 1em"><b>#include
45 &lt;libmawk.h&gt;</b></p>
46
47 <p style="margin-left:11%; margin-top: 1em"><b>CELL
48 *libmawk_get_var(mawk_state_t *</b><i>m</i><b>, const char
49 *</b><i>vname</i><b>); <br>
50 int libmawk_get_array_at(mawk_state_t *</b><i>m</i><b>,
51 const char *</b><i>arr_name</i><b>, <br>
52 const char *</b><i>idx</i><b>, const char
53 *</b><i>res</i><b>, int</b> <i>alloc</i><b>);</b></p>
54
55 <h2>DESCRIPTION
56 <a name="DESCRIPTION"></a>
57 </h2>
58
59
60 <p style="margin-left:11%; margin-top: 1em">The
61 <b>libmawk_get_var</b>() function returns a pointer to a
62 mawk cell that represents the global variable with name
63 passed in <i>vname</i> in the given context. The returned
64 CELL should never be free&rsquo;d or destroyed. Function
65 libmawk_print_cell may be used for converting the cell to
66 string. The caller should not change the type of cell but is
67 free to change the value.</p>
68
69 <p style="margin-left:11%; margin-top: 1em">Function
70 <b>libmawk_get_array_at</b>() performs the same operation
71 for an element of an array. -1 is returned if
72 <i>arr_name</i> is not an array or upon an error. If
73 <i>idx</i> is not an existing index in the array it is
74 allocated if <i>alloc</i> is non-zero. If <i>res</i> is not
75 NULL, it is destroyed (regardless of the return value) and
76 if the index exists (or is created by the call), is loaded
77 with the value. The caller needs to destroy <i>res</i> after
78 use. Since <i>res</i> is destroyed when non-NULL, it must be
79 a valid cell with valid type.</p>
80
81 <p style="margin-left:11%; margin-top: 1em">Argument m is a
82 libmawk context previously returned by libmawk_initialize()
83 or libmawk_initialize_stage3().</p>
84
85 <h2>SEE ALSO
86 <a name="SEE ALSO"></a>
87 </h2>
88
89
90
91 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
92 <b>libmawk_initialize</b>(3libmawk),
93 <b>libmawk_call_function</b>(3libmawk),
94 <b>libmawk_print_cell</b>(3libmawk).</p>
95 <hr>
96 </body>
97 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:31 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_INITIALIZE</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_INITIALIZE</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#RETURN VALUE">RETURN VALUE</a><br>
26 <a href="#SEE ALSO">SEE ALSO</a><br>
27
28 <hr>
29
30
31 <h2>NAME
32 <a name="NAME"></a>
33 </h2>
34
35
36
37 <p style="margin-left:11%; margin-top: 1em">libmawk_initialize
38 &minus; create a new libmawk context</p>
39
40 <h2>SYNOPSIS
41 <a name="SYNOPSIS"></a>
42 </h2>
43
44
45 <p style="margin-left:11%; margin-top: 1em"><b>#include
46 &lt;libmawk.h&gt;</b></p>
47
48
49 <p style="margin-left:11%; margin-top: 1em"><b>mawk_state_t
50 *libmawk_initialize(int</b> <i>s</i><b>, char
51 *</b><i>argv[]</i><b>);</b></p>
52
53 <h2>DESCRIPTION
54 <a name="DESCRIPTION"></a>
55 </h2>
56
57
58 <p style="margin-left:11%; margin-top: 1em">The
59 <b>libmawk_initialize</b>() function returns a pointer to a
60 newly created libmawk context. Any amount of libmawk
61 contexts can live in parallel in an application. Arguments
62 are the same as for a command line mawk session. Scripts are
63 loaded (either from command line or from files using -f),
64 variables are set (with -v), special options are set (with
65 -W), etc.</p>
66
67 <h2>RETURN VALUE
68 <a name="RETURN VALUE"></a>
69 </h2>
70
71
72 <p style="margin-left:11%; margin-top: 1em">A pointer to a
73 new libmawk context or NULL on error.</p>
74
75 <h2>SEE ALSO
76 <a name="SEE ALSO"></a>
77 </h2>
78
79
80
81 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
82 <b>libmawk_uninitialize</b>(3libmawk),</p>
83 <hr>
84 </body>
85 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:32 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_INITIALIZE_STAGE</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_INITIALIZE_STAGE</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#RETURN VALUE">RETURN VALUE</a><br>
26 <a href="#SEE ALSO">SEE ALSO</a><br>
27
28 <hr>
29
30
31 <h2>NAME
32 <a name="NAME"></a>
33 </h2>
34
35
36
37 <p style="margin-left:11%; margin-top: 1em">libmawk_initialize_stage*
38 &minus; create a new libmawk context in 3 stages</p>
39
40 <h2>SYNOPSIS
41 <a name="SYNOPSIS"></a>
42 </h2>
43
44
45 <p style="margin-left:11%; margin-top: 1em"><b>#include
46 &lt;libmawk.h&gt;</b></p>
47
48
49 <p style="margin-left:11%; margin-top: 1em"><b>mawk_state_t
50 *libmawk_initialize_stage1(void);</b></p>
51
52
53 <p style="margin-left:11%; margin-top: 1em"><b>mawk_state_t
54 *libmawk_initialize_stage2(mawk_state_t *</b>
55 <i>m,</i><b>int</b> <i>s</i>
56 <b>,</b><i>char</i><b>*&quot;</b><i>argv[]</i><b>);</b></p>
57
58
59 <p style="margin-left:11%; margin-top: 1em"><b>mawk_state_t
60 *libmawk_initialize_stage3(mawk_state_t *</b>
61 <i>m</i><b>);</b></p>
62
63 <h2>DESCRIPTION
64 <a name="DESCRIPTION"></a>
65 </h2>
66
67
68 <p style="margin-left:11%; margin-top: 1em">The
69 <b>libmawk_initialize_stage*</b>() functions together do the
70 same as libmawk_initialize() but allows the application to
71 take actions between different stages.
72 <b>libmawk_initialize_stage1</b>() returns a pointer to a
73 newly created libmawk context. Any amount of libmawk
74 contexts can live in parallel in an application.</p>
75
76
77 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage2</b>()
78 can be called after a succesful stage1 call. <br>
79 Stage2 is responsible for processing the command line
80 arguments and loading any script.</p>
81
82 <p style="margin-left:11%; margin-top: 1em">Arguments are
83 the same as for a command line mawk session. Scripts are
84 loaded (either from command line or from files using -f),
85 variables are set (with -v), special options are set (with
86 -W), etc. Unlike with libmawk_initialize(), the application
87 may decide not to provide any script at this stage. All
88 command line arguments are processed.</p>
89
90 <p style="margin-left:11%; margin-top: 1em">The most common
91 case is that the application calls stage1 with no script,
92 then already having a context makes some manipulations on it
93 (for example registers some C functions that would be
94 already called in the BEGIN part of the script that will be
95 later loaded). Optionally before calling stage2 the
96 application loads the actual script(s) using
97 mawk_append_input_file().</p>
98
99
100 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage3</b>()
101 is called as a final step of the three-stage initialization
102 process. Stage3 is responsible for running all the BEGIN
103 parts of all scripts loaded at stage1 or stage2. It is
104 useful to have stage3 in a separate call to allow
105 applications to manipulate the context right before
106 initializing the scripts.</p>
107
108 <p style="margin-left:11%; margin-top: 1em">Stage2 gets the
109 pointer returned by stage1 and stage3 gets the pointer
110 returned by stage2. Subsequent calls to libmawk functions
111 should get the pointer returned by stage3.</p>
112
113 <h2>RETURN VALUE
114 <a name="RETURN VALUE"></a>
115 </h2>
116
117
118 <p style="margin-left:11%; margin-top: 1em">At stage 1 a
119 pointer to a new libmawk context or NULL on error.
120 Subsequent stages will return the same pointer or NULL on
121 error.</p>
122
123 <h2>SEE ALSO
124 <a name="SEE ALSO"></a>
125 </h2>
126
127
128
129 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
130 <b>libmawk_uninitialize</b>(3libmawk),
131 <b>mawk_append_input_file(3libmawk).</b></p>
132 <hr>
133 </body>
134 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:32 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_REGISTER_FUNCTION</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_REGISTER_FUNCTION</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#RETURN VALUE">RETURN VALUE</a><br>
26 <a href="#SEE ALSO">SEE ALSO</a><br>
27
28 <hr>
29
30
31 <h2>NAME
32 <a name="NAME"></a>
33 </h2>
34
35
36
37 <p style="margin-left:11%; margin-top: 1em">libmawk_register_function
38 &minus; registers a C function with a callback</p>
39
40 <h2>SYNOPSIS
41 <a name="SYNOPSIS"></a>
42 </h2>
43
44
45 <p style="margin-left:11%; margin-top: 1em"><b>#include
46 &lt;libmawk.h&gt;</b></p>
47
48 <p style="margin-left:11%; margin-top: 1em"><b>typedef CELL
49 *libmawk_c_function(mawk_state_t *</b><i>m</i><b>, CELL
50 *</b><i>sp</i><b>, int</b> <i>a_args</i><b>); <br>
51 int libmawk_register_function(mawk_state_t
52 *</b><i>MAWK</i><b>, const char *</b><i>fname</i><b>,
53 libmawk_c_function *</b><i>callback</i><b>); <br>
54 CELL *libmawk_stackret(CELL
55 *</b><i>original_sp</i><b>);</b></p>
56
57 <h2>DESCRIPTION
58 <a name="DESCRIPTION"></a>
59 </h2>
60
61
62 <p style="margin-left:11%; margin-top: 1em">The
63 <b>libmawk_register_function</b>() call registers an user
64 defined function donated by the host application in a mawk
65 context so that it acts exactly like user defined functions
66 in written in awk. The name of the new function is given in
67 <i>fname</i> and should not match any of the user defined
68 function names in the awk script.</p>
69
70 <p style="margin-left:11%; margin-top: 1em">When the user
71 function is called back, argument <i>sp</i> is the stack
72 pointer and <i>a_args</i> holds the number of arguments. The
73 user function is responsible for managing the stack: it
74 should pop all arguments before returning.</p>
75
76 <p style="margin-left:11%; margin-top: 1em">The user
77 function should also generate a return value, which is done
78 by calling libmawk_set_cell() on the stack slot returned by
79 libmawk_stackret. Libmawk_stackret should be called with the
80 modified <i>sp</i> after popping all arguments.</p>
81
82 <p style="margin-left:11%; margin-top: 1em">Argument m is a
83 libmawk context previously returned by libmawk_initialize()
84 or libmawk_initialize_stage3().</p>
85
86 <p style="margin-left:11%; margin-top: 1em">For more
87 information about user function callbacks, especially on
88 stack handling, see manual page example(3libmawk).</p>
89
90 <h2>RETURN VALUE
91 <a name="RETURN VALUE"></a>
92 </h2>
93
94
95 <p style="margin-left:11%; margin-top: 1em">The user
96 function should return the stack pointer after popping all
97 arguments.</p>
98
99 <p style="margin-left:11%; margin-top: 1em">The
100 libmawk_register_function call returns 0 on success.</p>
101
102 <p style="margin-left:11%; margin-top: 1em">Call
103 libmawk_stackret returns a stack pointer to the slot where
104 the user function should store its return value.</p>
105
106 <h2>SEE ALSO
107 <a name="SEE ALSO"></a>
108 </h2>
109
110
111
112 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
113 <b>libmawk_initialize</b>(3libmawk),
114 <b>libmawk_set_cell</b>(3libmawk),
115 <b>libmawk_print_cell</b>(3libmawk).</p>
116 <hr>
117 </body>
118 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:32 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_RUN_MAIN</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_RUN_MAIN</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#SEE ALSO">SEE ALSO</a><br>
26
27 <hr>
28
29
30 <h2>NAME
31 <a name="NAME"></a>
32 </h2>
33
34
35
36 <p style="margin-left:11%; margin-top: 1em">libmawk_run_main
37 &minus; run main parts of a script</p>
38
39 <h2>SYNOPSIS
40 <a name="SYNOPSIS"></a>
41 </h2>
42
43
44 <p style="margin-left:11%; margin-top: 1em"><b>#include
45 &lt;libmawk.h&gt;</b></p>
46
47 <p style="margin-left:11%; margin-top: 1em"><b>void
48 libmawk_run_main(mawk_state_t *</b><i>m</i><b>);</b></p>
49
50 <h2>DESCRIPTION
51 <a name="DESCRIPTION"></a>
52 </h2>
53
54
55 <p style="margin-left:11%; margin-top: 1em">The
56 <b>libmawk_run_main</b>() attempts to take and parse the
57 next input record and runs all main parts of the script that
58 matches. If there are multiple full records in the input
59 buffer, the process repeats until the buffer becomes empty
60 or contains a partial record. If there is no full record in
61 the buffer, the call returns with nothing done. The call
62 itself never blocks, but the script may. The input buffer
63 may be filled using the libmawk_append_input() call.</p>
64
65 <p style="margin-left:11%; margin-top: 1em">Argument m is a
66 libmawk context previously returned by libmawk_initialize()
67 or libmawk_initialize_stage3().</p>
68
69 <h2>SEE ALSO
70 <a name="SEE ALSO"></a>
71 </h2>
72
73
74
75 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
76 <b>libmawk_initialize</b>(3libmawk),
77 <b>libmawk_append_input</b>(3libmawk),</p>
78 <hr>
79 </body>
80 </html>
0 <!-- Creator : groff version 1.22.2 -->
1 <!-- CreationDate: Sat Jun 14 14:27:32 2014 -->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3 "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta name="generator" content="groff -Thtml, see www.gnu.org">
7 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
8 <meta name="Content-Style" content="text/css">
9 <style type="text/css">
10 p { margin-top: 0; margin-bottom: 0; vertical-align: top }
11 pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
12 table { margin-top: 0; margin-bottom: 0; vertical-align: top }
13 h1 { text-align: center }
14 </style>
15 <title>LIBMAWK_SET_CELL</title>
16
17 </head>
18 <body>
19
20 <h1 align="center">LIBMAWK_SET_CELL</h1>
21
22 <a href="#NAME">NAME</a><br>
23 <a href="#SYNOPSIS">SYNOPSIS</a><br>
24 <a href="#DESCRIPTION">DESCRIPTION</a><br>
25 <a href="#RETURN VALUE">RETURN VALUE</a><br>
26 <a href="#SEE ALSO">SEE ALSO</a><br>
27
28 <hr>
29
30
31 <h2>NAME
32 <a name="NAME"></a>
33 </h2>
34
35
36
37 <p style="margin-left:11%; margin-top: 1em">libmawk_set_cell
38 &minus; set the value of a mawk cell.</p>
39
40 <h2>SYNOPSIS
41 <a name="SYNOPSIS"></a>
42 </h2>
43
44
45 <p style="margin-left:11%; margin-top: 1em"><b>#include
46 &lt;libmawk.h&gt;</b></p>
47
48 <p style="margin-left:11%; margin-top: 1em"><b>CELL
49 *libmawk_set_cell(mawk_state_t *</b><i>m</i><b>, CELL
50 *</b><i>cell</i><b>, const
51 char</b><i>argtype</i><b>,</b><i>...</i><b>); <br>
52 CELL *libmawk_set_cellp(mawk_state_t *</b><i>m</i><b>, CELL
53 *</b><i>cell</i><b>, const char</b><i>argtype</i><b>, void
54 *</b><i>argp</i><b>);</b></p>
55
56 <h2>DESCRIPTION
57 <a name="DESCRIPTION"></a>
58 </h2>
59
60
61 <p style="margin-left:11%; margin-top: 1em">The
62 <b>libmawk_set_cell</b>() function modifies the value of a
63 mawk cell (variable). Argumetn argtype is a format character
64 that describes the type of the payload (accessed trough
65 vararg).</p>
66
67 <p style="margin-left:11%; margin-top: 1em">The
68 <b>libmawk_set_cellp</b>() function performs the same action
69 but accepts a generic pointer to the payload.</p>
70
71 <p style="margin-left:11%; margin-top: 1em"><b>Format
72 character</b> is one of the followings: <br>
73 &rsquo;d&rsquo; for int payload <br>
74 &rsquo;f&rsquo; for double payload <br>
75 &rsquo;s&rsquo; for (zero terminated) char * payload.</p>
76
77 <p style="margin-top: 1em">Argument m is a libmawk context
78 previously returned by libmawk_initialize() or
79 libmawk_initialize_stage3().</p>
80
81 <h2>RETURN VALUE
82 <a name="RETURN VALUE"></a>
83 </h2>
84
85
86 <p style="margin-left:11%; margin-top: 1em">A pointer to
87 the cell modified.</p>
88
89 <h2>SEE ALSO
90 <a name="SEE ALSO"></a>
91 </h2>
92
93
94
95 <p style="margin-left:11%; margin-top: 1em"><b>libmawk_initialize_stage</b>(3libmawk),
96 <b>libmawk_initialize</b>(3libmawk),
97 <b>libmawk_get_var</b>(3libmawk).</p>
98 <hr>
99 </body>
100 </html>
+73
-0