ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
Semantic Trees

Semantic trees are the basic data building block for ceptr. More...

Files

file  label.c
 Implementation of label tabels for semantic reference to parts of semantic trees.
 
file  label.h
 Label tables map human readable text strings to parts of semantic trees.
 
file  mtree.c
 semantic tree matrix implementation
 
file  mtree.h
 semantic tree matrix header file ``
 
file  tree.c
 semantic tree pointer implementation
 
file  tree.h
 semantic trees header file
 

Macros

#define TREE_CHILDREN_BLOCK   5
 
#define TREE_PATH_TERMINATOR   0xFFFFFFFF
 
#define _t_new(p, sy, su, s)   __t_new(p,sy,su,s,0)
 
#define _t_newc(parent, symbol, c)   __t_newc(parent,symbol,c,0)
 
#define _t_newi(p, sy, su)   __t_newi(p,sy,su,0)
 
#define _t_newi64(p, sy, su)   __t_newi64(p,sy,su,0)
 
#define _t_news(parent, symbol, surface)   __t_news(parent,symbol,surface,0)
 
#define _t_new_str(parent, symbol, str)   __t_new_str(parent,symbol,str,0)
 
#define _t_newr(p, s)   __t_newr(p,s,0)
 
#define _t_fill_template(t, i)   __t_fill_template(t,i,false)
 
#define _t_find(t, sym)   __t_find(t,sym,1)
 
#define DO_KIDS(t, x)   {int i,_c=_t_children(t);for(i=1;i<=_c;i++){x;}}
 
#define root_check(c)   if (c->structure.parent != 0) {raise_error("can't add a node that isn't a root!");}
 

Enumerations

enum  TreeSurfaceFlags {
  TFLAG_ALLOCATED =0x0001, TFLAG_SURFACE_IS_TREE =0x0002, TFLAG_SURFACE_IS_RECEPTOR = 0x0004, TFLAG_SURFACE_IS_SCAPE =0x0008,
  TFLAG_SURFACE_IS_CPTR =0x0010, TFLAG_DELETED =0x0020, TFLAG_RUN_NODE =0x0040, TFLAG_REFERENCE =0x8000
}
 

Functions

T__t_new (T *t, Symbol symbol, void *surface, size_t size, bool is_run_node)
 
T__t_newc (T *t, Symbol symbol, char c, bool is_run_node)
 
T__t_newi (T *parent, Symbol symbol, int surface, bool is_run_node)
 
T__t_newi64 (T *parent, Symbol symbol, long surface, bool is_run_node)
 
T__t_news (T *parent, Symbol symbol, SemanticID surface, bool is_run_node)
 
T_t_newt (T *parent, Symbol symbol, T *t)
 
T__t_new_str (T *parent, Symbol symbol, char *str, bool is_run_node)
 
T_t_new_root (Symbol symbol)
 
T__t_newr (T *parent, Symbol symbol, bool is_run_node)
 
T_t_new_receptor (T *parent, Symbol symbol, Receptor *r)
 
T_t_new_scape (T *parent, Symbol symbol, Scape *s)
 
T_t_new_cptr (T *parent, Symbol symbol, void *s)
 
T_t_newp (T *parent, Symbol symbol, Process surface)
 
void _t_add (T *t, T *c)
 
void _t_detach_by_ptr (T *t, T *c)
 
T_t_detach_by_idx (T *t, int i)
 
void _t_replace (T *t, int i, T *r)
 
void _t_replace_node (T *t, T *r)
 
T_t_swap (T *t, int i, T *r)
 
void _t_insert_at (T *t, int *path, T *i)
 
void _t_morph (T *dst, T *src)
 
void __t_morph (T *t, Symbol s, void *surface, size_t length, int allocate)
 
void __t_free_children (T *t)
 
void __t_free (T *t)
 
void _t_free (T *t)
 
T_t_clone (T *t)
 
T_t_rclone (T *t)
 
T_t_build (SemTable *sem, T *t,...)
 
T_t_build2 (SemTable *sem, T *t,...)
 
T__t_tokenize (char *s)
 
T_t_parse (SemTable *sem, T *parent, char *s,...)
 
bool __t_fill_template (T *template, T *items, bool as_run_node)
 
int _t_children (T *t)
 
void * _t_surface (T *t)
 
Symbol _t_symbol (T *t)
 
size_t _t_size (T *t)
 
T_t_parent (T *t)
 
T_t_child (T *t, int i)
 
T_t_root (T *t)
 
T_t_next_sibling (T *t)
 
int _t_node_index (T *t)
 
T__t_find (T *t, Symbol sym, int start_child)
 
int _t_path_equal (int *p1, int *p2)
 
int _t_path_depth (int *p)
 
void _t_pathcpy (int *dst_p, int *src_p)
 
T_t_get (T *t, int *p)
 
T_t_getv (T *t,...)
 
int * _t_get_path (T *t)
 
void * _t_get_surface (T *t, int *p)
 
char * _t_sprint_path (int *fp, char *buf)
 
T_t_path_walk (T *t, int **pathP, int *lenP)
 
TreeHash _t_hash (SemTable *sem, T *t)
 
int _t_hash_equal (TreeHash h1, TreeHash h2)
 
UUIDt __uuid_gen ()
 
int __uuid_equal (UUIDt *u1, UUIDt *u2)
 
size_t __t_serialize (SemTable *sem, T *t, void **bufferP, size_t offset, size_t current_size, int compact)
 
void _t_serialize (SemTable *sem, T *t, void **surfaceP, size_t *sizeP)
 
T_t_unserialize (SemTable *sem, void **surfaceP, size_t *lengthP, T *t)
 
char * _t2rawjson (SemTable *sem, T *t, int level, char *buf)
 
char * _t2json (SemTable *sem, T *t, int level, char *buf)
 
int _t_write (SemTable *sem, T *t, Stream *stream)
 

Detailed Description

Semantic trees are the basic data building block for ceptr.

Everything in ceptr is built out of semantic trees. In ceptr all data is assumed to be meaningfull, not just structured.

Function Documentation

bool __t_fill_template ( T template,
T sem_map,
bool  as_run_node 
)

replace SLOTS in a template with the replacement values from links in a SEMANTIC_MAP tree ;

Parameters
[in,out]templatethe tree with SLOTs to be filled
[in]sem_mapmappings used to fill the template
Returns
boolean indicating whether fill resulted in templates removal
Note
the template is modified in place, so the caller may need to clone a source template

Examples (from test suite):

// test filling a value slot
T *template = _t_parse(G_sem,0,"(PATTERN (SEMTREX_SYMBOL_LITERAL (SLOT (USAGE:REQUEST_TYPE) (SLOT_IS_VALUE_OF:SEMTREX_SYMBOL))))");
T *sem_map = _t_parse(G_sem,0,"(SEMANTIC_MAP (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (ACTUAL_SYMBOL:PING))))");
_t_fill_template(template,sem_map);
spec_is_str_equal(t2s(template),"(PATTERN (SEMTREX_SYMBOL_LITERAL (SEMTREX_SYMBOL:PING)))");
_t_free(template);
_t_free(sem_map);
// test filling a value slot of a non leaf node
template = _t_build(G_sem,0,REQUEST,SLOT,ROLE,RESPONDER,SLOT_IS_VALUE_OF,TO_ADDRESS,NULL_SYMBOL,SLOT,USAGE,REQUEST_TYPE,NULL_SYMBOL,SLOT,USAGE,REQUEST_TYPE,NULL_SYMBOL,NULL_SYMBOL);
spec_is_str_equal(t2s(template),"(process:REQUEST (SLOT (ROLE:RESPONDER) (SLOT_IS_VALUE_OF:TO_ADDRESS)) (SLOT (USAGE:REQUEST_TYPE)) (SLOT (USAGE:REQUEST_TYPE)))");
sem_map = _t_parse(G_sem,0,"(SEMANTIC_MAP (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (ACTUAL_SYMBOL:PING))) (SEMANTIC_LINK (ROLE:RESPONDER) (REPLACEMENT_VALUE (ACTUAL_RECEPTOR (RECEPTOR_ADDR:3)))))");
_t_fill_template(template,sem_map);
spec_is_str_equal(t2s(template),"(process:REQUEST (TO_ADDRESS (RECEPTOR_ADDR:3)) (PING) (PING))");
_t_free(template);
_t_free(sem_map);
// test filling a structure slot
template = _t_parse(G_sem,0,"(PATTERN (SEMTREX_SYMBOL_LITERAL (SLOT (USAGE:REQUEST_TYPE))))");
sem_map = _t_parse(G_sem,0,"(SEMANTIC_MAP (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (SEMTREX_SYMBOL:PING))))");
_t_fill_template(template,sem_map);
spec_is_str_equal(t2s(template),"(PATTERN (SEMTREX_SYMBOL_LITERAL (SEMTREX_SYMBOL:PING)))");
_t_free(template);
_t_free(sem_map);
// test filling a slot that has specified children (which might also have SLOT)
template = _t_parse(G_sem,0,"(SLOT (GOAL:RESPONSE_HANDLER) (SLOT_CHILDREN (TEST_INT_SYMBOL:1) (SLOT (USAGE:REQUEST_TYPE))))");
sem_map = _t_parse(G_sem,0,"(SEMANTIC_MAP (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (TEST_INT_SYMBOL:32))) (SEMANTIC_LINK (GOAL:RESPONSE_HANDLER) (REPLACEMENT_VALUE (ACTUAL_PROCESS:ADD_INT))))");
_t_fill_template(template,sem_map);
spec_is_str_equal(t2s(template),"(process:ADD_INT (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:32))");
_t_free(template);
_t_free(sem_map);
// test filling a slot with nothing
template = _t_parse(G_sem,0,"(SLOT (GOAL:RESPONSE_HANDLER) (SLOT_CHILDREN (TEST_INT_SYMBOL:1) (SLOT (USAGE:REQUEST_TYPE)) (TEST_INT_SYMBOL:2)))");
sem_map = _t_parse(G_sem,0,"(SEMANTIC_MAP (SEMANTIC_LINK (USAGE:REQUEST_TYPE) (REPLACEMENT_VALUE (NULL_SYMBOL))) (SEMANTIC_LINK (GOAL:RESPONSE_HANDLER) (REPLACEMENT_VALUE (ACTUAL_PROCESS:ADD_INT))))");
_t_fill_template(template,sem_map);
spec_is_str_equal(t2s(template),"(process:ADD_INT (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:2))");
_t_free(template);
_t_free(sem_map);

Definition at line 1049 of file tree.c.

T* __t_find ( T t,
SemanticID  sym,
int  start_child 
)

search the children of a tree for symbol matching sym

Parameters
[in]tthe tree
[in]symthe SemanticID to search for
[in]start_childindex of the child at which to start the search
Returns
the found node or NULL

Definition at line 1328 of file tree.c.

void __t_morph ( T t,
Symbol  s,
void *  surface,
size_t  size,
int  allocate 
)

Convert the surface of a node

Frees the original surface value if it was allocated.

Note
only converts the type and surface, not the children!
Parameters
[in]tNode to be morphed
[in]sSymbol to change the surface to
[in]surfacedata to copy into the surface
[in]sizeof data
[in]allocateboolean to know whether to allocate surface or copy the surface as an int

Examples (from test suite):

T *x = _t_new(0,TEST_STR_SYMBOL,"fish",5);
int i = 789;
__t_morph(x,TEST_INT_SYMBOL,&i,sizeof(int),0);
spec_is_str_equal(t2s(x),"(TEST_INT_SYMBOL:789)");
_t_free(x);
Todo:
Handle the case where the surface of the node to be morphed is itself a tree

Definition at line 325 of file tree.c.

T* __t_new ( T parent,
Symbol  symbol,
void *  surface,
size_t  size,
bool  is_run_node 
)

Create a new tree node

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacepointer to node's data
[in]sizesize in bytes of the surface
Returns
pointer to node allocated on the heap

Definition at line 59 of file tree.c.

T* __t_new_str ( T parent,
Symbol  symbol,
char *  surface,
bool  is_run_node 
)

Create a new tree node with a cstring surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacestring value to store in the surface
Returns
pointer to node allocated on the heap

Definition at line 150 of file tree.c.

T* __t_newc ( T parent,
Symbol  symbol,
char  surface,
bool  is_run_node 
)

Create a new tree node with an char surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacechar value to store in the surface
Returns
pointer to node allocated on the heap

Definition at line 85 of file tree.c.

T* __t_newi ( T parent,
Symbol  symbol,
int  surface,
bool  is_run_node 
)

Create a new tree node with an integer surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfaceinteger value to store in the surface
Returns
pointer to node allocated on the heap

Definition at line 97 of file tree.c.

T* __t_newi64 ( T parent,
Symbol  symbol,
long  surface,
bool  is_run_node 
)

Create a new tree node with an long surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacelong integer value to store in the surface
Returns
pointer to node allocated on the heap

Definition at line 109 of file tree.c.

T* __t_newr ( T parent,
Symbol  symbol,
bool  is_run_node 
)

Create a new tree sub-root node (with null surface)

Parameters
[in]parentparent node for the node to be created.
[in]symbolsemantic symbol for the node to be create
Returns
pointer to node allocated on the heap

Definition at line 171 of file tree.c.

T* __t_news ( T parent,
Symbol  symbol,
SemanticID  surface,
bool  is_run_node 
)

Create a new tree node with a SemanticID surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacesemanticID value to store in the surface
Returns
pointer to node allocated on the heap

Definition at line 121 of file tree.c.

size_t __t_serialize ( SemTable sem,
T t,
void **  bufferP,
size_t  offset,
size_t  current_size,
int  compact 
)

Serialize a tree by recursive descent.

Parameters
[in]ddefinitions
[in]ttree to be serialized
[in]bufferPa pointer to a malloced ptr of "current_size" which will be realloced if serialized tree is bigger than initial buffer allocation.
[in]offsetcurrent offset into buffer at which to put serialized data
[in]current_sizesize of buffer
[in]compactboolean to indicate whether to add in extra information
Returns
the length that was added to the buffer
Todo:
compact is really a shorthand for whether this is a fixed size tree or not this should actually be determined on the fly by looking at the structure types.

Definition at line 1686 of file tree.c.

char* _t2json ( SemTable sem,
T t,
int  level,
char *  buf 
)

dump tree in JSON format

Parameters
[in]semthe semantic context
[in]tthe tree to dump
[in]levelcurrent level used for recursion (call with 0)
[in,out]bufbuffer to dump into

Examples (from test suite):

char buf[5000] = {0};
T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
_t2json(G_sem,t,INDENT,buf);
// @todo got screwed up by removing list, too lazy to fix
//spec_is_str_equal(buf,"{ \"symbol\":{ \"context\":255,\"id\":17 },\"type\":\"HTTP_REQUEST_V09\",\"name\":\"HTTP_REQUEST\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":16 },\"type\":\"VERSION\",\"name\":\"HTTP_REQUEST_VERSION\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":14 },\"type\":\"INTEGER\",\"name\":\"VERSION_MAJOR\",\"surface\":1},\n { \"symbol\":{ \"context\":255,\"id\":15 },\"type\":\"INTEGER\",\"name\":\"VERSION_MINOR\",\"surface\":0}]},\n { \"symbol\":{ \"context\":255,\"id\":2 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_METHOD\",\"surface\":\"GET\"},\n { \"symbol\":{ \"context\":255,\"id\":13 },\"type\":\"URI\",\"name\":\"HTTP_REQUEST_PATH\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":3 },\"type\":\"segments list\",\"name\":\"HTTP_REQUEST_PATH_SEGMENTS\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":4 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_PATH_SEGMENT\",\"surface\":\"groups\"},\n { \"symbol\":{ \"context\":255,\"id\":4 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_PATH_SEGMENT\",\"surface\":\"5\"}]},\n { \"symbol\":{ \"context\":255,\"id\":7 },\"type\":\"FILE_HANDLE\",\"name\":\"HTTP_REQUEST_PATH_FILE\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":5 },\"type\":\"CSTRING\",\"name\":\"FILE_NAME\",\"surface\":\"users\"},\n { \"symbol\":{ \"context\":255,\"id\":6 },\"type\":\"CSTRING\",\"name\":\"FILE_EXTENSION\",\"surface\":\"json\"}]},\n { \"symbol\":{ \"context\":255,\"id\":8 },\"type\":\"query struct\",\"name\":\"HTTP_REQUEST_PATH_QUERY\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":9 },\"type\":\"query param list\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAMS\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":12 },\"type\":\"KEY_VALUE_PARAM\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAM\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":10 },\"type\":\"CSTRING\",\"name\":\"PARAM_KEY\",\"surface\":\"sort_by\"},\n { \"symbol\":{ \"context\":255,\"id\":11 },\"type\":\"CSTRING\",\"name\":\"PARAM_VALUE\",\"surface\":\"last_name\"}]},\n { \"symbol\":{ \"context\":255,\"id\":12 },\"type\":\"KEY_VALUE_PARAM\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAM\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":10 },\"type\":\"CSTRING\",\"name\":\"PARAM_KEY\",\"surface\":\"page\"},\n { \"symbol\":{ \"context\":255,\"id\":11 },\"type\":\"CSTRING\",\"name\":\"PARAM_VALUE\",\"surface\":\"2\"}]}]}]}]}]}");
wjson(G_sem,t,"httpreq",0);
char *stxs = "/%<HTTP_REQUEST_PATH_SEGMENTS:HTTP_REQUEST_PATH_SEGMENTS,HTTP_REQUEST_PATH_FILE>";
T *stx;
stx = parseSemtrex(G_sem,stxs);
wjson(G_sem,stx,"httpreq",1);
T *r;
if (_t_matchr(stx,t,&r)) {
wjson(G_sem,r,"httpreq",2);
_t_free(r);
}
_t_free(stx);
_t_free(t);

Definition at line 1912 of file tree.c.

char* _t2rawjson ( SemTable sem,
T t,
int  level,
char *  buf 
)

dump tree in raw JSON format

Parameters
[in]semthe semantic context
[in]tthe tree to dump
[in]levelcurrent level used for recursion (call with 0)
[in,out]bufbuffer to dump into

Examples (from test suite):

char buf[5000] = {0};
T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
_t2json(G_sem,t,INDENT,buf);
// @todo got screwed up by removing list, too lazy to fix
//spec_is_str_equal(buf,"{ \"symbol\":{ \"context\":255,\"id\":17 },\"type\":\"HTTP_REQUEST_V09\",\"name\":\"HTTP_REQUEST\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":16 },\"type\":\"VERSION\",\"name\":\"HTTP_REQUEST_VERSION\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":14 },\"type\":\"INTEGER\",\"name\":\"VERSION_MAJOR\",\"surface\":1},\n { \"symbol\":{ \"context\":255,\"id\":15 },\"type\":\"INTEGER\",\"name\":\"VERSION_MINOR\",\"surface\":0}]},\n { \"symbol\":{ \"context\":255,\"id\":2 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_METHOD\",\"surface\":\"GET\"},\n { \"symbol\":{ \"context\":255,\"id\":13 },\"type\":\"URI\",\"name\":\"HTTP_REQUEST_PATH\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":3 },\"type\":\"segments list\",\"name\":\"HTTP_REQUEST_PATH_SEGMENTS\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":4 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_PATH_SEGMENT\",\"surface\":\"groups\"},\n { \"symbol\":{ \"context\":255,\"id\":4 },\"type\":\"CSTRING\",\"name\":\"HTTP_REQUEST_PATH_SEGMENT\",\"surface\":\"5\"}]},\n { \"symbol\":{ \"context\":255,\"id\":7 },\"type\":\"FILE_HANDLE\",\"name\":\"HTTP_REQUEST_PATH_FILE\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":5 },\"type\":\"CSTRING\",\"name\":\"FILE_NAME\",\"surface\":\"users\"},\n { \"symbol\":{ \"context\":255,\"id\":6 },\"type\":\"CSTRING\",\"name\":\"FILE_EXTENSION\",\"surface\":\"json\"}]},\n { \"symbol\":{ \"context\":255,\"id\":8 },\"type\":\"query struct\",\"name\":\"HTTP_REQUEST_PATH_QUERY\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":9 },\"type\":\"query param list\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAMS\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":12 },\"type\":\"KEY_VALUE_PARAM\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAM\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":10 },\"type\":\"CSTRING\",\"name\":\"PARAM_KEY\",\"surface\":\"sort_by\"},\n { \"symbol\":{ \"context\":255,\"id\":11 },\"type\":\"CSTRING\",\"name\":\"PARAM_VALUE\",\"surface\":\"last_name\"}]},\n { \"symbol\":{ \"context\":255,\"id\":12 },\"type\":\"KEY_VALUE_PARAM\",\"name\":\"HTTP_REQUEST_PATH_QUERY_PARAM\",\"children\":[\n { \"symbol\":{ \"context\":255,\"id\":10 },\"type\":\"CSTRING\",\"name\":\"PARAM_KEY\",\"surface\":\"page\"},\n { \"symbol\":{ \"context\":255,\"id\":11 },\"type\":\"CSTRING\",\"name\":\"PARAM_VALUE\",\"surface\":\"2\"}]}]}]}]}]}");
wjson(G_sem,t,"httpreq",0);
char *stxs = "/%<HTTP_REQUEST_PATH_SEGMENTS:HTTP_REQUEST_PATH_SEGMENTS,HTTP_REQUEST_PATH_FILE>";
T *stx;
stx = parseSemtrex(G_sem,stxs);
wjson(G_sem,stx,"httpreq",1);
T *r;
if (_t_matchr(stx,t,&r)) {
wjson(G_sem,r,"httpreq",2);
_t_free(r);
}
_t_free(stx);
_t_free(t);

Definition at line 1785 of file tree.c.

void _t_add ( T t,
T c 
)

add an existing tree onto another appending it as a child

Parameters
[in]ttree onto which c will be added
[in]ctree to add onto t

Definition at line 261 of file tree.c.

T* _t_build ( SemTable sem,
T parent,
  ... 
)

helper for building trees in c

Parameters
[in]semcurrent semantic contexts
[in]parentthe tree to add the built tree onto (can be NULL)
[in]...varargs directing the building of the tree. See examples
Returns
built tree
Note
this function doesn't validate that built tree follows the restrictions in the definitions it just uses the definitions to know what to expect in the varargs. Thus if you put the wrong things in the varargs it will likely segfault! Also you can build illegal trees. It would be possible to add an expectations layer that would see if what comes next looks ok according to what's expected as specified in the definitions. It would also be possible to run the built tree against the semtrex produced by _d_build_def_semtrex

Definition at line 635 of file tree.c.

T* _t_build2 ( SemTable sem,
T parent,
  ... 
)

another helper for building trees in c

Parameters
[in]semcurrent semantic contexts
[in]parentthe tree to add the built tree onto (can be NULL)
[in]...varargs directing the building of the tree. See examples
Returns
built tree
Note
this function doesn't validate that built tree follows the restrictions in the definitions it just uses the definitions to know what to expect in the varargs. Thus if you put the wrong things in the varargs it will likely segfault! Also you can build illegal trees. It would be possible to add an expectations layer that would see if what comes next looks ok according to what's expected as specified in the definitions. It would also be possible to run the built tree against the semtrex produced by _d_build_def_semtrex

Definition at line 771 of file tree.c.

T* _t_child ( T t,
int  i 
)

Get a tree node's nth child

Parameters
[in]tthe node
[in]idesired child
Returns
child or NULL if that child doesn't exist

Definition at line 1251 of file tree.c.

int _t_children ( T t)

get the number of children of a given node

Parameters
[in]tthe node
Returns
number of children

Definition at line 1205 of file tree.c.

T* _t_clone ( T t)

make a copy of a tree

Parameters
[in]ttree to clone
Returns
T duplicated tree
Note
all receptor/scape/stream trees are cloned as references

Examples (from test suite):

T *c = _t_clone(t);
spec_is_true(t!=c);
spec_is_equal(_t_children(c),_t_children(t));
char buf1[2000];
char buf2[2000];
__t_dump(G_sem,c,0,buf1);
__t_dump(G_sem,t,0,buf2);
spec_is_str_equal(buf1,buf2);
spec_is_equal((int)_t_size(t),(int)_t_size(c)); // test cloning of 0 size items (i.e. roots)
_t_free(t);
_t_free(c);

Definition at line 589 of file tree.c.

T* _t_detach_by_idx ( T t,
int  i 
)

Detatch the specified child from a node and return it

Note
does not free the memory occupied by the child
Parameters
[in]tnode to detach from
[in]iindex of the child to detach
Returns
the detatched child

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
char buf[2000];
int p1[] = {1,TREE_PATH_TERMINATOR};
// remove the version from the tree
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p1)),HTTP_REQUEST_VERSION);
T *t_version = _t_detach_by_idx(t,1);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p1)),HTTP_REQUEST_METHOD);
// detached nodes shouldn't have a parent
spec_is_ptr_equal(_t_parent(t_version),NULL);
_t_free(t);
_t_free(t_version);

Definition at line 278 of file tree.c.

void _t_detach_by_ptr ( T t,
T c 
)

search for a given node in the child list of a node and detatch it if found

Note
does not free the memory occupied by c
Parameters
[in]tnode to search
[in]cnode to search for in child list

Definition at line 291 of file tree.c.

void _t_free ( T t)

free the memory occupied by a tree

free walks the tree freeing all the children and any orthogonal trees.

Parameters
[in]ttree to be freed
Todo:
make this remove the child from the parent's child-list?

Definition at line 526 of file tree.c.

T* _t_get ( T t,
int *  p 
)

get a node by path

Parameters
[in]tthe tree to search
[in]pthe path to search for
Returns
pointer to a T

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
int p0[] = {TREE_PATH_TERMINATOR};
int p1[] = {1,TREE_PATH_TERMINATOR};
int p2[] = {2,TREE_PATH_TERMINATOR};
int p3[] = {3,TREE_PATH_TERMINATOR};
int p33[] = {3,3,TREE_PATH_TERMINATOR};
int p331[] = {3,3,1,TREE_PATH_TERMINATOR};
int p3312[] = {3,3,1,2,TREE_PATH_TERMINATOR};
int p33122[] = {3,3,1,2,2,TREE_PATH_TERMINATOR};
int p311[] = {3,1,1,TREE_PATH_TERMINATOR};
spec_is_ptr_equal(_t_get(t,p0),t);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p1)),HTTP_REQUEST_VERSION);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p2)),HTTP_REQUEST_METHOD);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p3)),HTTP_REQUEST_PATH);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p33)),HTTP_REQUEST_PATH_QUERY);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p331)),HTTP_REQUEST_PATH_QUERY_PARAMS);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p3312)),HTTP_REQUEST_PATH_QUERY_PARAM);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p33122)),PARAM_VALUE);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p311)),HTTP_REQUEST_PATH_SEGMENT);
spec_is_str_equal(t2s(_t_getv(t,3,3,1,2,TREE_PATH_TERMINATOR)),"(HTTP_REQUEST_PATH_QUERY_PARAM (PARAM_KEY:page) (PARAM_VALUE:2))");
// _t_get returns null if tree doesn't have a node at the given path
p311[2] = 3;
spec_is_ptr_equal(_t_get(t,p311),NULL);
_t_free(t);

Definition at line 1441 of file tree.c.

int* _t_get_path ( T t)

return the tree path of a given node

this function allocates a buffer to hold a path of the given node which it calculates by walkinga back up the tree

Todo:
implement jumping into orthogonal trees (i.e. return paths with 0 in them)
Parameters
[in]ttree node
Returns
path of node

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
int p0[] = {TREE_PATH_TERMINATOR};
int p1[] = {1,TREE_PATH_TERMINATOR};
int p2[] = {3,1,TREE_PATH_TERMINATOR};
int p3[] = {3,1,1,TREE_PATH_TERMINATOR};
int *path;
path = _t_get_path(_t_get(t,p0));
spec_is_path_equal(path,p0);
free(path);
path = _t_get_path(_t_get(t,p1));
spec_is_path_equal(path,p1);
free(path);
path = _t_get_path(_t_get(t,p3));
spec_is_path_equal(path,p3);
free(path);
path = _t_get_path(_t_get(t,p2));
spec_is_path_equal(path,p2);
free(path);
_t_free(t);

Definition at line 1384 of file tree.c.

void* _t_get_surface ( T t,
int *  p 
)

get the surface of a node by path

Parameters
[in]tthe tree to search
[in]pthe path to search for
Returns
pointer to surface or NULL if path not found

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
int p1[] = {3,1,1,TREE_PATH_TERMINATOR};
int p2[] = {3,1,2,TREE_PATH_TERMINATOR};
int p3[] = {3,3,1,2,2,TREE_PATH_TERMINATOR};
spec_is_str_equal((char *)_t_get_surface(t,p1),"groups");
spec_is_str_equal((char *)_t_get_surface(t,p2),"5");
spec_is_str_equal((char *)_t_get_surface(t,p3),"2");
// make a test tree with the HTTP request tree as an orthogonal tree
T *tt = _t_newt(0,TEST_TREE_SYMBOL,t);
int po[] = {0,TREE_PATH_TERMINATOR};
int po1[] = {0,3,1,1,TREE_PATH_TERMINATOR};
// using 0 in the path should "dive"into the orthogonal tree
T *x =_t_get(tt,po);
spec_is_ptr_equal(x,t);
spec_is_str_equal((char *)_t_get_surface(tt,po1),"groups");
_t_free(tt);

Definition at line 1492 of file tree.c.

T* _t_getv ( T t,
  ... 
)

get a node by path using variable arguments.

Parameters
[in]tthe tree to search
Returns
pointer to a T

note: the last argument MUST be TREE_PATH_TERMINATOR

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
int p0[] = {TREE_PATH_TERMINATOR};
int p1[] = {1,TREE_PATH_TERMINATOR};
int p2[] = {2,TREE_PATH_TERMINATOR};
int p3[] = {3,TREE_PATH_TERMINATOR};
int p33[] = {3,3,TREE_PATH_TERMINATOR};
int p331[] = {3,3,1,TREE_PATH_TERMINATOR};
int p3312[] = {3,3,1,2,TREE_PATH_TERMINATOR};
int p33122[] = {3,3,1,2,2,TREE_PATH_TERMINATOR};
int p311[] = {3,1,1,TREE_PATH_TERMINATOR};
spec_is_ptr_equal(_t_get(t,p0),t);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p1)),HTTP_REQUEST_VERSION);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p2)),HTTP_REQUEST_METHOD);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p3)),HTTP_REQUEST_PATH);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p33)),HTTP_REQUEST_PATH_QUERY);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p331)),HTTP_REQUEST_PATH_QUERY_PARAMS);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p3312)),HTTP_REQUEST_PATH_QUERY_PARAM);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p33122)),PARAM_VALUE);
spec_is_symbol_equal(0,_t_symbol(_t_get(t,p311)),HTTP_REQUEST_PATH_SEGMENT);
spec_is_str_equal(t2s(_t_getv(t,3,3,1,2,TREE_PATH_TERMINATOR)),"(HTTP_REQUEST_PATH_QUERY_PARAM (PARAM_KEY:page) (PARAM_VALUE:2))");
// _t_get returns null if tree doesn't have a node at the given path
p311[2] = 3;
spec_is_ptr_equal(_t_get(t,p311),NULL);
_t_free(t);

Definition at line 1470 of file tree.c.

TreeHash _t_hash ( SemTable sem,
T t 
)

reduce a tree to a hash value

Parameters
[in]symbolsdeclarations of symbols
[in]structuresdefinitions of structures
[in]tthe tree to hash
Returns
TreeHash value

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
TreeHash h = _t_hash(G_sem,t);
// test that changing a symbol changes the hash
t->contents.symbol.id++;
spec_is_true(!_t_hash_equal(h,_t_hash(G_sem,t)));
t->contents.symbol.id--;
// test that changing a surface changes the hash
int p[] = {1,2,TREE_PATH_TERMINATOR};
T *v = _t_get(t,p);
int orig_version = *(int *)&v->contents.surface;
*(int *)&v->contents.surface = orig_version + 1;
spec_is_true(!_t_hash_equal(h,_t_hash(G_sem,t)));
*(int *)&v->contents.surface = orig_version; // change value back
// test that changing child order changes the hash
T *t_version = _t_detach_by_idx(t,1);
_t_add(t,t_version);
spec_is_true(!_t_hash_equal(h,_t_hash(G_sem,t)));
_t_free(t);

Definition at line 1614 of file tree.c.

int _t_hash_equal ( TreeHash  h1,
TreeHash  h2 
)

comparison function for hash tree equality

we have this because TreeHash may become a larger structure not subject to direct equality testing.

Definition at line 1649 of file tree.c.

void _t_insert_at ( T t,
int *  path,
T i 
)

Insert a tree at a given tree path position

Parameters
[in]ttree on which to operate
[in]ppath to position in tree to inesert
[in]itree to insert

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
int p[] = {3,1,2,TREE_PATH_TERMINATOR};
T *c = _t_new(0,HTTP_REQUEST_PATH_SEGMENT,"a",2);
_t_insert_at(t,p,c);
char buf[2000];
p[2] = TREE_PATH_TERMINATOR;
c = _t_get(t,p);
__t_dump(G_sem,c,0,buf);
spec_is_str_equal(buf,"(HTTP_REQUEST_PATH_SEGMENTS (HTTP_REQUEST_PATH_SEGMENT:groups) (HTTP_REQUEST_PATH_SEGMENT:a) (HTTP_REQUEST_PATH_SEGMENT:5))");
_t_free(t);

Definition at line 438 of file tree.c.

void _t_morph ( T dst,
T src 
)

Convert the surface of one node to that of another

Frees the original surface value if it was allocated.

Note
only converts the type and surface, not the children!
Parameters
[in]dstNode to be morphed
[in]srcNode type that dst should be morephed to

Examples (from test suite):

T *x = _t_newi(0,TEST_INT_SYMBOL,123);
T *z = _t_new(0,TEST_STR_SYMBOL,"fish",5);
_t_morph(x,z);
spec_is_str_equal(t2s(x),"(TEST_STR_SYMBOL:fish)");
_t_free(x);
_t_free(z);

Definition at line 357 of file tree.c.

T* _t_new_cptr ( T parent,
Symbol  symbol,
void *  s 
)

Create a new tree node with a stream as it's surface

when cleaning up we'll need to know that this is a stream

Parameters
[in]parentparent node for the node to be created.
[in]symbolsemantic symbol for the node to be create
[in]sstream
Returns
pointer to node allocated on the heap

Examples (from test suite):

FILE *stream;
char buffer[] = "line1\nline2\n";
stream = fmemopen(buffer, strlen (buffer), "r+");
Stream *s = _st_new_unix_stream(stream,0);
T *ts = _t_new_cptr(0,EDGE_STREAM,s);
spec_is_true(ts->context.flags & TFLAG_SURFACE_IS_CPTR);
spec_is_true(ts->context.flags & TFLAG_REFERENCE);
spec_is_ptr_equal(_t_surface(ts),s);
char *x = t2s(ts);
x[12]=0; // chop off the actual address cus that changes all the time
spec_is_str_equal(x,"(EDGE_STREAM");
_t_free(ts);
// note, for now we must handle all stream deallocation manually because the stream
// is just stored in the tree as a cptr

Definition at line 239 of file tree.c.

T* _t_new_receptor ( T parent,
Symbol  symbol,
Receptor r 
)

Create a new tree node with a receptor as it's surface

this is just like _t_newt except that it uses a different flag because when cleaning up we'll need to know that this is a full receptor, not just a plain tree

Parameters
[in]parentparent node for the node to be created.
[in]symbolsemantic symbol for the node to be create
[in]rreceptor
Returns
pointer to node allocated on the heap

Examples (from test suite):

// @fixme this is really a bogus test, because why would a TEST_INT have a receptor as a child?
// we should make this a rational test
T *t = _t_new_root(TEST_ANYTHING_SYMBOL);
Receptor *r = _r_new(G_sem,TEST_RECEPTOR);
T *tr = _t_new_receptor(t,TEST_RECEPTOR,r);
spec_is_ptr_equal(_t_surface(tr),r);
spec_is_true(!(tr->context.flags & TFLAG_ALLOCATED));
spec_is_str_equal(t2s(t),"(TEST_ANYTHING_SYMBOL (TEST_RECEPTOR:{(RECEPTOR_INSTANCE (INSTANCE_OF:TEST_RECEPTOR) (CONTEXT_NUM:3) (PARENT_CONTEXT_NUM:0) (RECEPTOR_STATE (FLUX (DEFAULT_ASPECT (EXPECTATIONS) (SIGNALS))) (PENDING_SIGNALS) (PENDING_RESPONSES) (CONVERSATIONS) (RECEPTOR_ELAPSED_TIME:0)))}))");
_t_free(t); // note, no need to free the receptor explicitly, as _t_free knows about it

Definition at line 204 of file tree.c.

T* _t_new_root ( Symbol  symbol)

Create a new tree root node (with null surface and no parent)

Parameters
[in]symbolsemantic symbol for the node to be create
Returns
pointer to node allocated on the heap

Definition at line 160 of file tree.c.

T* _t_new_scape ( T parent,
Symbol  symbol,
Scape s 
)

Create a new tree node with a scape as it's surface

when cleaning up we'll need to know that this is a scape

Parameters
[in]parentparent node for the node to be created.
[in]symbolsemantic symbol for the node to be create
[in]sscape
Returns
pointer to node allocated on the heap

Examples (from test suite):

Scape *s = _s_new(TEST_INT_SYMBOL,TEST_STR_SYMBOL);
T *ts = _t_new_scape(0,TEST_ALPHABETIZE_SCAPE_SYMBOL,s);
spec_is_true(ts->context.flags &= TFLAG_SURFACE_IS_SCAPE);
spec_is_ptr_equal(_t_surface(ts),s);
spec_is_str_equal(t2s(ts),"(TEST_ALPHABETIZE_SCAPE_SYMBOL:key TEST_INT_SYMBOL,data TEST_STR_SYMBOL)");
_t_free(ts); // note, no need to free the scape explicitly, as _t_free knows about it

Definition at line 222 of file tree.c.

T* _t_newp ( T parent,
Symbol  symbol,
Process  surface 
)

Create a new tree node with a Process surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfaceProcess value
Returns
pointer to node allocated on the heap

Definition at line 251 of file tree.c.

T* _t_newt ( T parent,
Symbol  symbol,
T surface 
)

Create a new tree node with a tree as it's surface

Parameters
[in]parentparent node for the node to be created. Can be 0 if this is a root node
[in]symbolsemantic symbol for the node to be create
[in]surfacepointer to tree to store as an orthogonal tree in the surface
Returns
pointer to node allocated on the heap

Definition at line 133 of file tree.c.

T* _t_next_sibling ( T t)

Get a tree node's index position

Parameters
[in]tthe node
Returns
the index of the node
Todo:
improve algorithm as this is very expensive if called all the time.

Definition at line 1306 of file tree.c.

int _t_node_index ( T t)

Get a tree node's index position

Parameters
[in]tthe node
Returns
the index of the node

Definition at line 1284 of file tree.c.

T* _t_parent ( T t)

Get a tree node's parent

Parameters
[in]tthe node
Returns
parent or NULL if node is root

Definition at line 1262 of file tree.c.

T* _t_parse ( SemTable sem,
T parent,
char *  s,
  ... 
)

convert a string to a semantic tree

Parameters
[in]semthe semantic context
[in]parentthe parent node under which to add the parsed tree (can be NULL)
[in]sthe string to be converted
[in]...any substitution tree nodes
Returns
tree

Definition at line 919 of file tree.c.

int _t_path_depth ( int *  p)

return the depth of a given path

Parameters
[in]ppath
Returns
int value of depth

Examples (from test suite):

int p0[] = {TREE_PATH_TERMINATOR};
int p1[] = {1,TREE_PATH_TERMINATOR};
int p2[] = {3,0,TREE_PATH_TERMINATOR};
int p3[] = {2,1,1,TREE_PATH_TERMINATOR};
int p5[] = {3,0,2,1,1,TREE_PATH_TERMINATOR};
spec_is_equal(_t_path_depth(p0),0);
spec_is_equal(_t_path_depth(p1),1);
spec_is_equal(_t_path_depth(p2),2);
spec_is_equal(_t_path_depth(p3),3);
spec_is_equal(_t_path_depth(p5),5);

Definition at line 1365 of file tree.c.

int _t_path_equal ( int *  p1,
int *  p2 
)

compare equality of two paths

Parameters
[in]p1first path
[in]p2second path
Returns
1 if equal 0 if not

Examples (from test suite):

int p0[] = {TREE_PATH_TERMINATOR};
int p1[] = {1,TREE_PATH_TERMINATOR};
int p2[] = {2,TREE_PATH_TERMINATOR};
int p3[] = {2,1,1,TREE_PATH_TERMINATOR};
int p4[] = {3,0,TREE_PATH_TERMINATOR};
int p5[] = {3,0,2,1,1,TREE_PATH_TERMINATOR};
spec_is_true(_t_path_equal(p0,p0));
spec_is_true(_t_path_equal(p1,p1));
spec_is_true(_t_path_equal(p2,p2));
spec_is_true(_t_path_equal(p3,p3));
spec_is_true(!_t_path_equal(p0,p1));
spec_is_true(!_t_path_equal(p2,p3));
spec_is_true(!_t_path_equal(p4,p3));
spec_is_true(!_t_path_equal(p0,p3));
spec_is_true(!_t_path_equal(p4,p5));

Definition at line 1350 of file tree.c.

T* _t_path_walk ( T t,
int **  pathP,
int *  lenP 
)

walk a tree using a path as a "cursor"

the initial call to _t_path_walk can pass in NULL as the pointer, in which case the routine will allocate a buffer of size indicated in *lenP which should be a multiple of sizeof(int). Subsequent calls expect *lenP to be the current size of the buffer which will be reallocated if needed.

Parameters
[in]tthe tree to walk
[in,out]pathPthe pointer to the path cursor to walk from (allocates buffer if non provided)
[in,out]lenPthe path buffer size (used to calculate whether a realloc is needed)
Todo:
optimize reallocing

Examples (from test suite):

Definition at line 1543 of file tree.c.

void _t_pathcpy ( int *  dst_p,
int *  src_p 
)

copy a path

Parameters
[in,out]dst_ppointer to buffer holding destination path
[in]src_ppath

Examples (from test suite):

int pp[10];
int p5[] = {3,0,2,1,1,TREE_PATH_TERMINATOR};
_t_pathcpy(pp,p5);
spec_is_path_equal(pp,p5);

Definition at line 1424 of file tree.c.

void _t_replace ( T t,
int  i,
T r 
)

Replace the specified child with the given node.

Note
frees the replaced child
Parameters
[in]tparent node on which to operate
[in]iindex to child be replaced
[in]rnode to replace

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
// replace the version with a new version
T *t_version = _t_newr(0,HTTP_REQUEST_VERSION);
_t_newi(t_version,VERSION_MAJOR,1);
_t_newi(t_version,VERSION_MINOR,1);
_t_replace(t,1,t_version);
int p[] = {1,TREE_PATH_TERMINATOR};
spec_is_str_equal(t2s(_t_get(t,p)),"(HTTP_REQUEST_VERSION (VERSION_MAJOR:1) (VERSION_MINOR:1))");
_t_free(t);
t = _t_build(G_sem,0,SEMANTIC_MAP,SEMANTIC_LINK,USAGE,REQUEST_TYPE,REPLACEMENT_VALUE,ACTUAL_SYMBOL,PING,NULL_SYMBOL,NULL_SYMBOL,NULL_SYMBOL);
T *t2 = _t_build(G_sem,0,TEST_ANYTHING_SYMBOL,TEST_INT_SYMBOL,1,TEST_INT_SYMBOL,2,TEST_INT_SYMBOL,1,TEST_INT_SYMBOL,3,NULL_SYMBOL,NULL_SYMBOL);
// test that replace_node can replace at the parent level.
spec_is_str_equal(t2s(t),"(TEST_ANYTHING_SYMBOL (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:2) (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:3))");
spec_is_ptr_equal(_t_parent(t),NULL);
spec_is_ptr_equal(_t_parent(_t_child(t,2)),t);
// and also at the child level
t2 = _t_newi(0,TEST_INT_SYMBOL,314);
spec_is_str_equal(t2s(t),"(TEST_ANYTHING_SYMBOL (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:314) (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:3))");
spec_is_ptr_equal(_t_parent(_t_child(t,2)),t);
_t_free(t);

Definition at line 372 of file tree.c.

void _t_replace_node ( T t,
T r 
)

Replace the a node with the given node.

Note
frees any children of node to be replaced. Beware that the second parameter pointer gets freed too and will become invalid
Parameters
[in]tnode to be replaced
[in]rnode to replace

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
// replace the version with a new version
T *t_version = _t_newr(0,HTTP_REQUEST_VERSION);
_t_newi(t_version,VERSION_MAJOR,1);
_t_newi(t_version,VERSION_MINOR,1);
_t_replace(t,1,t_version);
int p[] = {1,TREE_PATH_TERMINATOR};
spec_is_str_equal(t2s(_t_get(t,p)),"(HTTP_REQUEST_VERSION (VERSION_MAJOR:1) (VERSION_MINOR:1))");
_t_free(t);
t = _t_build(G_sem,0,SEMANTIC_MAP,SEMANTIC_LINK,USAGE,REQUEST_TYPE,REPLACEMENT_VALUE,ACTUAL_SYMBOL,PING,NULL_SYMBOL,NULL_SYMBOL,NULL_SYMBOL);
T *t2 = _t_build(G_sem,0,TEST_ANYTHING_SYMBOL,TEST_INT_SYMBOL,1,TEST_INT_SYMBOL,2,TEST_INT_SYMBOL,1,TEST_INT_SYMBOL,3,NULL_SYMBOL,NULL_SYMBOL);
// test that replace_node can replace at the parent level.
spec_is_str_equal(t2s(t),"(TEST_ANYTHING_SYMBOL (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:2) (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:3))");
spec_is_ptr_equal(_t_parent(t),NULL);
spec_is_ptr_equal(_t_parent(_t_child(t,2)),t);
// and also at the child level
t2 = _t_newi(0,TEST_INT_SYMBOL,314);
spec_is_str_equal(t2s(t),"(TEST_ANYTHING_SYMBOL (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:314) (TEST_INT_SYMBOL:1) (TEST_INT_SYMBOL:3))");
spec_is_ptr_equal(_t_parent(_t_child(t,2)),t);
_t_free(t);

Definition at line 391 of file tree.c.

T* _t_root ( T t)

Get a tree node's root parent

Parameters
[in]tthe node
Returns
root node by walking up the parents

Definition at line 1272 of file tree.c.

void _t_serialize ( SemTable sem,
T t,
void **  surfaceP,
size_t *  lengthP 
)

Serialize a tree.

Parameters
[in]ddefinitions
[in]ttree to be serialized
[in,out]surfacePa pointer to a buffer that will be malloced
[in,out]lengthPthe serialized length of the tree

Examples (from test suite):

char buf[2000] = {0};
char buf1[2000] = {0};
T *t1,*t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
__t_dump(G_sem,t,0,buf);
size_t l;
void *surface,*s;
_t_serialize(G_sem,t,&surface,&l);
s = surface;
t1 = _t_unserialize(G_sem,&surface,&l,0);
__t_dump(G_sem,t1,0,buf1);
spec_is_str_equal(buf1,buf);
_t_free(t);
_t_free(t1);
free(s);

Definition at line 1723 of file tree.c.

size_t _t_size ( T t)

Get a tree node's surface size

Parameters
[in]tthe node
Returns
size

Definition at line 1238 of file tree.c.

char* _t_sprint_path ( int *  fp,
char *  buf 
)

print a path to a string

Parameters
[in]pthe path to print
[in,out]bufbuffer to copy the string text to
Returns
pointer to the bufer

Examples (from test suite):

char buf[255];
int p5[] = {3,0,2,1,1,TREE_PATH_TERMINATOR};
spec_is_str_equal(_t_sprint_path(p5,buf),"/3/0/2/1/1");

Definition at line 1508 of file tree.c.

void* _t_surface ( T t)

get the data of a given node

Parameters
[in]tthe node
Returns
pointer to node's surface

Definition at line 1215 of file tree.c.

T* _t_swap ( T t,
int  i,
T r 
)

Swap out the specified child for the given node.

Note
returns the replaced child
Parameters
[in]tinput node on which to operate
[in]iindex to child be replaced
[in]rnode to replace
Returns
pointer to node allocated on the heap

Examples (from test suite):

T *t = _makeTestHTTPRequestTree(); // GET /groups/5/users.json?sort_by=last_name?page=2 HTTP/1.0
// replace the version with a new version
T *t_version = _t_newr(0,HTTP_REQUEST_VERSION);
_t_newi(t_version,VERSION_MAJOR,1);
_t_newi(t_version,VERSION_MINOR,2);
spec_is_str_equal(t2s(_t_child(t,1)),"(HTTP_REQUEST_VERSION (VERSION_MAJOR:1) (VERSION_MINOR:1))");
T *s = _t_swap(t,1,t_version);
// swap returns the node swapped out as a root node
spec_is_str_equal(t2s(s),"(HTTP_REQUEST_VERSION (VERSION_MAJOR:1) (VERSION_MINOR:1))");
spec_is_ptr_equal(_t_parent(s),NULL);
spec_is_str_equal(t2s(_t_child(t,1)),"(HTTP_REQUEST_VERSION (VERSION_MAJOR:1) (VERSION_MINOR:2))");
_t_free(s);
_t_free(t);

Definition at line 418 of file tree.c.

Symbol _t_symbol ( T t)

Get a tree node's semantic symbol

Parameters
[in]tthe node
Returns
Symbol for the given node

Definition at line 1228 of file tree.c.

int _t_write ( SemTable sem,
T t,
Stream stream 
)

write a tree out to a stream

Parameters
[in]semcurrent semantic contexts
[in]tthe tree to write out
[in]streamthe stream to write to
Returns
unix error code, or number of bytes written

Definition at line 2066 of file tree.c.