*/
#include <stdio.h>
+#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
};
/*--------------------------------------------------------------------
- * Add ESI bit to object
+ * Report a parsing error
*/
static void
+esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
+{
+ int ellipsis = 0;
+ char buf[256], *q;
+ txt t;
+
+ if (i == 0)
+ i = p - ((char *)ew->st->ptr + ew->st->len);
+ if (i > 20) {
+ i = 20;
+ ellipsis = 1;
+ }
+ q = buf;
+ q += sprintf(buf, "at %zd: %s \"",
+ ew->off + (p - (char*)ew->st->ptr), err);
+ while (i > 0) {
+ if (*p >= ' ' && *p <= '~') {
+ *q++ = *p;
+ } else if (*p == '\n') {
+ *q++ = '\\';
+ *q++ = 'n';
+ } else if (*p == '\r') {
+ *q++ = '\\';
+ *q++ = 'r';
+ } else if (*p == '\t') {
+ *q++ = '\\';
+ *q++ = 't';
+ } else {
+ /* XXX: use %%%02x instead ? */
+ q += sprintf(q, "\\x%02x", *p);
+ }
+ p++;
+ i--;
+ }
+ if (ellipsis) {
+ *q++ = '[';
+ *q++ = '.';
+ *q++ = '.';
+ *q++ = '.';
+ *q++ = ']';
+ }
+ *q++ = '"';
+ *q++ = '\0';
+ t.b = buf;
+ t.e = q;
+ WSPR(ew->sp, SLT_ESI_xmlerror, t);
+}
+
+/*--------------------------------------------------------------------
+ * Add ESI bit to object
+ */
+
+static struct esi_bit *
esi_addbit(struct esi_work *ew)
{
ew->eb->verbatim = ew->dst;
sprintf(ew->eb->chunk_length, "%x\r\n", Tlen(ew->dst));
VSL(SLT_Debug, ew->sp->fd, "AddBit: %.*s", Tlen(ew->dst), ew->dst.b);
+ return(ew->eb);
}
}
/*--------------------------------------------------------------------
- * Add one piece to the output, either verbatim or include
+ * Tease the next attribute and value out of an XML element.
+ *
+ * XXX: is the syntax correct ?
*/
-static void
-esi_addinclude(struct esi_work *ew, txt t)
+static int
+esi_attrib(const struct esi_work *ew, txt *in, txt *attrib, txt *val)
{
- VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
- esi_addbit(ew);
- ew->eb->include = t;
+ /* Skip leading blanks */
+ while(in->b < in->e && isspace(*in->b))
+ in->b++;
+
+ /* Nothing found */
+ if (in->b >= in->e)
+ return (0);
+
+ if (!isalpha(*in->b)) {
+ /* XXX error */
+ esi_error(ew, in->b, 1, "XML 1.0 Illegal attribute character");
+ return (-1);
+ }
+
+ /* Attribute name until '=' or space */
+ *attrib = *in;
+ while(in->b < in->e && *in->b != '=' && !isspace(*in->b)) {
+ if (!isalnum(*in->b)) {
+ esi_error(ew, attrib->b, 1 + (in->b - attrib->b),
+ "XML 1.0 Illegal attribute character");
+ return (-1);
+ }
+ in->b++;
+ }
+ attrib->e = in->b;
+
+ if (in->b >= in->e || isspace(*in->b)) {
+ /* Attribute without value */
+ val->b = val->e = in->b;
+ return (1);
+ }
+
+ /* skip '=' */
+ in->b++;
+
+ /* Value, if any ? */
+ *val = *in;
+ if (in->b >= in->e)
+ return (1);
+
+ if (*in->b == '"') {
+ /* Skip quote */
+ in->b++;
+ val->b++;
+
+ /* Anything goes, until next quote */
+ while(in->b < in->e && *in->b != '"')
+ in->b++;
+ val->e = in->b;
+
+ if (in->b >= in->e) {
+ esi_error(ew, val->b, in->e - val->b,
+ "XML 1.0 missing ending quote");
+ return (-1);
+ }
+
+ /* Skip quote */
+ in->b++;
+ } else {
+ /* Anything until whitespace */
+ while(in->b < in->e && !isspace(*in->b))
+ in->b++;
+ val->e = in->b;
+ }
+ return (1);
}
/*--------------------------------------------------------------------
- * Report a parsing error
+ * Add one piece to the output, either verbatim or include
*/
static void
-esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
+esi_addinclude(struct esi_work *ew, txt t)
{
- int ellipsis = 0;
- char buf[256], *q;
- txt t;
-
- if (i == 0)
- i = p - ((char *)ew->st->ptr + ew->st->len);
- if (i > 20) {
- i = 20;
- ellipsis = 1;
- }
- q = buf;
- q += sprintf(buf, "at %zd: %s \"",
- ew->off + (p - (char*)ew->st->ptr), err);
- while (i > 0) {
- if (*p >= ' ' && *p <= '~') {
- *q++ = *p;
- } else if (*p == '\n') {
- *q++ = '\\';
- *q++ = 'n';
- } else if (*p == '\r') {
- *q++ = '\\';
- *q++ = 'r';
- } else if (*p == '\t') {
- *q++ = '\\';
- *q++ = 't';
- } else {
- /* XXX: use %%%02x instead ? */
- q += sprintf(q, "\\x%02x", *p);
- }
- p++;
- i--;
- }
- if (ellipsis) {
- *q++ = '[';
- *q++ = '.';
- *q++ = '.';
- *q++ = '.';
- *q++ = ']';
+ struct esi_bit *eb;
+ txt tag;
+ txt cont;
+
+ eb = esi_addbit(ew);
+ while (esi_attrib(ew, &t, &tag, &cont) == 1) {
+ VSL(SLT_Debug, 0, "<%.*s> -> <%.*s>",
+ tag.e - tag.b, tag.b,
+ cont.e - cont.b, cont.b);
}
- *q++ = '"';
- *q++ = '\0';
- t.b = buf;
- t.e = q;
- WSPR(ew->sp, SLT_ESI_xmlerror, t);
+ eb->include = t;
+ VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
}
/*--------------------------------------------------------------------
if (celem == 0) {
o.b = r + 11;
- o.e = q;
- esi_addinclude(ew, o);
if (q[-1] != '/') {
esi_error(ew, p, 1 + q - p,
"ESI 1.0 wants emtpy esi:include");
+ o.e = q;
+ } else {
+ o.e = q - 1;
}
+ esi_addinclude(ew, o);
ew->dst.b = q + 1;
ew->dst.e = q + 1;
} else {