Skip to content

Commit 1c3f237

Browse files
author
Kyle Maxwell
committed
array bang
1 parent fa7c505 commit 1c3f237

File tree

11 files changed

+76
-16
lines changed

11 files changed

+76
-16
lines changed

Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ check-am:
3939
@echo "trivial2..."; ./parsley test/trivial2.let test/trivial2.html 2>&1 | diff test/trivial2.json - && echo " success."
4040
@echo "craigs-simple..."; ./parsley test/craigs-simple.let test/craigs-simple.html 2>&1 | diff test/craigs-simple.json - && echo " success."
4141
@echo "yelp-home..."; ./parsley test/yelp-home.let test/yelp-home.html 2>&1 | diff test/yelp-home.json - && echo " success."
42-
@echo "cool..."; perl -e 'alarm shift @ARGV; exec @ARGV' 1 ./parsley test/cool.let test/cool.html 2>&1 | diff test/cool.json - && echo " success."
42+
@echo "cool..."; perl -e 'alarm shift @ARGV; exec @ARGV' 1 ./parsley test/cool.let test/cool.html 2>&1 | diff test/cool.json - && echo " success."
43+
@echo "bang..."; ./parsley test/bang.let test/bang.html 2>&1 | diff test/bang.json - && echo " success."
44+
@echo "unbang..."; ./parsley test/unbang.let test/unbang.html 2>&1 | diff test/unbang.json - && echo " success."

Makefile.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ check-am:
742742
@echo "craigs-simple..."; ./parsley test/craigs-simple.let test/craigs-simple.html 2>&1 | diff test/craigs-simple.json - && echo " success."
743743
@echo "yelp-home..."; ./parsley test/yelp-home.let test/yelp-home.html 2>&1 | diff test/yelp-home.json - && echo " success."
744744
@echo "cool..."; perl -e 'alarm shift @ARGV; exec @ARGV' 1 ./parsley test/cool.let test/cool.html 2>&1 | diff test/cool.json - && echo " success."
745+
@echo "bang..."; ./parsley test/bang.let test/bang.html 2>&1 | diff test/bang.json - && echo " success."
746+
@echo "unbang..."; ./parsley test/unbang.let test/unbang.html 2>&1 | diff test/unbang.json - && echo " success."
745747
# Tell versions [3.59,3.63) of GNU make to not export all variables.
746748
# Otherwise a system limit (for SysV at least) may be exceeded.
747749
.NOEXPORT:

parsley.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ parsedParsleyPtr parsley_parse_string(parsleyPtr parsley, char* string, size_t s
103103

104104
static char *
105105
xpath_of(xmlNodePtr node) {
106-
if(node == NULL || node->name == NULL && node->parent == NULL) return strdup("/");
106+
if(node == NULL || node->name == NULL || node->parent == NULL) return strdup("/");
107107

108108
struct ll * ptr = (struct ll *) calloc(sizeof(struct ll *), 1);
109109

@@ -118,6 +118,7 @@ xpath_of(xmlNodePtr node) {
118118
}
119119

120120
struct printbuf *buf = printbuf_new();
121+
sprintbuf(buf, "");
121122
while(ptr->name != NULL) {
122123
sprintbuf(buf, "/%s", ptr->name);
123124
struct ll * last = ptr;
@@ -126,7 +127,7 @@ xpath_of(xmlNodePtr node) {
126127
}
127128
free(ptr);
128129

129-
char *str = strdup(buf->buf);
130+
char *str = strdup(strlen(buf->buf) ? buf->buf : "/");
130131
printbuf_free(buf);
131132
return str;
132133
}
@@ -148,17 +149,15 @@ unlink(xmlNodePtr xml) {
148149
}
149150
}
150151

151-
static bool
152-
is_root(xmlElementPtr xml) {
153-
return xml != NULL && xml->name != NULL && xml->prefix != NULL && !strcmp(xml->name, "root") && !strcmp(xml->prefix, "parsley");
154-
}
155-
156-
// static bool
157-
// is_root(xmlNodePtr node) {
158-
// return !strcmp(node->ns->prefix, "parsley") && !strcmp(node->name, "root");
152+
// static bool
153+
// is_root(xmlElementPtr xml) {
154+
// return xml != NULL && xml->name != NULL && xml->prefix != NULL && !strcmp(xml->name, "root") && !strcmp(xml->prefix, "parsley");
159155
// }
160-
//
161156

157+
static bool
158+
is_root(xmlNodePtr node) {
159+
return node != NULL && node->ns != NULL && !strcmp(node->ns->prefix, "parsley") && !strcmp(node->name, "root");
160+
}
162161

163162
int compare_pos (const void * a, const void * b)
164163
{
@@ -281,24 +280,28 @@ collate(xmlNodePtr xml) {
281280

282281
static void
283282
prune(parsedParsleyPtr ptr, xmlNodePtr xml, char* err) {
284-
if(xml == NULL) return;
283+
if(xml == NULL || is_root(xml)) return;
285284
bool optional = xmlGetProp(xml, "optional") != NULL;
286285
if(optional) {
287286
unlink(xml);
288287
visit(ptr, xml->parent, err);
288+
// fprintf(stderr, "optional ok\n");
289289
return;
290290
} else {
291291
if(err == NULL) asprintf(&err, "%s was empty", xpath_of(xml));
292292
if(!is_root(xml->parent)) {
293+
// fprintf(stderr, "prune up: %s\n", xml->parent->name);
293294
prune(ptr, xml->parent, err);
294295
} else {
296+
// fprintf(stderr, "error out\n");
295297
ptr->error = err;
296298
}
297299
}
298300
}
299301

300302
static void
301303
visit(parsedParsleyPtr ptr, xmlNodePtr xml, char* err) {
304+
if(xml == NULL) return;
302305
if(xml->type != XML_ELEMENT_NODE) return;
303306
xmlNodePtr child = xml->children;
304307
xmlNodePtr parent = xml->parent;
@@ -318,13 +321,14 @@ visit(parsedParsleyPtr ptr, xmlNodePtr xml, char* err) {
318321

319322
static bool
320323
xml_empty(xmlNodePtr xml) {
324+
// fprintf(stderr, "%s\n", xml->name);
321325
xmlNodePtr child = xml->children;
322326
while(child != NULL) {
323327
if(child->type != XML_TEXT_NODE) return false;
324328
if(strlen(child->content)) return false;
325329
child = child->next;
326330
}
327-
// printf("hello!\n");
331+
// printf("hello!\n");
328332
return true;
329333
}
330334

@@ -529,6 +533,7 @@ render(contextPtr c) {
529533
char *filter = resolve_filter(c);
530534
char *expr = resolve_expr(c);
531535
char *scope = filter == NULL ? expr : filter;
536+
char *group_optional = (c->flags & PARSLEY_BANG) ? "" : " optional=\"true\"";
532537
bool magic_children = c->array && filter == NULL;
533538
bool simple_array = c->array && filter != NULL;
534539
bool filtered = filter != NULL;
@@ -537,7 +542,7 @@ render(contextPtr c) {
537542
if(c->array) sprintbuf(c->buf, "<parsley:groups>\n");
538543
if(filtered) sprintbuf(c->buf, "<xsl:for-each select=\"%s\">\n", filter);
539544
if(filtered && !multiple) sprintbuf(c->buf, "<xsl:if test=\"position()=1\">\n");
540-
if(multiple) sprintbuf(c->buf, "<parsley:group optional=\"true\">\n");
545+
if(multiple) sprintbuf(c->buf, "<parsley:group%s>\n", group_optional);
541546

542547
sprintbuf(c->buf, "<xsl:attribute name=\"position\"><xsl:value-of select=\"count(preceding::*) + count(ancestor::*)\"/></xsl:attribute>\n");
543548

parsley.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ typedef struct __parsley_context {
5454
} parsley_context;
5555

5656
enum {
57-
PARSLEY_OPTIONAL = 1,
57+
PARSLEY_OPTIONAL = 1,
58+
PARSLEY_BANG = 2
5859
};
5960

6061
typedef parsley_context * contextPtr;

test/bang.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<html>
2+
<body>
3+
<ul>
4+
<li>
5+
<h4>hi</h4>
6+
<p>world</p>
7+
</li>
8+
<li>
9+
<h4>hello</h4>
10+
<p>people</p>
11+
</li>
12+
<li>
13+
<h4>bye empty</h4>
14+
</li>
15+
</ul>
16+
</body>
17+
</html>

test/bang.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Parsing failed: /list/para was empty

test/bang.let

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"list(li)!": [{
3+
"title": "h4",
4+
"para": "p"
5+
}]
6+
}

test/unbang.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<html>
2+
<body>
3+
<ul>
4+
<li>
5+
<h4>hi</h4>
6+
<p>world</p>
7+
</li>
8+
<li>
9+
<h4>hello</h4>
10+
<p>people</p>
11+
</li>
12+
<li>
13+
<h4>bye empty</h4>
14+
</li>
15+
</ul>
16+
</body>
17+
</html>

test/unbang.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "list": [ { "title": "hi", "para": "world" }, { "title": "hello", "para": "people" } ] }

test/unbang.let

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"list(li)": [{
3+
"title": "h4",
4+
"para": "p"
5+
}]
6+
}

0 commit comments

Comments
 (0)