26 #ifndef XML_STATUS_ERROR
27 #define XML_STATUS_ERROR 0
52 static void error_context(
void)
77 static void lexerror(
const char *name)
81 agerr(
AGERR,
"Unknown HTML element <%s> on line %d \n",
85 typedef int (*attrFn) (
void *,
char *);
86 typedef int (*bcmpfn) (
const void *,
const void *);
88 #define MAX_CHAR (((unsigned char)(~0)) >> 1)
89 #define MIN_CHAR ((signed char)(~MAX_CHAR))
90 #define MAX_UCHAR ((unsigned char)(~0))
91 #define MAX_USHORT ((unsigned short)(~0))
99 #define ISIZE (sizeof(attr_item))
104 static int icmp(attr_item * i, attr_item * j)
115 static int pencolorfn(
htmldata_t * p,
char *v)
129 unsigned short flags = 0;
133 switch (tolower(c)) {
147 agerr(
AGWARN,
"Unrecognized character '%c' (%d) in sides attribute\n", c, c);
158 p->
title = strdup(v);
175 char* buf = strdup (v);
176 for (tk = strtok (buf, DELIM); tk; tk = strtok (
NULL, DELIM)) {
177 c = (char) toupper(*tk);
182 agerr(
AGWARN,
"Illegal value %s for STYLE - ignored\n", tk);
191 agerr(
AGWARN,
"Illegal value %s for STYLE - ignored\n", tk);
218 static int doInt(
char *v,
char *
s,
int min,
int max,
long *ul)
222 long b = strtol(v, &ep, 10);
225 agerr(
AGWARN,
"Improper %s value %s - ignored", s, v);
227 }
else if (b > max) {
228 agerr(
AGWARN,
"%s value %s > %d - too large - ignored", s, v, max);
230 }
else if (b < min) {
231 agerr(
AGWARN,
"%s value %s < %d - too small - ignored", s, v, min);
239 static int gradientanglefn(
htmldata_t * p,
char *v)
243 if (doInt(v,
"GRADIENTANGLE", 0, 360, &u))
254 if (doInt(v,
"BORDER", 0, MAX_UCHAR, &u))
256 p->
border = (
unsigned char) u;
261 static int cellpaddingfn(
htmldata_t * p,
char *v)
265 if (doInt(v,
"CELLPADDING", 0, MAX_UCHAR, &u))
267 p->
pad = (
unsigned char) u;
272 static int cellspacingfn(
htmldata_t * p,
char *v)
276 if (doInt(v,
"CELLSPACING", MIN_CHAR, MAX_CHAR, &u))
278 p->
space = (
signed char) u;
283 static int cellborderfn(
htmltbl_t * p,
char *v)
287 if (doInt(v,
"CELLSBORDER", 0, MAX_CHAR, &u))
289 p->
cb = (
unsigned char) u;
293 static int columnsfn(
htmltbl_t * p,
char *v)
296 agerr(
AGWARN,
"Unknown value %s for COLUMNS - ignored\n", v);
303 static int rowsfn(
htmltbl_t * p,
char *v)
306 agerr(
AGWARN,
"Unknown value %s for ROWS - ignored\n", v);
313 static int fixedsizefn(
htmldata_t * p,
char *v)
316 char c = (char) toupper(*(
unsigned char *) v);
320 agerr(
AGWARN,
"Illegal value %s for FIXEDSIZE - ignored\n", v);
329 char c = (char) toupper(*v);
330 if ((c ==
'B') && !
strcasecmp(v + 1,
"OTTOM"))
335 agerr(
AGWARN,
"Illegal value %s for VALIGN - ignored\n", v);
344 char c = (char) toupper(*v);
350 agerr(
AGWARN,
"Illegal value %s for ALIGN - ignored\n", v);
356 static int cell_halignfn(
htmldata_t * p,
char *v)
359 char c = (char) toupper(*v);
369 agerr(
AGWARN,
"Illegal value %s for ALIGN in TD - ignored\n", v);
376 char c = (char) toupper(*v);
384 agerr(
AGWARN,
"Illegal value %s for BALIGN in TD - ignored\n", v);
392 if (doInt(v,
"HEIGHT", 0, MAX_USHORT, &u))
394 p->
height = (
unsigned short) u;
402 if (doInt(v,
"WIDTH", 0, MAX_USHORT, &u))
404 p->
width = (
unsigned short) u;
412 if (doInt(v,
"ROWSPAN", 0, MAX_USHORT, &u))
415 agerr(
AGWARN,
"ROWSPAN value cannot be 0 - ignored\n");
418 p->
rspan = (
unsigned short) u;
426 if (doInt(v,
"COLSPAN", 0, MAX_USHORT, &u))
429 agerr(
AGWARN,
"COLSPAN value cannot be 0 - ignored\n");
432 p->
cspan = (
unsigned short) u;
436 static int fontcolorfn(
textfont_t * p,
char *v)
452 if (doInt(v,
"POINT-SIZE", 0, MAX_UCHAR, &u))
454 p->
size = (double) u;
464 static int scalefn(
htmlimg_t * p,
char *v)
466 p->
scale = strdup(v);
470 static int alignfn(
int *p,
char *v)
473 char c = (char) toupper(*v);
476 else if ((c ==
'L') || !
strcasecmp(v + 1,
"EFT"))
478 else if ((c ==
'C') ||
strcasecmp(v + 1,
"ENTER"))
481 agerr(
AGWARN,
"Illegal value %s for ALIGN - ignored\n", v);
488 static attr_item tbl_items[] = {
489 {
"align", (attrFn) halignfn},
490 {
"bgcolor", (attrFn) bgcolorfn},
491 {
"border", (attrFn) borderfn},
492 {
"cellborder", (attrFn) cellborderfn},
493 {
"cellpadding", (attrFn) cellpaddingfn},
494 {
"cellspacing", (attrFn) cellspacingfn},
495 {
"color", (attrFn) pencolorfn},
496 {
"columns", (attrFn) columnsfn},
497 {
"fixedsize", (attrFn) fixedsizefn},
498 {
"gradientangle", (attrFn) gradientanglefn},
499 {
"height", (attrFn) heightfn},
500 {
"href", (attrFn) hreffn},
501 {
"id", (attrFn) idfn},
502 {
"port", (attrFn) portfn},
503 {
"rows", (attrFn) rowsfn},
504 {
"sides", (attrFn) sidesfn},
505 {
"style", (attrFn) stylefn},
506 {
"target", (attrFn) targetfn},
507 {
"title", (attrFn) titlefn},
508 {
"tooltip", (attrFn) titlefn},
509 {
"valign", (attrFn) valignfn},
510 {
"width", (attrFn) widthfn},
513 static attr_item cell_items[] = {
514 {
"align", (attrFn) cell_halignfn},
515 {
"balign", (attrFn) balignfn},
516 {
"bgcolor", (attrFn) bgcolorfn},
517 {
"border", (attrFn) borderfn},
518 {
"cellpadding", (attrFn) cellpaddingfn},
519 {
"cellspacing", (attrFn) cellspacingfn},
520 {
"color", (attrFn) pencolorfn},
521 {
"colspan", (attrFn) colspanfn},
522 {
"fixedsize", (attrFn) fixedsizefn},
523 {
"gradientangle", (attrFn) gradientanglefn},
524 {
"height", (attrFn) heightfn},
525 {
"href", (attrFn) hreffn},
526 {
"id", (attrFn) idfn},
527 {
"port", (attrFn) portfn},
528 {
"rowspan", (attrFn) rowspanfn},
529 {
"sides", (attrFn) sidesfn},
530 {
"style", (attrFn) stylefn},
531 {
"target", (attrFn) targetfn},
532 {
"title", (attrFn) titlefn},
533 {
"tooltip", (attrFn) titlefn},
534 {
"valign", (attrFn) valignfn},
535 {
"width", (attrFn) widthfn},
538 static attr_item font_items[] = {
539 {
"color", (attrFn) fontcolorfn},
540 {
"face", (attrFn) facefn},
541 {
"point-size", (attrFn) ptsizefn},
544 static attr_item img_items[] = {
545 {
"scale", (attrFn) scalefn},
546 {
"src", (attrFn) srcfn},
549 static attr_item br_items[] = {
550 {
"align", (attrFn) alignfn},
562 doAttrs(
void *tp, attr_item * items,
int nel,
char **atts,
char *s)
569 while ((name = *atts++) !=
NULL) {
572 ip = (attr_item *) bsearch(&key, items, nel, ISIZE, (bcmpfn) icmp);
574 state.
warn |= ip->action(tp, val);
576 agerr(
AGWARN,
"Illegal attribute %s in %s - ignored\n", name,
583 static void mkBR(
char **atts)
586 doAttrs(&
htmllval.
i, br_items,
sizeof(br_items) / ISIZE, atts,
"<BR>");
593 doAttrs(img, img_items,
sizeof(img_items) / ISIZE, atts,
"<IMG>");
605 doAttrs(&tf, font_items,
sizeof(font_items) / ISIZE, atts,
"<FONT>");
616 doAttrs(cell, cell_items,
sizeof(cell_items) / ISIZE, atts,
"<TD>");
627 doAttrs(tbl, tbl_items,
sizeof(tbl_items) / ISIZE, atts,
"<TABLE>");
632 static void startElement(
void *user,
const char *name,
char **atts)
689 static void endElement(
void *user,
const char *name)
750 static void characterData(
void *user,
const char *s,
int length)
756 for (i = length; i; i--) {
781 XML_SetUserData(state.parser,
GD_gvc(env->
g));
782 XML_SetElementHandler(state.parser,
783 (XML_StartElementHandler) startElement,
785 XML_SetCharacterDataHandler(state.parser, characterData);
791 "Not built with libexpat. Table formatting is not available.\n");
802 XML_ParserFree(state.parser);
817 static char *eatComment(
char *p)
823 while (depth && (c = *s++)) {
832 if ((t < p) || strncmp(t,
"--", 2)) {
844 static char *findNext(
char *s,
agxbuf* xb)
850 if ((*t ==
'!') && !strncmp(t + 1,
"--", 2))
851 t = eatComment(t + 3);
853 while (*t && (*t !=
'>'))
856 agerr(
AGWARN,
"Label closed before end of HTML element\n");
862 while ((c = *t) && (c !=
'<')) {
863 if ((c ==
'&') && (*(t+1) !=
'#')) {
879 return XML_GetCurrentLineNumber(state.parser);
886 static void printTok(
int tok)
991 fprintf(stderr,
"%s \"", s);
993 fprintf(stderr,
"\"\n");
995 fprintf(stderr,
"%s\n", s);
1003 static char *begin_html =
"<HTML>";
1004 static char *end_html =
"</HTML>";
1013 if (state.
mode == 2)
1015 if (state.
mode == 0) {
1027 endp = findNext(s,&state.
lb);
1036 rv = XML_Parse(state.parser,
agxbuse(&state.
lb),llen, 0);
1038 rv = XML_Parse(state.parser, s, len, (len ? 0 : 1));
1042 XML_ErrorString(XML_GetErrorCode(state.parser)),
1051 }
while (state.
tok == 0);
1053 printTok (state.
tok);
int initHTMLlexer(char *src, agxbuf *xb, htmlenv_t *env)
int agerr(agerrlevel_t level, const char *fmt,...)
char * scanEntity(char *t, agxbuf *xb)
void agxbinit(agxbuf *xb, unsigned int hint, unsigned char *init)
if(aagss+aagstacksize-1<=aagssp)
int strcasecmp(const char *s1, const char *s2)
size_t agxbput_n(agxbuf *xb, const char *s, size_t ssz)
void htmlerror(const char *msg)
void agxbfree(agxbuf *xb)