version 1.115, 2011/01/01 15:45:18 |
version 1.120, 2011/01/03 23:24:16 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
struct regset *regs; /* read/writable registers */ |
struct regset *regs; /* read/writable registers */ |
struct roffstr *first_string; /* user-defined strings & macros */ |
struct roffstr *first_string; /* user-defined strings & macros */ |
const char *current_string; /* value of last called user macro */ |
const char *current_string; /* value of last called user macro */ |
struct tbl *first_tbl; /* first table parsed */ |
struct tbl_node *first_tbl; /* first table parsed */ |
struct tbl *last_tbl; /* last table parsed */ |
struct tbl_node *last_tbl; /* last table parsed */ |
struct tbl *tbl; /* current table being parsed */ |
struct tbl_node *tbl; /* current table being parsed */ |
}; |
}; |
|
|
struct roffnode { |
struct roffnode { |
Line 301 roffnode_push(struct roff *r, enum rofft tok, const ch |
|
Line 301 roffnode_push(struct roff *r, enum rofft tok, const ch |
|
static void |
static void |
roff_free1(struct roff *r) |
roff_free1(struct roff *r) |
{ |
{ |
struct tbl *t; |
struct tbl_node *t; |
|
|
while (r->first_tbl) { |
while (r->first_tbl) { |
t = r->first_tbl; |
t = r->first_tbl; |
Line 515 roff_parseln(struct roff *r, int ln, char **bufp, |
|
Line 515 roff_parseln(struct roff *r, int ln, char **bufp, |
|
} |
} |
|
|
|
|
int |
void |
roff_endparse(struct roff *r) |
roff_endparse(struct roff *r) |
{ |
{ |
|
|
/* FIXME: if r->tbl */ |
|
if (r->last) |
if (r->last) |
(*r->msg)(MANDOCERR_SCOPEEXIT, r->data, |
(*r->msg)(MANDOCERR_SCOPEEXIT, r->data, |
r->last->line, r->last->col, NULL); |
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; |
|
} |
} |
} |
|
|
|
|
Line 1138 roff_T_(ROFF_ARGS) |
|
Line 1143 roff_T_(ROFF_ARGS) |
|
if (NULL == r->tbl) |
if (NULL == r->tbl) |
(*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL); |
(*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL); |
else |
else |
tbl_restart(r->tbl); |
tbl_restart(ppos, ln, r->tbl); |
|
|
return(ROFF_IGN); |
return(ROFF_IGN); |
} |
} |
Line 1147 roff_T_(ROFF_ARGS) |
|
Line 1152 roff_T_(ROFF_ARGS) |
|
static enum rofferr |
static enum rofferr |
roff_TS(ROFF_ARGS) |
roff_TS(ROFF_ARGS) |
{ |
{ |
struct tbl *t; |
struct tbl_node *t; |
|
|
if (r->tbl) { |
if (r->tbl) { |
(*r->msg)(MANDOCERR_SCOPEBROKEN, r->data, ln, ppos, NULL); |
(*r->msg)(MANDOCERR_SCOPEBROKEN, r->data, ln, ppos, NULL); |
Line 1196 roff_userdef(ROFF_ARGS) |
|
Line 1201 roff_userdef(ROFF_ARGS) |
|
{ |
{ |
const char *arg[9]; |
const char *arg[9]; |
char *cp, *n1, *n2; |
char *cp, *n1, *n2; |
int i, quoted, pairs; |
int i; |
|
|
/* |
/* |
* Collect pointers to macro argument strings |
* Collect pointers to macro argument strings |
* and null-terminate them. |
* and null-terminate them. |
*/ |
*/ |
cp = *bufp + pos; |
cp = *bufp + pos; |
for (i = 0; i < 9; i++) { |
for (i = 0; i < 9; i++) |
/* Quoting can only start with a new word. */ |
arg[i] = '\0' == *cp ? "" : |
if ('"' == *cp) { |
mandoc_getarg(&cp, r->msg, r->data, ln, &pos); |
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++; |
|
} |
|
|
|
/* |
/* |
* Expand macro arguments. |
* Expand macro arguments. |