<!-- Creator : groff version 1.22.2 -->
<!-- CreationDate: Sat Jun 14 14:27:30 2014 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="generator" content="groff -Thtml, see www.gnu.org">
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="Content-Style" content="text/css">
<style type="text/css">
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
h1 { text-align: center }
</style>
<title>EXAMPLE</title>
</head>
<body>
<h1 align="center">EXAMPLE</h1>
<a href="#NAME">NAME</a><br>
<a href="#SYNOPSIS">SYNOPSIS</a><br>
<a href="#DESCRIPTION">DESCRIPTION</a><br>
<a href="#Example application">Example application</a><br>
<hr>
<h2>NAME
<a name="NAME"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">libmawk example
− how to use the library</p>
<h2>SYNOPSIS
<a name="SYNOPSIS"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em"><b>#include
<libmawk.h></b></p>
<h2>DESCRIPTION
<a name="DESCRIPTION"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">Libmawk is a
library that lets applications to embed awk scripts using
the code of the popular implementation <b>mawk.</b> The
normal process is to call libmawk_initialize() to set up a
new mawk context (with script(s) loaded), then in the main
loop feed it using libmawk_append_input(). For "out of
band" communication, the program may also call
functions implemented in awk and read (or modify) global
variables of the awk script. The hos tapplication usally
will also bind some of its functions to the context using
libmawk_register_function, which allows the awk script to
call the host applicaiton’s functions directly as they
were awk builtins or user defined functions. After the main
loop, the application destroys the context freeing up all
memory allocated for the script(s).</p>
<p style="margin-left:11%; margin-top: 1em">One context is
for one awk program. One awk program may consist of multiple
script files (just as with command line awk, with multiple
-f filename arguments). Libmawk is instance safe, the host
application may create multiple instances of contexts with
the same or with different set of awk scripts loaded. These
contexts are totally separate, no variables, functions or
any sort of states are shared. However, the host application
may provide means of communication between those scripts by
custom functions or by copying variable contents between
them.</p>
<h2>Example application
<a name="Example application"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">The following
example application creates a single context to demonstrate
all the above mentioned functionality. <br>
#include <stdio.h> <br>
#include <libmawk.h></p>
<p style="margin-left:11%; margin-top: 1em">CELL
*blobb(mawk_state_t *context, CELL * sp, int a_args) <br>
{</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>int n;</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>char buff[64];</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>/* do something - print BLOBB and all arguments */</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>printf("BLOBB! ");</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>for(n = a_args-1; n >= 0; n--)</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>printf("%d=’%s’ ", n,
libmawk_print_cell((sp-n), buff, sizeof(buff)));</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>printf("0);</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>/* restore the stack (remove all arguments) */</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>sp = sp - a_args;</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>/* set a return value (find out where the return value
is on the stack,</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>using libmawk_stackret()) */</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>libmawk_set_cell(context, libmawk_stackret(sp),
’f’, (double)1234);</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>/* return the new stack pointer - should be the one that
it was before</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>arguments had been pushed on the stack */</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>return sp;</p></td>
<td width="77%">
</td></tr>
</table>
<p style="margin-left:11%;">}</p>
<p style="margin-left:11%; margin-top: 1em">int main(int
argc, char **argv) <br>
{</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>mawk_state_t *m;</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>CELL ret, arrv, *vr;</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>char buff[64];</p></td></tr>
</table>
<p style="margin-left:11%; margin-top: 1em">/* the simpler
way is:</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>m = libmawk_initialize(argc, argv);</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>However, if the application wants to change the
environment before</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="92%">
<p>executing BEGIN, the following, 3 stage initialization
should be done:</p></td></tr>
</table>
<p style="margin-left:11%;">*/</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>m = libmawk_initialize_stage1(); /* set up m */</p></td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>custom_array_init(m); /* set up a new builtin array with
side effects, before parsing scripts */</p></td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>m = libmawk_initialize_stage2(m, argc, argv); /* parse
args loads the script(s) */</p></td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>m = libmawk_initialize_stage3(m); /* execute BEGIN {}
*/</p> </td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>ret.type = C_NOINIT;</p></td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%"></td>
<td width="8%">
<p>if (m != NULL) {</p></td>
<td width="8%"></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* test function call */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>if (libmawk_call_function(m, "func", &ret,
"dfs", (int)42, (double)1.234, (char *)"test
string.") == 0) {</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>printf("Return value of func is ’%s’0,
libmawk_print_cell(&ret, buff, sizeof(buff)));</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>libmawk_cell_destroy(m, &ret);</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>}</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>printf("Failed to call func()0);</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* this is the same function call with a different
syntax */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>{</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>int i = 42;</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>double d = 1.234;</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>char *s = "test string.";</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>void *args[] = {&i, &d, s};</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>if (libmawk_call_functionp(m, "func",
&ret, "dfs", args) != 0) {</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
</td>
<td width="62%">
<p>printf("Return value of func is ’%s’0,
libmawk_print_cell(&ret, buff, sizeof(buff)));</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
</td>
<td width="62%">
<p>libmawk_cell_destroy(m, &ret);</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>}</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>}</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* register a C function (resolved runtime) */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>if (libmawk_register_function(m, "blobb",
blobb) != 0) {</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>fprintf(stderr, "ERROR: Unable to register function
blobb0);</p> </td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>}</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* run some data */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>libmawk_append_input(m, "This is a0ultiline test
input0ut in the artificial input buffer.0);</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>libmawk_run_main(m);</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* print var: scalar */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>vr = libmawk_get_var(m, "var");</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>if (vr != NULL)</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>printf("Variable var = ’%s’0,
libmawk_print_cell(vr, buff, sizeof(buff)));</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>else</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="7%">
<p>printf("No such variable</p></td>
<td width="62%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* print var: array */</p></td>
<td width="7%"></td>
<td width="62%">
</td></tr>
</table>
<p style="margin-left:11%;">#warning TODO</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>arrv.type = C_NOINIT;</p></td>
<td width="69%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>if (libmawk_get_array_at(m, "arr",
"hello", &arrv, 0) > 0)</p></td>
<td width="69%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="69%">
<p>printf("Variable arr[</p></td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>else</p></td>
<td width="69%">
</td></tr>
<tr valign="top" align="left">
<td width="8%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="69%">
<p>printf("No such variable</p></td></tr>
</table>
<p style="margin-left:11%; margin-top: 1em">#warning todo:
array set</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* set var: array; change the existing
(arr["hello"]) */</p></td>
<td width="69%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
<p>//</p></td>
<td width="8%">
</td>
<td width="8%">
<p>if (ret != NULL)</p></td>
<td width="69%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
<p>//</p></td>
<td width="8%">
</td>
<td width="8%">
</td>
<td width="69%">
<p>libmawk_set_cell(m, ret, ’s’,
"WORLD");</p> </td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="8%">
<p>/* set var: array; create a new index */</p></td>
<td width="69%">
</td></tr>
</table>
<p style="margin-left:11%;">#warning todo: array set</p>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
<p>//</p></td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_get_array_at(m, "arr",
"bye", &arrv, 1);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
<p>//</p></td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_set_cell(m, ret, ’s’,
"universe");</p> </td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>/* run some more data */</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_append_input(m, "Second0);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_append_input(m, "run.0);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_run_main(m);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>custom_array_print(m);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>/* run end */</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>libmawk_uninitialize(m);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%"></td>
<td width="8%">
<p>}</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%"></td>
<td width="8%">
<p>else {</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%">
</td>
<td width="8%">
</td>
<td width="77%">
<p>printf("Init failed.0);</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%"></td>
<td width="8%">
<p>}</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%"></td>
<td width="8%">
<p>printf("END0);</p></td>
<td width="77%">
</td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="-3%"></td>
<td width="7%"></td>
<td width="8%">
<p>return 0 ;</p></td>
<td width="77%">
</td></tr>
</table>
<p style="margin-left:11%;">}</p>
<hr>
</body>
</html>