version 1.14, 2019/04/05 14:37:36 |
version 1.17, 2019/04/07 14:49:26 |
|
|
int nline; /* Line number of next token. */ |
int nline; /* Line number of next token. */ |
int ncol; /* Column number of next token. */ |
int ncol; /* Column number of next token. */ |
int del; /* Levels of nested nodes being deleted. */ |
int del; /* Levels of nested nodes being deleted. */ |
|
int spc; /* Whitespace before the next element. */ |
int attr; /* The most recent attribute is valid. */ |
int attr; /* The most recent attribute is valid. */ |
int warn; |
int warn; |
}; |
}; |
Line 170 static const struct element elements[] = { |
|
Line 171 static const struct element elements[] = { |
|
{ "sect2", NODE_SECTION }, |
{ "sect2", NODE_SECTION }, |
{ "section", NODE_SECTION }, |
{ "section", NODE_SECTION }, |
{ "sgmltag", NODE_SGMLTAG }, |
{ "sgmltag", NODE_SGMLTAG }, |
|
{ "simpara", NODE_PARA }, |
{ "simplelist", NODE_SIMPLELIST }, |
{ "simplelist", NODE_SIMPLELIST }, |
{ "spanspec", NODE_SPANSPEC }, |
{ "spanspec", NODE_SPANSPEC }, |
{ "structfield", NODE_PARAMETER }, |
{ "structfield", NODE_PARAMETER }, |
|
|
xml_char(struct parse *ps, const char *p, int sz) |
xml_char(struct parse *ps, const char *p, int sz) |
{ |
{ |
struct pnode *dat; |
struct pnode *dat; |
|
size_t newsz; |
|
|
if (ps->del > 0) |
if (ps->del > 0) |
return; |
return; |
Line 308 xml_char(struct parse *ps, const char *p, int sz) |
|
Line 311 xml_char(struct parse *ps, const char *p, int sz) |
|
exit(1); |
exit(1); |
} |
} |
dat->node = NODE_TEXT; |
dat->node = NODE_TEXT; |
|
dat->spc = ps->spc; |
dat->parent = ps->cur; |
dat->parent = ps->cur; |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->attrq); |
TAILQ_INIT(&dat->attrq); |
Line 322 xml_char(struct parse *ps, const char *p, int sz) |
|
Line 326 xml_char(struct parse *ps, const char *p, int sz) |
|
/* Append to the current text node. */ |
/* Append to the current text node. */ |
|
|
assert(sz >= 0); |
assert(sz >= 0); |
ps->cur->b = realloc(ps->cur->b, ps->cur->bsz + sz + 1); |
newsz = ps->cur->bsz + (ps->cur->bsz && ps->spc) + sz; |
|
ps->cur->b = realloc(ps->cur->b, newsz + 1); |
if (ps->cur->b == NULL) { |
if (ps->cur->b == NULL) { |
perror(NULL); |
perror(NULL); |
exit(1); |
exit(1); |
} |
} |
|
if (ps->cur->bsz && ps->spc) |
|
ps->cur->b[ps->cur->bsz++] = ' '; |
memcpy(ps->cur->b + ps->cur->bsz, p, sz); |
memcpy(ps->cur->b + ps->cur->bsz, p, sz); |
ps->cur->bsz += sz; |
ps->cur->b[ps->cur->bsz = newsz] = '\0'; |
ps->cur->b[ps->cur->bsz] = '\0'; |
|
ps->cur->real = ps->cur->b; |
ps->cur->real = ps->cur->b; |
|
ps->spc = 0; |
} |
} |
|
|
|
/* |
|
* Close out the text node and strip trailing whitespace, if one is open. |
|
*/ |
static void |
static void |
pnode_trim(struct pnode *pn) |
pnode_closetext(struct parse *p) |
{ |
{ |
assert(pn->node == NODE_TEXT); |
struct pnode *n; |
for (; pn->bsz > 0; pn->b[--pn->bsz] = '\0') |
|
if (isspace((unsigned char)pn->b[pn->bsz - 1]) == 0) |
if ((n = p->cur) == NULL || n->node != NODE_TEXT) |
break; |
return; |
|
p->cur = n->parent; |
|
while (n->bsz > 0 && isspace((unsigned char)n->b[n->bsz - 1])) { |
|
n->b[--n->bsz] = '\0'; |
|
p->spc = 1; |
|
} |
} |
} |
|
|
static void |
static void |
Line 356 xml_entity(struct parse *p, const char *name) |
|
Line 371 xml_entity(struct parse *p, const char *name) |
|
return; |
return; |
} |
} |
|
|
/* Close out the text node, if there is one. */ |
pnode_closetext(p); |
if (p->cur->node == NODE_TEXT) { |
|
pnode_trim(p->cur); |
|
p->cur = p->cur->parent; |
|
} |
|
|
|
if (p->tree->flags & TREE_CLOSED && p->cur == p->tree->root) |
if (p->tree->flags & TREE_CLOSED && p->cur == p->tree->root) |
warn_msg(p, "entity after end of document: &%s;", name); |
warn_msg(p, "entity after end of document: &%s;", name); |
Line 382 xml_entity(struct parse *p, const char *name) |
|
Line 393 xml_entity(struct parse *p, const char *name) |
|
} |
} |
dat->node = NODE_ESCAPE; |
dat->node = NODE_ESCAPE; |
dat->bsz = strlen(dat->b); |
dat->bsz = strlen(dat->b); |
|
dat->spc = p->spc; |
dat->parent = p->cur; |
dat->parent = p->cur; |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->attrq); |
TAILQ_INIT(&dat->attrq); |
TAILQ_INSERT_TAIL(&p->cur->childq, dat, child); |
TAILQ_INSERT_TAIL(&p->cur->childq, dat, child); |
|
p->spc = 0; |
} |
} |
|
|
/* |
/* |
Line 409 xml_elem_start(struct parse *ps, const char *name) |
|
Line 422 xml_elem_start(struct parse *ps, const char *name) |
|
return; |
return; |
} |
} |
|
|
/* Close out the text node, if there is one. */ |
pnode_closetext(ps); |
if (ps->cur != NULL && ps->cur->node == NODE_TEXT) { |
|
pnode_trim(ps->cur); |
|
ps->cur = ps->cur->parent; |
|
} |
|
|
|
for (elem = elements; elem->name != NULL; elem++) |
for (elem = elements; elem->name != NULL; elem++) |
if (strcmp(elem->name, name) == 0) |
if (strcmp(elem->name, name) == 0) |
Line 447 xml_elem_start(struct parse *ps, const char *name) |
|
Line 456 xml_elem_start(struct parse *ps, const char *name) |
|
perror(NULL); |
perror(NULL); |
exit(1); |
exit(1); |
} |
} |
dat->node = elem->node; |
|
|
/* |
|
* Nodes that begin a new macro or request line or start by |
|
* printing text always want whitespace before themselves. |
|
*/ |
|
|
|
switch (dat->node = elem->node) { |
|
case NODE_AUTHORGROUP: |
|
case NODE_BOOKINFO: |
|
case NODE_CAUTION: |
|
case NODE_EDITOR: |
|
case NODE_ENTRY: |
|
case NODE_FUNCDEF: |
|
case NODE_FUNCPROTOTYPE: |
|
case NODE_INFORMALEQUATION: |
|
case NODE_INLINEEQUATION: |
|
case NODE_ITEMIZEDLIST: |
|
case NODE_LEGALNOTICE: |
|
case NODE_LITERALLAYOUT: |
|
case NODE_NOTE: |
|
case NODE_ORDEREDLIST: |
|
case NODE_PARA: |
|
case NODE_PREFACE: |
|
case NODE_PROGRAMLISTING: |
|
case NODE_REFMETA: |
|
case NODE_REFNAMEDIV: |
|
case NODE_REFSYNOPSISDIV: |
|
case NODE_ROW: |
|
case NODE_SBR: |
|
case NODE_SCREEN: |
|
case NODE_SECTION: |
|
case NODE_SYNOPSIS: |
|
case NODE_TGROUP: |
|
case NODE_TIP: |
|
case NODE_TITLE: |
|
case NODE_VARIABLELIST: |
|
case NODE_VARLISTENTRY: |
|
case NODE_WARNING: |
|
dat->spc = 1; |
|
break; |
|
default: |
|
dat->spc = ps->spc; |
|
break; |
|
} |
dat->parent = ps->cur; |
dat->parent = ps->cur; |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->childq); |
TAILQ_INIT(&dat->attrq); |
TAILQ_INIT(&dat->attrq); |
Line 518 xml_elem_end(struct parse *ps, const char *name) |
|
Line 570 xml_elem_end(struct parse *ps, const char *name) |
|
return; |
return; |
} |
} |
|
|
/* Close out the text node, if there is one. */ |
if (ps->del == 0) |
if (ps->del == 0 && ps->cur != NULL && ps->cur->node == NODE_TEXT) { |
pnode_closetext(ps); |
pnode_trim(ps->cur); |
|
ps->cur = ps->cur->parent; |
|
} |
|
|
|
if (name != NULL) { |
if (name != NULL) { |
for (elem = elements; elem->name != NULL; elem++) |
for (elem = elements; elem->name != NULL; elem++) |
Line 557 xml_elem_end(struct parse *ps, const char *name) |
|
Line 606 xml_elem_end(struct parse *ps, const char *name) |
|
ps->tree->flags |= TREE_CLOSED; |
ps->tree->flags |= TREE_CLOSED; |
else |
else |
ps->cur = ps->cur->parent; |
ps->cur = ps->cur->parent; |
|
ps->spc = 0; |
break; |
break; |
} |
} |
assert(ps->del == 0); |
assert(ps->del == 0); |
Line 650 parse_string(struct parse *p, char *b, size_t rlen, |
|
Line 700 parse_string(struct parse *p, char *b, size_t rlen, |
|
size_t pend; /* Offset of the end of the current word. */ |
size_t pend; /* Offset of the end of the current word. */ |
int elem_end; |
int elem_end; |
|
|
|
p->spc = 0; |
pend = 0; |
pend = 0; |
for (;;) { |
for (;;) { |
|
|
Line 662 parse_string(struct parse *p, char *b, size_t rlen, |
|
Line 713 parse_string(struct parse *p, char *b, size_t rlen, |
|
if ((poff = pend) == rlen) |
if ((poff = pend) == rlen) |
break; |
break; |
if (isspace((unsigned char)b[pend])) { |
if (isspace((unsigned char)b[pend])) { |
|
p->spc = 1; |
increment(p, b, &pend, refill); |
increment(p, b, &pend, refill); |
continue; |
continue; |
} |
} |
Line 835 parse_file(struct parse *p, int fd, const char *fname) |
|
Line 887 parse_file(struct parse *p, int fd, const char *fname) |
|
perror(fname); |
perror(fname); |
p->tree->flags |= TREE_FAIL; |
p->tree->flags |= TREE_FAIL; |
} |
} |
if (p->cur != NULL && p->cur->node == NODE_TEXT) { |
pnode_closetext(p); |
pnode_trim(p->cur); |
|
p->cur = p->cur->parent; |
|
} |
|
if ((p->tree->flags & TREE_CLOSED) == 0) |
if ((p->tree->flags & TREE_CLOSED) == 0) |
warn_msg(p, "document not closed"); |
warn_msg(p, "document not closed"); |
return p->tree; |
return p->tree; |