Module Name:    othersrc
Committed By:   agc
Date:           Sat Jun  1 22:27:32 UTC 2013

Added Files:
        othersrc/external/historical/eawk/doc: embedding extensions

Log Message:
add preliminary documentation for both extending, and embedding, eawk.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 othersrc/external/historical/eawk/doc/embedding \
    othersrc/external/historical/eawk/doc/extensions

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: othersrc/external/historical/eawk/doc/embedding
diff -u /dev/null othersrc/external/historical/eawk/doc/embedding:1.1
--- /dev/null	Sat Jun  1 22:27:32 2013
+++ othersrc/external/historical/eawk/doc/embedding	Sat Jun  1 22:27:32 2013
@@ -0,0 +1,76 @@
+Embedding eawk in other programs
+================================
+
+It's now possible to use awk from within other programs, such as editors
+and shells, to provide full awk parsing, string manipulation and other
+benefits.
+
+The easiest way to accomplish this is to look at the source in dist/main.c
+
+1. set the defaults with:
+
+	eawk_t		  awk;
+
+	...
+	eawk_setdefaults(&awk, *argv);
+
+2. Set up the file names of any scripts with:
+
+	eawk_setup_scripts(&awk, argc, argv);
+
+(where argc is the number of scripts, and argv are the names of them).
+
+3. And set up the runtime args
+
+	eawk_setup_environment(&awk, argc, argv);
+
+4. Parse awk scripts
+
+	eawk_parse(&awk);
+
+5. Set up any read or write callbacks:
+
+	eawk_set_write_callback(&awk, writerec);
+	eawk_set_read_callback(&awk, readrec, NULL);
+
+The callbacks had previously been declared with:
+
+	/* callback for fetching output text */
+	static ssize_t
+	writerec(char *buf, size_t size)
+	{
+		ssize_t	wc;
+
+		wc = fwrite(buf, 1, size, stdout);
+		fflush(stdout);
+		return wc;
+	}
+
+The writerec callback is called when there is output from eawk. Normally
+this would just be printed on stdout -- and is what this callback does.
+However, it's also possible to send this through other processing, or
+hand to other threads or processes)
+
+	/* callback for fetching input text */
+	static ssize_t
+	readrec(eawk_t *eawk, FILE *fp, void *vp)
+	{
+		char	 buf[BUFSIZ];
+
+		USE_ARG(vp);
+		if (fgets(buf, sizeof(buf), fp) != NULL) {
+			eawk->incc = strlen(buf);
+			memcpy(eawk->inbuf, buf, eawk->incc);
+			return eawk->incc;
+		}
+		return 0;
+	}
+
+The readrec callback is called when eawk is to be given input. There is an
+opaque object in the function signature, in case this is needed to retrieve
+characters. In our case, we are simply taking input from the "fp" file
+descriptor, and transferring it to (a fixed-size buffer in) eawk.
+
+6. Call eawk_run() to do all the processing work:
+
+	eawk_run(&awk);
Index: othersrc/external/historical/eawk/doc/extensions
diff -u /dev/null othersrc/external/historical/eawk/doc/extensions:1.1
--- /dev/null	Sat Jun  1 22:27:32 2013
+++ othersrc/external/historical/eawk/doc/extensions	Sat Jun  1 22:27:32 2013
@@ -0,0 +1,96 @@
+Extending eawk
+==============
+
+To add new functionality to eawk, extensions are used. They can be layered
+on top of each other, and provide access to thirs-party libraries. To write
+and use an extensions, we'll look at the base64 encoding extension in eawk:
+
+-- see extend/base64/base64.c
+
+1. include the header to get definitions
+
+#include "eawk.h"
+
+2. write wrapper functions for every function you want to call from eawk:
+
+	/* base64 encode function */
+	static awkcell_t *
+	eawk_base64_b64encode(void *veawk, char *name, int argc, awkcell_t **a)
+	{
+		eawk_t		*eawk = (eawk_t *)veawk;
+		size_t		 outsize;
+		size_t		 insize;
+		char		*out;
+		char		*in;
+
+		USE_ARG(name);
+		if (argc < 1 || argc > 2) {
+			eawk_setsval(eawk, eawk->fp->retval, "");
+			return eawk->fp->retval;
+		}
+		/* get data off stack */
+		in = eawk_getsval(eawk, a[0]);
+		insize = (argc > 1) ? (size_t)eawk_getfval(eawk, a[1]) : strlen(in);
+		outsize = ((insize * 4) / 3) + 32;
+		out = calloc(1, outsize);
+		outsize = b64encode(in, insize, out, outsize, 0);
+		/* return code */
+		eawk_setsvalN(eawk, eawk->fp->retval, out, outsize);
+		free(out);
+		return eawk->fp->retval;
+	}
+
+argc gives the number of args the awk script used when calling your function
+
+string data is retrieved from the runtime stack with eawk_getsval, args are
+numbered from 0 (and the function name and return value are not counted).
+Numeric data can be retried with eawk_getfval.
+
+When returning args, eawk_setsval is used for strings (and eawk_setsvalN for
+fixed length strings). eawk_setfval is used for numeric data. Arrays can be
+used to receive and send back values, see the regexec() wrapper for an example
+of this.
+
+3.  Finally, the extension mechanism loads the wrapper functions from
+a .so, and the function is accessed using this mechanism.
+
+	int eawk_use_base64(eawk_t */*eawk*/);
+
+	/* register base64 functions */
+	int
+	eawk_use_base64(eawk_t *eawk)
+	{
+		if (eawk_find_lib(eawk, "base64") < 0) {
+			eawk_register_func(eawk, "base64", "b64decode", eawk_base64_b64decode);
+			eawk_register_func(eawk, "base64", "b64encode", eawk_base64_b64encode);
+			eawk_register_func(eawk, "base64", "b85decode", eawk_base64_b85decode);
+			eawk_register_func(eawk, "base64", "b85encode", eawk_base64_b85encode);
+		}
+		return 1;
+	}
+
+The eawk_register_func is the means by which a wrapper function (see
+above) is invoked from an eawk script.  The second arg is the name of
+the library, the third arg the name that is recognised in the script
+to invoke the function, and the last arg is the name of the function
+which we defined earlier.
+
+It's possible for a wrapper function to be called with different
+script function names -- see the lstat and stat wrapper function in
+extend/c/c.c
+
+We also forward declare the 'use' function to avoid compiler warnings -
+
+	int eawk_use_base64(eawk_t */*eawk*/);
+
+it will be invoked automatically using dlopen(3) functionality.
+
+4. An example of its use:
+
+        echo "Another fine mess you got me into" | \
+	env LD_LIBRARY_PATH=lib:extend/base64 bin/eawk '\
+		BEGIN { use("base64") }
+		{ print $0, b64encode($0), b85encode($0) }'
+
+(which is test 23 in the regression test suite, and prints out base64
+and base85 encoding for the input)

Reply via email to