From 1c80d5dfe1558f2a7e9c27f79ea36d0ef674cd6d Mon Sep 17 00:00:00 2001 From: Kyle Maxwell Date: Fri, 20 Mar 2009 00:04:15 -0700 Subject: [PATCH] WIP --- parsley.c | 93 ++++++++++++++++++++----------------------------- parsley.h | 6 ++-- parsleyc_main.c | 7 ++-- util.c | 19 ++++++++-- util.h | 2 +- 5 files changed, 62 insertions(+), 65 deletions(-) diff --git a/parsley.c b/parsley.c index 6512b20..b15af9f 100644 --- a/parsley.c +++ b/parsley.c @@ -430,39 +430,19 @@ parsleyPtr parsley_compile(char* parsley_str, char* incl) { return parsley; } - struct printbuf* buf = printbuf_new(); - - sprintbuf_parsley_header(buf); - sprintbuf(buf, "%s\n", incl); - sprintbuf(buf, "%s\n", "\n"); - sprintbuf(buf, "%s\n", "\n"); + xmlNodePtr node = new_stylesheet_skeleton(incl); - contextPtr context = new_context(json, buf); + contextPtr context = new_context(json, node); __parsley_recurse(context); json_object_put(json); // frees json parsley->error = last_parsley_error; - sprintbuf(buf, "%s\n", "\n"); - sprintbuf(buf, "%s\n", "\n"); - sprintbuf(buf, "%s\n", "\n"); - - // printf("1\n"); - if(parsley->error == NULL) { - xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); - xmlDocPtr doc = xmlCtxtReadMemory(ctxt, buf->buf, buf->size, "http://parslets.com/compiled", NULL, 3); - xmlFreeParserCtxt(ctxt); - parsley->raw_stylesheet = strdup(buf->buf); - parsley->stylesheet = xsltParseStylesheetDoc(doc); + parsley->stylesheet = xsltParseStylesheetDoc(node->doc); } - // printf("2\n"); - free_context(context); - // printf("3\n"); - printbuf_free(buf); - // printf("4\n"); return parsley; } @@ -491,17 +471,20 @@ static void free_context(contextPtr c) { free(c); } -static contextPtr new_context(struct json_object * json, struct printbuf *buf) { +static contextPtr new_context(struct json_object * json, xmlNodePtr node) { contextPtr c = calloc(sizeof(parsley_context), 1); + c->node = node; + c->ns = node->ns; c->tag = strdup("root"); c->expr = pxpath_new_path(1, "/"); - c->buf = buf; c->json = json; return c; } contextPtr deeper_context(contextPtr context, char* key, struct json_object * val) { contextPtr c = (contextPtr) calloc(sizeof(parsley_context), 1); + c->node = context->node; + c->ns = context->ns; c->parent = context; c->tag = parsley_key_tag(key); c->flags = parsley_key_flags(key); @@ -511,7 +494,6 @@ contextPtr deeper_context(contextPtr context, char* key, struct json_object * va c->string = val != NULL && json_object_is_type(c->json, json_type_string); c->filter = parsley_key_filter(key); c->magic = context->array && context->filter == NULL; - c->buf = context->buf; c->expr = c->string ? myparse(json_object_get_string(c->json)) : NULL; if(context->child == NULL) { context->child = c; @@ -520,15 +502,13 @@ contextPtr deeper_context(contextPtr context, char* key, struct json_object * va while(tmp->next != NULL) tmp = tmp->next; tmp->next = c; } - // fprintf(stderr, "tag: %s\nexpr: %s\nfilter: %s\n\n", c->tag, pxpath_to_string(c->expr), pxpath_to_string(c->filter)); + fprintf(stderr, "json: %s\ntag: %s\nexpr: %s\nfilter: %s\n\n", json_object_get_string(c->json), c->tag, pxpath_to_string(c->expr), pxpath_to_string(c->filter)); return c; } void parsley_free(parsleyPtr ptr) { if(ptr->error != NULL) free(ptr->error); - if(ptr->raw_stylesheet != NULL) - free(ptr->raw_stylesheet); if(ptr->stylesheet != NULL) xsltFreeStylesheet(ptr->stylesheet); free(ptr); @@ -542,10 +522,6 @@ void yyerror(const char * s) { printbuf_free(buf); } -static char* optional(contextPtr c) { - return (c->flags & PARSLEY_OPTIONAL) ? " optional=\"true\"" : ""; -} - static bool all_strings(struct json_object * json) { json_object_object_foreach(json, key, val) { @@ -621,34 +597,41 @@ render(contextPtr c) { char *filter = resolve_filter(c); char *expr = resolve_expr(c); char *scope = filter == NULL ? expr : filter; - char *group_optional = (c->flags & PARSLEY_BANG) ? "" : " optional=\"true\""; bool magic_children = c->array && filter == NULL; bool simple_array = c->array && filter != NULL; bool filtered = filter != NULL; bool multiple = (c->array || c->magic) && !magic_children; + + printf("node %s\n", c->node->name); + xmlNsPtr parsley = c->ns; + xmlNsPtr xsl = xmlDocGetRootElement(c->node->doc)->ns; - if(c->array) sprintbuf(c->buf, "\n"); - if(filtered) sprintbuf(c->buf, "\n", filter); - if(filtered && !multiple) sprintbuf(c->buf, "\n"); - if(multiple) sprintbuf(c->buf, "\n", group_optional); - - sprintbuf(c->buf, "\n"); + if(c->array) c->node = xmlNewChild(c->node, parsley, "groups", NULL); + if(filtered) { + c->node = xmlNewChild(c->node, xsl, "for-each", NULL); + xmlSetProp(c->node, "select", filter); + } + if(filtered && !multiple) { + c->node = xmlNewChild(c->node, xsl, "if", NULL); + xmlSetProp(c->node, "test", "position() = 1"); + } + if(multiple) { + c->node = xmlNewChild(c->node, parsley, "group", NULL); + if (c->flags & PARSLEY_BANG) xmlSetProp(c->node, "optional", "true"); + } + xmlNodePtr attr = xmlNewChild(c->node, xsl, "attribute", NULL); + xmlSetProp(attr, "name", "position"); + xmlNodePtr counter = xmlNewChild(attr, xsl, "value-of", NULL); + xmlSetProp(counter, "select", "count(preceding::*) + count(ancestor::*)"); if(c->string) { - sprintbuf(c->buf, "\n", expr); + c->node = xmlNewChild(c->node, xsl, "value-of", NULL); + xmlSetProp(counter, "select", expr); } else { - if(magic_children) sprintbuf(c->buf, "\n"); + if(magic_children) c->node = xmlNewChild(c->node, parsley, "zipped", NULL); __parsley_recurse(c); - if(magic_children) sprintbuf(c->buf, "\n"); } - // fprintf(stderr, "d\n"); - - if(multiple) sprintbuf(c->buf, "\n"); - if(filtered && !multiple) sprintbuf(c->buf, "\n"); - if(filtered) sprintbuf(c->buf, "\n"); - if(c->array) sprintbuf(c->buf, "\n"); - if(filter !=NULL) free(filter); if(expr !=NULL) free(expr); } @@ -656,15 +639,13 @@ render(contextPtr c) { void __parsley_recurse(contextPtr context) { contextPtr c; if(context->json == NULL) return; - // fprintf(stderr, "recursing: %s\n", json_object_to_json_string(context->json)); + fprintf(stderr, "<%s> %s\n", context->tag, context->node->name); json_object_object_foreach(context->json, key, val) { c = deeper_context(context, key, val); - // fprintf(stderr, "<%s%s>\n", c->tag, optional(c)); - sprintbuf(c->buf, "<%s%s>\n", c->tag, optional(c)); - // fprintf(stderr, "a\n"); + fprintf(stderr, "<%s>\n", c->tag); + c->node = xmlNewChild(c->node, NULL, c->tag, NULL); + if (c->flags & PARSLEY_OPTIONAL) xmlSetProp(c->node, "optional", "true"); render(c); - sprintbuf(c->buf, "\n", c->tag); - // fprintf(stderr, "\n", c->tag); } } diff --git a/parsley.h b/parsley.h index 9c7e872..38b636f 100644 --- a/parsley.h +++ b/parsley.h @@ -16,7 +16,6 @@ static char* last_parsley_error; typedef struct __compiled_parsley { - char* raw_stylesheet; xsltStylesheetPtr stylesheet; char* error; } compiled_parsley; @@ -39,7 +38,8 @@ typedef struct __key_node { typedef key_node * keyPtr; typedef struct __parsley_context { - struct printbuf * buf; + xmlNsPtr ns; + xmlNodePtr node; struct json_object * json; char* tag; pxpathPtr filter; @@ -79,7 +79,7 @@ static contextPtr init_context(); static contextPtr clone_context(contextPtr); static contextPtr tagged_context(contextPtr, char*); -static contextPtr new_context(struct json_object *, struct printbuf *); +static contextPtr new_context(struct json_object *, xmlNodePtr node); static contextPtr deeper_context(contextPtr, char*, struct json_object *); static void __parsley_recurse(contextPtr); diff --git a/parsleyc_main.c b/parsleyc_main.c index 6a9120f..7f07d21 100644 --- a/parsleyc_main.c +++ b/parsleyc_main.c @@ -99,9 +99,10 @@ int main (int argc, char **argv) { exit(1); } - FILE* fo = parsley_fopen(arguments.output_file, "w"); - fprintf(fo, compiled->raw_stylesheet); - fclose(fo); + // FILE* fo = parsley_fopen(arguments.output_file, "w"); + // fprintf(fo, compiled->raw_stylesheet); + // fclose(fo); + printf(stderr, "feature disabled"); return 0; } diff --git a/util.c b/util.c index fb3e653..24da762 100644 --- a/util.c +++ b/util.c @@ -100,8 +100,8 @@ pxpathPtr parsley_key_filter(char* key) { // free(expr); return out; } - -char* sprintbuf_parsley_header(struct printbuf *buf) { +xmlNodePtr new_stylesheet_skeleton(char *incl) { + struct printbuf *buf = printbuf_new(); sprintbuf(buf, "%s", ""); sprintbuf(buf, "%s", ""); sprintbuf(buf, "%s", "\n"); + sprintbuf(buf, "%s\n", incl); + sprintbuf(buf, "%s\n", "\n"); + sprintbuf(buf, "%s\n", "\n"); + sprintbuf(buf, "%s\n", "\n"); + sprintbuf(buf, "%s\n", "\n"); + xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); + xmlDocPtr doc = xmlCtxtReadMemory(ctxt, buf->buf, buf->size, "http://parslets.com/compiled", NULL, 3); + xmlFreeParserCtxt(ctxt); + printbuf_free(buf); + + xmlNodePtr node = xmlDocGetRootElement(doc); + while(xmlLastElementChild(node) != NULL) { + node = xmlLastElementChild(node); + } + return node; } diff --git a/util.h b/util.h index db1a7bc..9d38f2d 100644 --- a/util.h +++ b/util.h @@ -17,7 +17,7 @@ #include FILE* parsley_fopen(char*, char*); -char* sprintbuf_parsley_header(struct printbuf *); +xmlNodePtr new_stylesheet_skeleton(char *incl); void registerEXSLT(); void printbuf_file_read(FILE *f, struct printbuf *buf);