diff --git a/lib/Makefile b/lib/Makefile index 1452400..59b699f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ sources=$(treap.sources) \ $(tree.sources) \ $(node.sources) -treap.sources = treap-extend.c \ +treap.sources = treap-insert.c \ treap-fini.c \ treap-init.c \ treap-lookup.c \ @@ -49,7 +49,18 @@ tree.sources = tree-fini.c \ tree.headers = tree-i.h \ tree.h -node.sources = node-foreach.c +node.sources = node-foreach.c \ + node-id.c \ + node-name.c \ + node-parent.c \ + node-type.c \ + node-size.c \ + node-offset.c \ + node-assign.c \ + node-cda.c \ + node-cdp.c \ + node-cdv.c \ + node-cd.c node.headers = node-i.h \ node.h @@ -75,6 +86,7 @@ $(library): $(sources:%.c=%.o) $(sources:%.c=%.o): %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< +$(node.sources:%.c=%.o): $(node.headers) $(treap.sources:%.c=%.o): $(treap.headers) $(stable.sources:%.c=%.o): $(stable.headers) treap.h $(tree.sources:%.c=%.o): $(tree.headers) treap.h stable.h node.h node-i.h diff --git a/lib/node-assign.c b/lib/node-assign.c index 5a47f63..1303ecc 100644 --- a/lib/node-assign.c +++ b/lib/node-assign.c @@ -1,15 +1,12 @@ #include -#include -#include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" int -aff_n_assign(struct AffTreeNode_s *node, - enum AffNodeType_e type, - uint32_t size, - uint64_t offset) +aff_node_assign(struct AffNode_s *node, + enum AffNodeType_e type, + uint32_t size, + uint64_t offset) { if (node == 0) return 1; diff --git a/lib/node-cd.c b/lib/node-cd.c new file mode 100644 index 0000000..8a8da73 --- /dev/null +++ b/lib/node-cd.c @@ -0,0 +1,20 @@ +#include +#include +#include "node-i.h" + +struct AffNode_s * +aff_node_cd(struct AffTree_s *tree, + struct AffSTable_s *stable, + struct AffNode_s *n, + int create, + ...) +{ + struct AffNode_s *res; + va_list va; + + va_start(va, create); + res = aff_node_cdv(tree, stable, n, create, va); + va_end(va); + + return res; +} diff --git a/lib/node-cda.c b/lib/node-cda.c new file mode 100644 index 0000000..61327c6 --- /dev/null +++ b/lib/node-cda.c @@ -0,0 +1,14 @@ +#include +#include +#include "node-i.h" + +struct AffNode_s * +aff_node_cda(struct AffTree_s *tree, + struct AffSTable_s *stable, + struct AffNode_s *n, + int create, + const char *p[]) +{ + /* XXX */ + return 0; +} diff --git a/lib/node-cdp.c b/lib/node-cdp.c new file mode 100644 index 0000000..d42410b --- /dev/null +++ b/lib/node-cdp.c @@ -0,0 +1,35 @@ +#include +#include +#include "stable.h" +#include "node.h" +#include "tree.h" +#include "node-i.h" + +struct AffNode_s * +aff_node_chdir(struct AffTree_s *tree, + struct AffSTable_s *stable, + struct AffNode_s *n, + int create, + const char *p) +{ + const struct AffSymbol_s *sym; + struct AffNode_s *ch; + + if (tree == 0 || stable == 0 || n == 0) + return 0; + if (p == 0) + return n; + + sym = aff_stable_lookup(stable, p); + if (sym == 0 && create) { + sym = aff_stable_insert(stable, p); + } + if (sym == 0) + return 0; + + ch = aff_tree_lookup(tree, n, sym); + if (ch == 0 && create) { + ch = aff_tree_insert(tree, n, sym); + } + return ch; +} diff --git a/lib/node-cdv.c b/lib/node-cdv.c new file mode 100644 index 0000000..da1adb8 --- /dev/null +++ b/lib/node-cdv.c @@ -0,0 +1,20 @@ +#include +#include +#include "node-i.h" + +struct AffNode_s * +aff_node_cdv(struct AffTree_s *tree, + struct AffSTable_s *stable, + struct AffNode_s *n, + int create, + va_list va) +{ + const char *name; + + for (;;) { + name = va_arg(va, const char *); + if (name == 0) + return n; + n = aff_node_chdir(tree, stable, n, create, name); + } +} diff --git a/lib/node-id.c b/lib/node-id.c index 04be468..f4833d6 100644 --- a/lib/node-id.c +++ b/lib/node-id.c @@ -1,10 +1,9 @@ #include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" uint64_t -aff_n_id(const struct AffTreeNode_s *tn) +aff_node_id(const struct AffNode_s *tn) { if (tn == 0) return 0; diff --git a/lib/node-name.c b/lib/node-name.c index e21e416..08b6edf 100644 --- a/lib/node-name.c +++ b/lib/node-name.c @@ -1,10 +1,9 @@ #include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" const struct AffSymbol_s * -aff_n_name(const struct AffTreeNode_s *tn) +aff_node_name(const struct AffNode_s *tn) { if (tn == 0) return 0; diff --git a/lib/node-offset.c b/lib/node-offset.c index 0c932e8..64b4d52 100644 --- a/lib/node-offset.c +++ b/lib/node-offset.c @@ -1,10 +1,9 @@ #include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" uint64_t -aff_n_offset(const struct AffTreeNode_s *tn) +aff_node_offset(const struct AffNode_s *tn) { if (tn == 0) return 0; diff --git a/lib/node-parent.c b/lib/node-parent.c index e586cea..0aeaf78 100644 --- a/lib/node-parent.c +++ b/lib/node-parent.c @@ -1,12 +1,11 @@ #include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" -const struct AffTreeNode_s * -aff_n_parent(const struct AffTreeNode_s *tn) +struct AffNode_s * +aff_node_parent(const struct AffNode_s *tn) { if (tn == 0) return 0; - return tn->key.parent; + return (struct AffNode_s *)tn->key.parent; } diff --git a/lib/node-size.c b/lib/node-size.c new file mode 100644 index 0000000..6cffda3 --- /dev/null +++ b/lib/node-size.c @@ -0,0 +1,11 @@ +#include +#include +#include "node-i.h" + +uint32_t +aff_node_size(const struct AffNode_s *tn) +{ + if (tn == 0) + return 0; + return tn->size; +} diff --git a/lib/node-type.c b/lib/node-type.c index 8e71b97..d36b4d6 100644 --- a/lib/node-type.c +++ b/lib/node-type.c @@ -1,11 +1,10 @@ #include -#include "treap.h" -#include "stable.h" -#include "tree-i.h" +#include +#include "node-i.h" enum AffNodeType_e -aff_n_type(const struct AffTreeNode_s *tn) +aff_node_type(const struct AffNode_s *tn) { if (tn == 0) return affNodeInvalid; diff --git a/lib/node.h b/lib/node.h index daabc0d..c8a977f 100644 --- a/lib/node.h +++ b/lib/node.h @@ -22,9 +22,9 @@ * otherwise, missing components will be added to the tree and symbol table. * * cda() walks through a given sequence of path elments. The list ends with NULL - * cdp() takes a linked list of path elements in the reverse order and walks it * cd() takes a list as separate arguments, the last argument must be NULL. * cdv() takes arguments of cd() converted into va_list. + * chdir() moves one step through the tree. * * There are also node manipulation routines in AFF readers and writers. */ @@ -39,12 +39,6 @@ enum AffNodeType_e { affNodeComplex }; -/* AFF reverse path structure */ -struct AffReversePath_s { - const struct AffReversePath_s *parent; - const char *name; -}; - struct AffTree_s; struct AffSTable_s; @@ -53,8 +47,8 @@ void aff_node_foreach(struct AffNode_s *n, void *arg), void *arg); uint64_t aff_node_id(const struct AffNode_s *tn); -const struct AFfSymbol_s*aff_node_name(const struct AffNode_s *n); -struct AffNode_t *aff_node_parent(const struct AffNode_s *n); +const struct AffSymbol_s*aff_node_name(const struct AffNode_s *n); +struct AffNode_s *aff_node_parent(const struct AffNode_s *n); enum AffNodeType_e aff_node_type(const struct AffNode_s *n); uint32_t aff_node_size(const struct AffNode_s *n); uint64_t aff_node_offset(const struct AffNode_s *tn); @@ -63,26 +57,25 @@ int aff_node_assign(struct AffNode_s *node, uint32_t size, uint64_t offset); -struct AffNode_t *aff_node_cda(struct AffTree_s *tree, +struct AffNode_s *aff_node_chdir(struct AffTree_s *tree, + struct AffSTable_s *stable, + struct AffNode_s *n, + int create, + const char *p); +struct AffNode_s *aff_node_cda(struct AffTree_s *tree, struct AffSTable_s *stable, struct AffNode_s *n, int create, const char *p[]); -struct AffNode_t *aff_node_cdp(struct AffTree_s *tree, - struct AffSTable_s *stable, - struct AffNode_s *n, - int create, - struct AffReversePath_s *rp); -struct AffNode_t *aff_node_cdv(struct AffTree_s *tree, +struct AffNode_s *aff_node_cdv(struct AffTree_s *tree, struct AffSTable_s *stable, struct AffNode_s *n, int create, va_list va); -struct AffNode_t *aff_node_cd(struct AffTree_s *tree, +struct AffNode_s *aff_node_cd(struct AffTree_s *tree, struct AffSTable_s *stable, struct AffNode_s *n, int create, - const char *name, ...); - + ...); #endif /* !defined(MARK_a4d076cf_516e_4864_861a_ed8239937ca5) */ diff --git a/lib/stable-insert.c b/lib/stable-insert.c index 0711de5..32e69b5 100644 --- a/lib/stable-insert.c +++ b/lib/stable-insert.c @@ -23,7 +23,7 @@ aff_stable_insert(struct AffSTable_s *st, const char *name) b = malloc(sizeof (struct Block_s)); if (b == 0) return 0; - aff_st_iblock(b, st->size + 1); + aff_stable_iblock(b, st->size + 1); st->last_block->next = b; st->last_block = b; } @@ -33,7 +33,7 @@ aff_stable_insert(struct AffSTable_s *st, const char *name) if (sym->name == 0) return 0; sym->id = st->size + 1; - if (aff_treap_extend(st->treap, sym->name, len, sym) != 0) { + if (aff_treap_insert(st->treap, sym->name, len, sym) != 0) { free((void *)sym->name); return 0; } diff --git a/lib/treap-extend.c b/lib/treap-insert.c similarity index 94% rename from lib/treap-extend.c rename to lib/treap-insert.c index 8028087..b700cb1 100644 --- a/lib/treap-extend.c +++ b/lib/treap-insert.c @@ -4,7 +4,7 @@ #include "treap-i.h" int -aff_treap_extend(struct AffTreap_s *h, const void *key, int size, void *data) +aff_treap_insert(struct AffTreap_s *h, const void *key, int size, void *data) { struct Node_s *q; struct Node_s *p; diff --git a/lib/tree-fini.c b/lib/tree-fini.c index 3b9eed7..c6d2d91 100644 --- a/lib/tree-fini.c +++ b/lib/tree-fini.c @@ -1,17 +1,19 @@ #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" void * -aff_tt_fini(struct AffTree_s *tt) +aff_tree_fini(struct AffTree_s *tt) { struct Block_s *bl; if (tt == 0) return 0; - aff_h_fini(tt->treap); + aff_treap_fini(tt->treap); for (bl = tt->block.next; bl;) { struct Block_s *n = bl->next; free(bl); diff --git a/lib/tree-foreach.c b/lib/tree-foreach.c index f7b639f..a56c8de 100644 --- a/lib/tree-foreach.c +++ b/lib/tree-foreach.c @@ -1,12 +1,14 @@ #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" void -aff_tt_foreach(const struct AffTree_s *tt, - void (*proc)(const struct AffTreeNode_s *node, void *arg), - void *arg) +aff_tree_foreach(const struct AffTree_s *tt, + void (*proc)(struct AffNode_s *node, void *arg), + void *arg) { const struct Block_s *b; uint32_t i; @@ -16,7 +18,7 @@ aff_tt_foreach(const struct AffTree_s *tt, for (b = &tt->block; b; b = b->next) { for (i = 0; i < b->used; i++) { - proc(b->node, arg); + proc((struct AffNode_s *)b->node, arg); } } } diff --git a/lib/tree-fsize.c b/lib/tree-fsize.c index 3ce0b93..8ef9971 100644 --- a/lib/tree-fsize.c +++ b/lib/tree-fsize.c @@ -1,10 +1,12 @@ #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" uint64_t -aff_tt_file_size(const struct AffTree_s *tt) +aff_tree_file_size(const struct AffTree_s *tt) { if (tt == 0) return 0; diff --git a/lib/tree-iblock.c b/lib/tree-iblock.c index af9c1d2..9d3a2c0 100644 --- a/lib/tree-iblock.c +++ b/lib/tree-iblock.c @@ -1,10 +1,12 @@ #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" void -aff_tt_iblock(struct Block_s *block, int start) +aff_tree_iblock(struct Block_s *block, int start) { block->next = 0; block->start = start; diff --git a/lib/tree-index.c b/lib/tree-index.c index 972d700..71bf0ba 100644 --- a/lib/tree-index.c +++ b/lib/tree-index.c @@ -1,12 +1,14 @@ #include #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" -struct AffTreeNode_s * -aff_tt_index(const struct AffTree_s *tt, uint64_t index) +struct AffNode_s * +aff_tree_index(const struct AffTree_s *tt, uint64_t index) { const struct Block_s *b; @@ -16,7 +18,7 @@ aff_tt_index(const struct AffTree_s *tt, uint64_t index) if (index < b->start) return 0; if (index < b->start + b->used) - return (struct AffTreeNode_s *)&b->node[b->start - index]; + return (struct AffNode_s *)&b->node[b->start - index]; } return 0; } diff --git a/lib/tree-init.c b/lib/tree-init.c index 545bd70..732ebed 100644 --- a/lib/tree-init.c +++ b/lib/tree-init.c @@ -1,18 +1,20 @@ #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" struct AffTree_s * -aff_tt_init(void) +aff_tree_init(void) { struct AffTree_s *tt = malloc(sizeof (struct AffTree_s)); if (tt == 0) return 0; - tt->treap = aff_h_init(); + tt->treap = aff_treap_init(); if (tt->treap == 0) { free(tt); return 0; @@ -21,14 +23,14 @@ aff_tt_init(void) tt->file_size = 0; tt->last_block = &tt->block; tt->root.type = affNodeVoid; - tt->root.key.parent = 0; + tt->root.key.parent = &tt->root; tt->root.key.name = 0; tt->root.id = 0; tt->root.size = 0; tt->root.offset = 0; tt->root.next = 0; tt->root.children = 0; - aff_tt_iblock(&tt->block, 1); + aff_tree_iblock(&tt->block, 1); return tt; } diff --git a/lib/tree-insert.c b/lib/tree-insert.c index 73afe89..f3b15dd 100644 --- a/lib/tree-insert.c +++ b/lib/tree-insert.c @@ -1,17 +1,19 @@ #include #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" -struct AffTreeNode_s * -aff_tt_insert(struct AffTree_s *tt, - const struct AffTreeNode_s *parent, - const struct AffSymbol_s *name) +struct AffNode_s * +aff_tree_insert(struct AffTree_s *tt, + struct AffNode_s *parent, + const struct AffSymbol_s *name) { struct Block_s *b; - struct AffTreeNode_s *n; + struct AffNode_s *n; struct Key_s k; int len = 0; @@ -20,7 +22,7 @@ aff_tt_insert(struct AffTree_s *tt, k.parent = parent; k.name = name; - n = aff_h_lookup(tt->treap, &k, sizeof (struct Key_s)); + n = aff_treap_lookup(tt->treap, &k, sizeof (struct Key_s)); if (n) return 0; @@ -28,7 +30,7 @@ aff_tt_insert(struct AffTree_s *tt, b = malloc(sizeof (struct Block_s)); if (b == 0) return 0; - aff_tt_iblock(b, tt->size + 1); + aff_tree_iblock(b, tt->size + 1); tt->last_block->next = b; tt->last_block = b; } @@ -40,8 +42,8 @@ aff_tt_insert(struct AffTree_s *tt, n->offset = 0; n->id = tt->size + 1; n->next = parent->children; - ((struct AffTreeNode_s *)parent)->children = n; - if (aff_h_extend(tt->treap, &n->key, sizeof (struct Key_s), n) != 0) { + ((struct AffNode_s *)parent)->children = n; + if (aff_treap_insert(tt->treap, &n->key, sizeof (struct Key_s), n) != 0) { return 0; } b->used++; diff --git a/lib/tree-lookup.c b/lib/tree-lookup.c index f5ffab5..7f2d580 100644 --- a/lib/tree-lookup.c +++ b/lib/tree-lookup.c @@ -1,13 +1,15 @@ #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" -struct AffTreeNode_s * -aff_tt_lookup(const struct AffTree_s *tt, - const struct AffTreeNode_s *parent, - const struct AffSymbol_s *name) +struct AffNode_s * +aff_tree_lookup(const struct AffTree_s *tt, + const struct AffNode_s *parent, + const struct AffSymbol_s *name) { struct Key_s k; @@ -17,5 +19,5 @@ aff_tt_lookup(const struct AffTree_s *tt, k.parent = parent; k.name = name; - return aff_h_lookup(tt->treap, &k, sizeof (struct Key_s)); + return aff_treap_lookup(tt->treap, &k, sizeof (struct Key_s)); } diff --git a/lib/tree-print.c b/lib/tree-print.c index 3644179..4dcba8d 100644 --- a/lib/tree-print.c +++ b/lib/tree-print.c @@ -1,16 +1,18 @@ #include #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" static void -print_node(const struct AffTreeNode_s *node, void *arg) +print_node(struct AffNode_s *node, void *arg) { printf(" %16p %016llx: [%16p %16p %16p %32s] ", node, node->id, node->children, node->next, - node->key.parent, aff_sym_name(node->key.name)); + node->key.parent, aff_symbol_name(node->key.name)); switch (node->type) { case affNodeInvalid: printf("unvalid node\n"); @@ -37,7 +39,7 @@ print_node(const struct AffTreeNode_s *node, void *arg) } void -aff_tt_print(const struct AffTree_s *tt) +aff_tree_print(struct AffTree_s *tt) { if (tt == 0) { printf("NULL Tree table\n"); @@ -45,6 +47,6 @@ aff_tt_print(const struct AffTree_s *tt) } printf("Tree table at %p, size=%lld, file-size=%lld:\n", tt, tt->size, tt->file_size); - aff_tt_foreach(tt, print_node, 0); + aff_tree_foreach(tt, print_node, 0); printf("Tree table end\n"); } diff --git a/lib/tree-root.c b/lib/tree-root.c index 5e6319c..bb4c99f 100644 --- a/lib/tree-root.c +++ b/lib/tree-root.c @@ -1,12 +1,14 @@ #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" -struct AffTreeNode_s * -aff_tt_root(const struct AffTree_s *tt) +struct AffNode_s * +aff_tree_root(const struct AffTree_s *tt) { if (tt == 0) return 0; - return (struct AffTreeNode_s *)&tt->root; + return (struct AffNode_s *)&tt->root; } diff --git a/lib/tree-size.c b/lib/tree-size.c index 1404f99..74d6568 100644 --- a/lib/tree-size.c +++ b/lib/tree-size.c @@ -1,10 +1,12 @@ #include +#include #include "treap.h" #include "stable.h" +#include "node-i.h" #include "tree-i.h" uint64_t -aff_tt_size(const struct AffTree_s *tt) +aff_tree_size(const struct AffTree_s *tt) { if (tt == 0) return 0; diff --git a/misc/grok-xml.c b/misc/grok-xml.c new file mode 100644 index 0000000..1a23c26 --- /dev/null +++ b/misc/grok-xml.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include + +struct Path { + const xmlChar *name; + struct Path *prev; +}; + +static xmlChar * +normalize(xmlChar *ptr) +{ + if (ptr == 0) + return 0; + while (isspace(*ptr)) + ptr++; + return ptr; +} + +static void +print_path(struct Path *p) +{ + if (p) { + print_path(p->prev); + printf("/%s", p->name); + } +} + +static void +walk_tree(xmlDocPtr doc, xmlNodePtr node, struct Path *up) +{ + struct Path p; + xmlNodePtr clds; + xmlChar *data; + + p.prev = up; + p.name = node->name; + + if (xmlStrcmp(node->name, (const xmlChar *)"text")) { +#if 0 + print_path(&p); + printf("\n"); +#endif + } else { + data = normalize(xmlNodeListGetString(doc, node, 1)); + if (data && *data) { + print_path(up); + printf(" \"%s\"\n", data); + } + } + + for (clds = node->xmlChildrenNode; clds; clds = clds->next) + walk_tree(doc, clds, &p); +} + +int +main(int argc, char *argv[]) +{ + struct Path p; + char *fname; + xmlDocPtr doc; + xmlNodePtr node; + + if (argc != 2) { + fprintf(stderr, "Usage: grok-xml xml\n"); + return 1; + } + fname = argv[1]; + doc = xmlParseFile(fname); + if (doc == 0) { + fprintf(stderr, "Error reading XML document %s\n", fname); + return 1; + } + node = xmlDocGetRootElement(doc); + if (node == 0) { + fprintf(stderr, "empty document\n"); + goto end; + } + p.prev = 0; + p.name = (xmlChar *)basename(fname); + walk_tree(doc, node, &p); + +end: + xmlFreeDoc(doc); + doc = 0; + + return 0; +} diff --git a/tests/test-treap.c b/tests/test-treap.c index 27e1496..c173789 100644 --- a/tests/test-treap.c +++ b/tests/test-treap.c @@ -17,7 +17,7 @@ get_size(const void *p) int main(int argc, char *argv[]) { - struct AffTreap_s *h = aff_h_init(); + struct AffTreap_s *h = aff_treap_init(); char *ptr; int status; @@ -29,20 +29,20 @@ main(int argc, char *argv[]) status = sscanf(buffer, "%s %s", key, value); switch (status) { case 1: - ptr = aff_h_lookup(h, key, strlen(key) + 1); + ptr = aff_treap_lookup(h, key, strlen(key) + 1); printf("lookup(%s)=%s\n", key, ptr); break; case 2: - status = aff_h_extend(h, strdup(key), strlen(key) + 1, - strdup(value)); + status = aff_treap_extend(h, strdup(key), strlen(key) + 1, + strdup(value)); printf("insert(%s, %s) = %d\n", key, value, status); break; default: continue; } } - aff_h_print(h, get_size); - aff_h_fini(h); + aff_treap_print(h, get_size); + aff_treap_fini(h); return 0; }