Cobra Inline Programs accessing pattern sets

NAME

Accessing Pattern Sets from Inline Programs

SYNTAX

	add_pattern(N, n, m)
	del_pattern(N, n, m)
	is_pattern(N)
	pattern_exists(N)

DESCRIPTION

Pattern sets are normally defined with query commands (see pe and ps), but they can also be created, and accessed, from within inline Cobra programs. Four predefined functions support this access. (But, see also the builtin function pset for some additional ways to access the matches in a named pattern set.)

In th syntax section above, N is the name of the pattern set, which is either specified as a name, a string, or a string variable, and n and m token references:

Function

	add_pattern(N, n, m);
adds a pattern to pattern set N, creating that pattern set if it does not yet exist. The first lexical token that is part of the pattern to be added is the token referenced by variable n, and the last is the token references by variable m.

Function

	del_pattern(N, n, m);
deletes the first pattern matching the start and end token specified in pattern set N. It is an error if set N does not exist.
Bound variables are not checked for this function.

Function

	is_pattern(N)
returns non-zero if the pattern with name N exists, and zero otherwise. It has no side-effects (i.e., it will not create the pattern if it does not exist).
A synonym of is_pattern(N) is pattern_exists(N).

EXAMPLES

Adding a pattern to an existing set is simple:
	$ cobra cobra_list.c
	1 core, 1 files, 1192 tokens
	: pe A: while ( .* )
	1 pattern stored in set 'A'
	%{
		a = Begin; # make up an arbitrary new match sequence
		b = Begin.nxt;
		add_pattern(A, a, b);	# add it to set A
		Stop;
	%}
	: dp A		# now has 2 patterns
	1: cobra_list.c:7..7
		7  #include "cobra.h"
	2: cobra_list.c:206..206
		206          while (p)
	2 patterns
	:
An example of a case where we want to refine a search by deleting selected patterns could be as follows. Here we look for a pattern where a locally defined array variable (bound to meta variable x) is used as an actual parameter in a function call, where we use a pattern set constraint to exclude calls to the library function memset.
	pe C1: { .* @type x:@ident \[ .* \] .* @ident <1> ( .* :x .* ) \; .* } @1 (.txt != "memset")
We now want to refine this pattern set by removing local declarations marked as extern. There are of course more direct ways to do the same, but this can illustrate the principle.
	%{
		p = pset(C1);
		while (p.seq != 0)
		{	v = p.p_bdef;	# def of bound variable x:@ident
			v = v.prv;	# @type
			v = v.prv;	# . @type x:@ident
			if (v.txt == "extern")
			{	ff = p.p_start;
				tt = p.p_end;
				del_pattern(C1, ff, tt);	# omit match
			}
			p = p.nxt;
		}
		Stop;
	%}
Note that the pattern match is deleted from the pattern-set itself, not from the list returned by the pset command.

NOTES

If functions add_pattern or del_pattern are used for a pattern set that was previously copied with a pset command, the copied structure is not automatically updated, and keeps referring to the elements at the time the copy was created. A new pset call will copy the updated structure. A repeated pset that is issued without changes having been made to the pattern set will not create a new version of the sequence, but return the old instance.

SEE ALSO

functions_predefined, pset

Inline Programs
Manual
Tutorial
(Last Updated: 22 June 2024)