Add yxml_symlen() utility function
diff --git a/test/test.c b/test/test.c index 065196b..18473bd 100644 --- a/test/test.c +++ b/test/test.c
@@ -23,6 +23,7 @@ #include <yxml.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <inttypes.h> @@ -57,6 +58,7 @@ static void y_printres(yxml_t *x, yxml_ret_t r) { static int indata; int nextdata = 0; + switch(r) { case YXML_OK: if(verbose) { @@ -68,6 +70,8 @@ case YXML_ELEMSTART: y_printtoken(x, "elemstart "); y_printstring(x->elem); + if(yxml_symlen(x, x->elem) != strlen(x->elem)) + y_printtoken(x, "assertfail: elem lengths don't match"); if(r & YXML_CONTENT) y_printtoken(x, "content"); break; @@ -77,6 +81,8 @@ case YXML_ATTRSTART: y_printtoken(x, "attrstart "); y_printstring(x->attr); + if(yxml_symlen(x, x->attr) != strlen(x->attr)) + y_printtoken(x, "assertfail: attr lengths don't match"); break; case YXML_ATTREND: y_printtoken(x, "attrend"); @@ -92,6 +98,8 @@ case YXML_PISTART: y_printtoken(x, "pistart "); y_printstring(x->pi); + if(yxml_symlen(x, x->pi) != strlen(x->pi)) + y_printtoken(x, "assertfail: pi lengths don't match"); break; case YXML_PIEND: y_printtoken(x, "piend");
diff --git a/yxml.h b/yxml.h index 97c4bc8..97565ec 100644 --- a/yxml.h +++ b/yxml.h
@@ -143,6 +143,16 @@ #endif +/* Returns the length of the element name (x->elem), attribute name (x->attr), + * or PI name (x->pi). This function should ONLY be used directly after the + * YXML_ELEMSTART, YXML_ATTRSTART or YXML_PISTART (respectively) tokens have + * been returned by yxml_parse(), calling this at any other time may not give + * the correct results. This function should also NOT be used on strings other + * than x->elem, x->attr or x->pi. */ +static inline size_t yxml_symlen(yxml_t *x, const char *s) { + return (x->stack + x->stacklen) - (const unsigned char*)s; +} + #endif /* vim: set noet sw=4 ts=4: */
diff --git a/yxml.pod b/yxml.pod index bb4c6ea..bf5e172 100644 --- a/yxml.pod +++ b/yxml.pod
@@ -241,7 +241,7 @@ C<YXML_ELEMCLOSE>. Yxml will verify that elements properly nest and that the name of each closing -tag properly matches that of the respective opening tag. The application may +tag properly matches that of the corresponding opening tag. The application may safely assume that each C<YXML_ELEMSTART> is properly matched with a C<YXML_ELEMCLOSE>, or that otherwise an error is returned. Furthermore, only a single root element is allowed. When the root element is closed, no further @@ -435,3 +435,16 @@ "C<< <a/><!-- .. >>"). =back + +=head2 Utility functions + + size_t yxml_symlen(yxml_t *, const char *); + +C<yxml_symlen()> returns the length of the element name (C<< x->elem >>), +attribute name (C<< x->attr >>), or PI name (C<< x->pi >>). When used +correctly, it gives the same result as C<strlen()>, except without having to +scan through the string. This function should B<ONLY> be used directly after +the C<YXML_ELEMSTART>, C<YXML_ATTRSTART> or C<YXML_PISTART> (respectively) +tokens have been returned by C<yxml_parse()>, calling this function at any +other time may not give the correct results. This function should B<NOT> be +used on strings other than C<< x->elem >>, C<< x->attr >> or C<< x->pi >>.