diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | cmd/main.c | 64 | ||||
| -rw-r--r-- | src/leven.c | 14 | ||||
| -rw-r--r-- | src/parse.c | 10 | ||||
| -rw-r--r-- | test/parse.c | 36 |
5 files changed, 109 insertions, 16 deletions
@@ -1,3 +1,4 @@ compile_commands.json obj/ /app +/.cache @@ -3,39 +3,70 @@ #include <stdio.h> #include <fcntl.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <sys/mman.h> #include "leven.h" #include "parse.h" +#include "log.h" int main(int argc, char **argv) { int rc; - /* int fd = open("filename", O_RDONLY); */ - /* int len = lseek(fd, 0, SEEK_END); */ - /* void *data = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); */ + char *a; + { + int fd = open("/Users/delusional/Documents/xmldiff/file_a.xml", O_RDONLY); + int len = lseek(fd, 0, SEEK_END); + a = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); + } + + char* b; + { + int fd = open("/Users/delusional/Documents/xmldiff/file_b.xml", O_RDONLY); + int len = lseek(fd, 0, SEEK_END); + b = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); + } - char* a = "<root><a/><b></b></root>"; - char* b = "<root><a><b/></a></root>"; + /* char* a = "<root><a/><b></b></root>"; */ + /* char* b = "<root><a><b/></a></root>"; */ + log("Parse a"); struct Tree a_tree; size_t *a_chunks; rc = parse_string(a, &a_tree, &a_chunks); if(rc != 0) return 1; - printf("%ld\n", a_tree.len); + log("Tree a size %ld", a_tree.len); + log("Parse b"); struct Tree b_tree; size_t *b_chunks; rc = parse_string(b, &b_tree, &b_chunks); if(rc != 0) return 1; - printf("%ld\n", b_tree.len); + log("Tree b size %ld", b_tree.len); - DECL_MAT_DATA(cost, uint32_t, 4, 4, - 0, 2, 2, 2, - 2, 0, 1, 1, - 2, 1, 0, 1, - 2, 1, 1, 0, + DECL_MAT_DATA(cost, uint32_t, 5, 5, + 0, 2, 2, 2, 2, + 2, 1, 1, 1, 1, + 2, 1, 1, 1, 1, + 2, 1, 1, 0, 1, + 2, 1, 1, 1, 1 ); + for(size_t j = 0; j < 4; j++) { + size_t b_tag_end = b_chunks[j]; + while(b[b_tag_end] != '>') b_tag_end++; + for(size_t i = 0; i < 4; i++) { + size_t a_tag_end = a_chunks[i]; + while(a[a_tag_end] != '>') a_tag_end++; + log("%ld, %ld", i, j); + + size_t a_len = a_tag_end - a_chunks[i]; + size_t b_len = b_tag_end - b_chunks[j]; + log("B: %ld, A: %ld", b_len, a_len); + log("A: %.*s, B: %.*s", (int)a_len, a + a_chunks[i], (int)b_len, b + b_chunks[j]); + + *imat_uint32_t(cost, i+1, j+1) = !(a_len == b_len && memcmp(a + a_chunks[i], b + b_chunks[j], a_len) == 0) * 1; + } + } printf("\n"); for(size_t y = 0; y < b_tree.len; y++) { for(size_t x = 0; x < b_tree.adj.stride; x++) { @@ -52,6 +83,15 @@ int main(int argc, char **argv) { printf("\n"); } printf("\n"); + + logb("2D Array %s [%ldx%d]", "cost", cost.stride, 5); + for(uint32_t y = 0; y < 5; y++) { + lognl(); + for(uint32_t x = 0; x < cost.stride; x++) { + logc("%03d ", *imat_uint32_t(cost, x, y)); + } + } + loge(); /* mat_uint32_t cost = { */ /* .data = malloc(a_tree.len * b_tree.len * sizeof(uint32_t)), */ /* .stride = a_tree.len, */ diff --git a/src/leven.c b/src/leven.c index 9ed2ab3..f060929 100644 --- a/src/leven.c +++ b/src/leven.c @@ -176,8 +176,10 @@ void constrained_tree_alignment ( const mat_uint32_t cost, const mat_uint32_t cost_n, // The resulting computed cost matrixes node and forest. Size a.len x b.len const mat_uint32_t cost_f, + // Scratch space mat_uint32_t cost_s, uint32_t *adj_alignment, + mat_uint32_t alignment ) { @@ -198,7 +200,7 @@ void constrained_tree_alignment ( size_t remain = 1; size_t cursor = j-1; while(remain > 0) { - log("ADD %ld", cursor); + log("ADD %ld", cursor+1); size_t adj_len = 0; while(adj_len < b.adj.stride && *imat_nid(b.adj, adj_len, cursor) != 0) adj_len++; @@ -212,7 +214,7 @@ void constrained_tree_alignment ( size_t remain = 1; size_t cursor = i-1; while(remain > 0) { - log("REMOVE %ld", cursor); + log("REMOVE %ld", cursor+1); size_t adj_len = 0; while(adj_len < a.adj.stride && *imat_nid(a.adj, adj_len, cursor) != 0) adj_len++; @@ -293,6 +295,14 @@ void constrained_tree_alignment ( b_cursor--; a_cursor--; } + + while(a_cursor >= 0) { + uint32_t *slot = imat_uint32_t(to_compute, 0, to_compute_head); + to_compute_head++; + slot[0] = *imat_nid(a.adj, a_cursor, i-1); + slot[1] = -1; + a_cursor--; + } } else if(a_adj_len > 0 && *imat_uint32_t(cost_n, i, j) == *imat_uint32_t(cost_n, i, 0) + min_cost_a) { // Remove this node and replace it with one of its children log("REMOVE %ld %ld", i, j); diff --git a/src/parse.c b/src/parse.c index 6ab2007..31a93a6 100644 --- a/src/parse.c +++ b/src/parse.c @@ -5,6 +5,7 @@ #include <ctype.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "log.h" @@ -31,6 +32,10 @@ static bool alnum(struct ParseCtx *ctx) { return isalnum(ctx->cursor[0]); } +static bool wspace(struct ParseCtx *ctx) { + return strchr(" \n\t", ctx->cursor[0]) != NULL; +} + static int read_STag(struct ParseCtx *ctx, bool *self_close, size_t nodeId) { // Record start position of the tag if (ctx->phase == PHASE_BUILD) { @@ -40,7 +45,8 @@ static int read_STag(struct ParseCtx *ctx, bool *self_close, size_t nodeId) { if(*ctx->cursor != '<') return 1; ctx->cursor++; - while(isalnum(*ctx->cursor) || *ctx->cursor == ' ' || *ctx->cursor == '"' || *ctx->cursor == '=') ctx->cursor++; + // @COMP Does xml allow all whitespace in the tag? + while(alnum(ctx) || *ctx->cursor == ' ' || *ctx->cursor == '"' || *ctx->cursor == '=') ctx->cursor++; // Check for self-closing tag if(*ctx->cursor == '/') { @@ -70,7 +76,7 @@ static int read_Content(struct ParseCtx *ctx, size_t nodeId) { *imat_nid(ctx->tree->adj, children, nodeId) = childId+1; children++; - } else if(alnum(ctx)) { + } else if(alnum(ctx) || wspace(ctx)) { ctx->cursor++; } else { break; diff --git a/test/parse.c b/test/parse.c index 07dbbfa..328bfd3 100644 --- a/test/parse.c +++ b/test/parse.c @@ -36,6 +36,42 @@ int main(int argc, char **argv) { { struct Tree a; size_t *chunks = NULL; + if(parse_string("<root> </root>", &a, &chunks) != 0) return fail(); + if(a.adj.stride != 1) return fail(); + if(a.len != 1) return fail(); + nid expected[] = { + 0, + }; + if(memcmp(a.adj.data, expected, sizeof(expected)) != 0) return fail(); + + // Verify chunk offsets + if(chunks[0] != 0) return fail(); + + free(chunks); + free(a.adj.data); + } + + { + struct Tree a; + size_t *chunks = NULL; + if(parse_string("<root>\n</root>", &a, &chunks) != 0) return fail(); + if(a.adj.stride != 1) return fail(); + if(a.len != 1) return fail(); + nid expected[] = { + 0, + }; + if(memcmp(a.adj.data, expected, sizeof(expected)) != 0) return fail(); + + // Verify chunk offsets + if(chunks[0] != 0) return fail(); + + free(chunks); + free(a.adj.data); + } + + { + struct Tree a; + size_t *chunks = NULL; if(parse_string("<root><a></a><b></b></root>", &a, &chunks) != 0) return fail(); if(a.adj.stride != 2) return fail(); if(a.len != 3) return fail(); |
