• No results found

C Support Libraries

In document HANDBOOK OF APPLIED CRYPTOGRAPHY pdf (Page 195-200)

Tree Library

The AST tree library, in lib/astlib.c, is used in transform mode to perform tree rewriting, although some of them may be useful in nontransform mode.

ast_append

void ast_append(a,b). Add b to the end of a’s sibling list. Appending a

NULL pointer is illegal.

*ast_bottom

AST *ast_bottom(a). Find the bottom of a’s child list (going straight down).

*ast_cut_between

AST *ast_cut_between(a,b). Unlink all siblings between a and b and return a pointer to the first element of the sibling list that was unlinked. Basically, all this routine does is to make a point to b and make sure that the tail of the sibling list, which was unlinked, does not point to b. The routine ensures that a and b are (perhaps indirectly) connected to start with.

ast_insert_after

void ast_insert_after(a,b). Add subtree b immediately after a as its sibling. If b is a sibling list at its top level, then the last sibling of b points to the previous right sibling of a.Inserting a NULL pointer has no effect.

*ast_find_all

AST *ast_find_all(t, u, cursor). Find all occurrences of u in t. cursor (a pointer to an AST pointer) must be initialized to t. It eventually returns NULL when no more occurrences of u are found. This function is useful for iterating over every occurrence of a particular subtree. For example,

/* find all scalar assignments withing a statement list */ AST *scalar_assign = #( #[Assign], #[Var] );

AST *cursor = statement_list;

while ((p=ast_find_all(statement_list, scalar_assign, &cursor))) {

/* perform an operation on ’p’ */ }

where ast_node() (the function invoked by references to #[]) is assumed to take a single argument—a token type—and assignments are structured as:

Assign

This function does not seem to work if you make nested calls to it; i.e., a loop containing an ast_find_all() which contains another call to

ast_find_all().

ast_free

void ast_free(t). Recursively walk t, freeing all the nodes in a depth-first order. This is perhaps not very useful because more than a free() may be required to properly destroy a node.

*ast_make

AST *ast_ make(root, child1, ..., childn, NULL). Create a tree

with root as the root of the specified n children. If root is NULL, then a sibling list is constructed. If childi is a list of sibling, then childi+1 will be attached to the last sibling of childi. Any NULL childi results in childi-1 being the last sibling. The root must not have children to begin with.

A shorthand can be used in a description read by SORCERER:

#(root, child_1, ..., child_n) } ast_match

int ast_match(t,u). Returns true if t and u are the same (the trees have the same tree structure and tokenSORAST fields); else it returns false. If both trees are NULL, true is returned.

ast_match_partial

int ast_match_partial(t,u). Returns true if u matches t (beginning at root), but u can be smaller than t (i.e., a subtree of t).

ast_nsiblings

int ast_nsiblings(t). Returns the number of siblings of t.

ast_scan

int ast_scan(template, t, labelptr1, ..., labelptrn). This

function is analogous to scanf. It tries to match tree t against template and return the number of labels that were successfully mapped. The template is a string consisting of a SORCERER tree description with an optional set of node labels. For every label specified in template, the address of a SORAST pointer must be passed. Upon return from ast_scan(), the pointers will point to the requested nodes in t. This function can only be conveniently used from within a SORCERER description file and requires the use of the #tokdefs directive; it can be used in nontransform mode. Consider the following example.

n = ast_scan("#( %1:A %2:B %3:C )", t, &x, &y, &z);

which SORCERER converts to before the call to ast_scan()}:

n = ast_scan("#( %1:7 %2:8 %3:9 )", t, &x, &y, &z);

where the token types of A, B, and C are 7, 8, and 9, respectively. After the call, pointers x, y, and z will point to the root, the first child and the second child, respectively; n will be 3.

C Programming Interface

The order of label specification in template is not significant.

*ast_sibling_index

AST *ast_sibling_index(t,i). Return a pointer to the ith sibling where the sibling to the right of t is i==2. A index of i==1, returns t.

*ast_tail

AST *ast_tail(a). Find the end of a’s sibling list and return a pointer to it.

*ast_to_slist

SList *ast_to_slist(t). Return a list containing the siblings of t. This can be useful for walking a list of subtrees without having to parse it. For example,

<<SList *stats;>> slist

: ( stat )* <<stats = ast_to_list(_root);>> ;

where _root is the argument passed to every function that points to the input tree node. In this case, the variable stats will be a list with an element (SORAST *) for each statement in the statement list.

*slist_to_ast

AST *slist_to_ast(list). Return a tree composed of the elements of

list with a sibling for each element in list.

List Library

The SORCERER list library, lib/sorlist.c, is a simple linked-list manager that makes lists of pointers. The pointer for a new list must be initialized to NULL as any non-empty list has a sentinel node whose elem field pointer is really a pointer to the last element.

*slist_iterate

void *slist_iterate(list,cursor). Iterate over a list of elements in

list; return a pointer to a new element in list upon every call and NULL when no more are left. It can be used like this:

cursor = mylist;

while ( (p=slist_iterate(mylist,\&cursor)) ) { /* place with element p */

}

Lists can also be traversed with

SList *p;

for (p = list->next; p!=NULL; p=p->next) {

slist_add

void slist_add(list, e). Add element e to list . Any non-empty list has a sentinel node whose elem pointer is really a pointer to the last element. Elements are appended to the list. For example,

SList *Strings = NULL; list_add(&Strings, "hi"); list_add(&Strings, "there"); slist_free

void slist_free(list). Free a list (frees all of the nodes used to hold pointers to actual elements). It does not effect the elements tracked by the list.

Stack Library

The SORCERER stack library, lib/sstack.c, is a simple linked-list style stack of pointers. There is no sentinel node, and a pointer for a stack must be initialized to NULL

initially.

sstack_push

void sstack_push(st,e). Push element e on stack st where e can be a pointer to any object. For example,

SStack *st = NULL;

sstack_push(&st, "I push");

sstack_push(&st, "therefore, I’m a stack"); *sstack_pop

void *sstack_pop(st). Pop the top element off of stack st and return it. For example,

SStack *st = NULL; char *s;

sstack_push(&st, "over the edge"); s = sstack_pop(&st);

printf("%s\n", s);

should print "over the edge".

Integer Stack Library

The SORCERER SIntStack library, lib/sintstack.c, is a simple array-based stack of integers. Stacks of integers are common (such as saving the scope/level of programming language); hence, we have constructed a stack which is much easier to use and faster than the normal stack routines. Overflow and underflow conditions are trapped.

*sint_newstack

SIntStack *sint_newstack(size). Make a new stack with a maximum depth of size and return a pointer to it.

C Programming Interface

sint_freestack

void sint_freestack(SIntStack *st). Destroys a stack created by

sint_newstack().

sint_push

void sint_push(st, i). Push integer i onto stack st. For example,

SIntStack *st = sint_newstack(100); sint_push(st, 42);

sint_push(st, 3); sint_pop

int sint_pop(st). Pop the top integer off the stack and return it.

SIntStack *st = sint_newstack(10); sint_push(st, 3);

printf("%d\n", sint_pop(st));

would print "3".

sint_stacksize

int sint_stacksize(st). Returns the number of integers currently on the stack.

sint_stackreset

void sint_stackreset(st). Remove all integers from the stack.

sint_stackempty

int sint_stackempty(st). Returns true if there are no integers on stack st.

sint_top

int sint_top(st). Return the top integer on the stack without affecting the state of the stack.

In document HANDBOOK OF APPLIED CRYPTOGRAPHY pdf (Page 195-200)