=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.111 retrieving revision 1.120 diff -u -p -r1.111 -r1.120 --- mandoc/roff.c 2010/12/29 01:16:57 1.111 +++ mandoc/roff.c 2011/01/03 23:24:16 1.120 @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.111 2010/12/29 01:16:57 kristaps Exp $ */ +/* $Id: roff.c,v 1.120 2011/01/03 23:24:16 schwarze Exp $ */ /* - * Copyright (c) 2010 Kristaps Dzonsons - * Copyright (c) 2010 Ingo Schwarze + * Copyright (c) 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2010, 2011 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -59,6 +59,7 @@ enum rofft { ROFF_tr, ROFF_TS, ROFF_TE, + ROFF_T_, ROFF_cblock, ROFF_ccond, /* FIXME: remove this. */ ROFF_USERDEF, @@ -85,7 +86,9 @@ struct roff { struct regset *regs; /* read/writable registers */ struct roffstr *first_string; /* user-defined strings & macros */ const char *current_string; /* value of last called user macro */ - struct tbl *tbl; + struct tbl_node *first_tbl; /* first table parsed */ + struct tbl_node *last_tbl; /* last table parsed */ + struct tbl_node *tbl; /* current table being parsed */ }; struct roffnode { @@ -143,6 +146,7 @@ static void roff_setstr(struct roff *, static enum rofferr roff_so(ROFF_ARGS); static enum rofferr roff_TE(ROFF_ARGS); static enum rofferr roff_TS(ROFF_ARGS); +static enum rofferr roff_T_(ROFF_ARGS); static enum rofferr roff_userdef(ROFF_ARGS); /* See roff_hash_find() */ @@ -175,6 +179,7 @@ static struct roffmac roffs[ROFF_MAX] = { { "tr", roff_line_ignore, NULL, NULL, 0, NULL }, { "TS", roff_TS, NULL, NULL, 0, NULL }, { "TE", roff_TE, NULL, NULL, 0, NULL }, + { "T&", roff_T_, NULL, NULL, 0, NULL }, { ".", roff_cblock, NULL, NULL, 0, NULL }, { "\\}", roff_ccond, NULL, NULL, 0, NULL }, { NULL, roff_userdef, NULL, NULL, 0, NULL }, @@ -296,12 +301,16 @@ roffnode_push(struct roff *r, enum rofft tok, const ch static void roff_free1(struct roff *r) { + struct tbl_node *t; - if (r->tbl) { - tbl_free(r->tbl); - r->tbl = NULL; + while (r->first_tbl) { + t = r->first_tbl; + r->first_tbl = t->next; + tbl_free(t); } + r->first_tbl = r->last_tbl = r->tbl = NULL; + while (r->last) roffnode_pop(r); @@ -506,15 +515,20 @@ roff_parseln(struct roff *r, int ln, char **bufp, } -int +void roff_endparse(struct roff *r) { - /* FIXME: if r->tbl */ if (r->last) (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, r->last->line, r->last->col, NULL); - return(1); + + if (r->tbl) { + (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, + r->tbl->line, r->tbl->pos, NULL); + tbl_end(r->tbl); + r->tbl = NULL; + } } @@ -1115,7 +1129,7 @@ roff_TE(ROFF_ARGS) if (NULL == r->tbl) (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL); else - tbl_free(r->tbl); + tbl_end(r->tbl); r->tbl = NULL; return(ROFF_IGN); @@ -1123,15 +1137,36 @@ roff_TE(ROFF_ARGS) /* ARGSUSED */ static enum rofferr +roff_T_(ROFF_ARGS) +{ + + if (NULL == r->tbl) + (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL); + else + tbl_restart(ppos, ln, r->tbl); + + return(ROFF_IGN); +} + +/* ARGSUSED */ +static enum rofferr roff_TS(ROFF_ARGS) { + struct tbl_node *t; if (r->tbl) { (*r->msg)(MANDOCERR_SCOPEBROKEN, r->data, ln, ppos, NULL); - tbl_reset(r->tbl); - } else - r->tbl = tbl_alloc(r->data, r->msg); + tbl_end(r->tbl); + } + t = tbl_alloc(ppos, ln, r->data, r->msg); + + if (r->last_tbl) + r->last_tbl->next = t; + else + r->first_tbl = r->last_tbl = t; + + r->tbl = r->last_tbl = t; return(ROFF_IGN); } @@ -1166,53 +1201,16 @@ roff_userdef(ROFF_ARGS) { const char *arg[9]; char *cp, *n1, *n2; - int i, quoted, pairs; + int i; /* * Collect pointers to macro argument strings * and null-terminate them. */ cp = *bufp + pos; - for (i = 0; i < 9; i++) { - /* Quoting can only start with a new word. */ - if ('"' == *cp) { - quoted = 1; - cp++; - } else - quoted = 0; - arg[i] = cp; - for (pairs = 0; '\0' != *cp; cp++) { - /* Unquoted arguments end at blanks. */ - if (0 == quoted) { - if (' ' == *cp) - break; - continue; - } - /* After pairs of quotes, move left. */ - if (pairs) - cp[-pairs] = cp[0]; - /* Pairs of quotes do not end words, ... */ - if ('"' == cp[0] && '"' == cp[1]) { - pairs++; - cp++; - continue; - } - /* ... but solitary quotes do. */ - if ('"' != *cp) - continue; - if (pairs) - cp[-pairs] = '\0'; - *cp = ' '; - break; - } - /* Last argument; the remaining ones are empty strings. */ - if ('\0' == *cp) - continue; - /* Null-terminate argument and move to the next one. */ - *cp++ = '\0'; - while (' ' == *cp) - cp++; - } + for (i = 0; i < 9; i++) + arg[i] = '\0' == *cp ? "" : + mandoc_getarg(&cp, r->msg, r->data, ln, &pos); /* * Expand macro arguments. @@ -1348,4 +1346,11 @@ roff_freestr(struct roff *r) } r->first_string = NULL; +} + +const struct tbl_span * +roff_span(const struct roff *r) +{ + + return(r->tbl ? tbl_span(r->tbl) : NULL); }