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)