CFPEEK |
|
CFPEEK |
Sergey Poznyakoff |
Cfpeek
offers a scripting facility, which can be used to
easily extend its functionality beyond the basic operations, described
in previous chapters. Scripts must be written in Scheme, using ‘Guile’,
the GNU’s Ubiquitous Intelligent Language for Extensions. For
information about the language, refer to Revised(5)
Report on the Algorithmic Language Scheme. For a detailed
description of Guile and its features, see
Overview in The Guile Reference Manual.
This section assumes that the reader has sufficient knowledge about this programming language.
The scripting facility is enabled by the use of the --expression
(-e) of --file (-f command line options.
The --expression (-e) option takes as its argument a
Scheme expression, which will be executed for each statement matching
the supplied keys (or for each statement in the tree, if no keys were
supplied). The expression can obtain information about the statement
from the global variable node
, which represents a node in the
parse tree describing this statement. The node contains complete
information about the statement, including its location in the source
file, its type and neighbor nodes, etc. A number of functions is
provided to retrieve that information from the node. These functions
are discussed in detail in Scripting.
Let’s start from the simplest example. The following command prints all nodes in the file:
$ cfpeek --expression='(display node)(newline)' sample.conf #<node .user: "smith"> #<node .group: "mail"> #<node .pidfile: "/var/run/example"> #<node .logging.facility: "daemon"> #<node .logging.tag: "example"> #<node .program="a".command: "a.out"> #<node .program="a".logging.facility: "local0"> #<node .program="a".logging.tag: "a"> #<node .program="b".command: "b.out"> #<node .program="b".wait: "yes"> #<node .program="b".pidfile: "/var/run/b.pid">
The format shown in this example is the default Scheme representation for nodes. You can use accessor functions to format the output to your liking. For instance, the function ‘grecs-node-locus’ returns the location of the node in the input file. The returned value is a cons, with the file name as its car and the line number as its cdr. Thus, you can print statement locations with the following command:
cfpeek --expr='(let ((loc grecs-node-locus)) (format #t "~A:~A~%" (car loc) (cdr loc)))' \ sample.conf
Complex expressions are cumbersome to type in the command line,
therefore the --file (-f) option is provided. This
option takes the name of the script file as its argument. This file
must define the function named cfpeek
which takes a node as its
argument. The script file is then loaded and the cfpeek
function is called for each matching node.
Now, if we put the expression used in the previous example in a script file (e.g. locus.scm):
(define (cfpeek node) (let ((loc grecs-node-locus)) (format #t "~A:~A~%" (car loc) (cdr loc))))
then the example can be rewritten as:
$ cfpeek -f locus.scm sample.conf
When both --file and --expression options are used in the
same invocation, the cfpeek
function is not invoked by default.
In fact, it even does not need to be defined. When used this way,
cfpeek
first loads the requested script file, and then
applies the expression to each matching node, the same way it always
does when --expression is supplied. It is the responsibility of
the expression itself to call any function or functions defined in the
file. This way of invoking ‘cfpeek’ is useful for supplying
additional parameters to the script. For example:
$ cfpeek -f script.scm -e '(process-node node #t)' input.conf
It is supposed that the function process-node
is defined
somewhere in script.scm and takes two arguments: a node and a
boolean.
The --init=expr (-i expr) option provides an initialization expression expr. This expression is evaluated once, after loading the script file, if one is specified, and before starting the main loop.
Similarly, the option --done=expr (-d expr) introduces a Scheme expression to be evaluated at the end of the run, after all nodes have been processed.
This document was generated on January 7, 2021 using makeinfo.
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.