diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-01-10 23:53:33 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-01-10 23:53:33 +0000 |
commit | 32091ea77a0c9b3c6bdba26aa50d7d9212d45bd3 (patch) | |
tree | 4daa44cc742082a1a350500d2d405287c8ed8648 /usr.bin/mandoc | |
parent | 0da47356692d60755345bd20924a410a62488591 (diff) |
Refactoring in preparation for .rm support:
Unify parsing of names given as roff request arguments into a new
function roff_getname(), which is rather different from the parsing
function for normal arguments, mandoc_getarg(), because names cannot
be quoted and cannot contain whitespace or escaped characters.
The new function now throws an ERROR when finding escaped characters
in a name.
"I'm fine with this." kristaps@
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/main.c | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 83 |
3 files changed, 49 insertions, 40 deletions
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 6e699387762..682a3b1bb03 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.65 2011/01/09 13:16:48 schwarze Exp $ */ +/* $Id: main.c,v 1.66 2011/01/10 23:53:32 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> @@ -179,6 +179,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "input stack limit exceeded, infinite loop?", "skipping bad character", + "escaped character not allowed in a name", "skipping text before the first section header", "skipping unknown macro", "NOT IMPLEMENTED: skipping request", diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index fc317069d5e..bb2a7074f12 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.28 2011/01/09 14:30:48 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.29 2011/01/10 23:53:32 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -116,6 +116,7 @@ enum mandocerr { MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */ MANDOCERR_BADCHAR, /* skipping bad character */ + MANDOCERR_NAMESC, /* escaped character not allowed in a name */ MANDOCERR_NOTEXT, /* skipping text before the first section header */ MANDOCERR_MACRO, /* skipping unknown macro */ MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */ diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index f4bc46244b7..7f58211bc55 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.27 2011/01/04 22:28:17 schwarze Exp $ */ +/* $Id: roff.c,v 1.28 2011/01/10 23:53:32 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -130,6 +130,7 @@ static enum rofferr roff_cond_sub(ROFF_ARGS); static enum rofferr roff_ds(ROFF_ARGS); static enum roffrule roff_evalcond(const char *, int *); static void roff_freestr(struct roff *); +static char *roff_getname(struct roff *, char **, int, int); static const char *roff_getstrn(const struct roff *, const char *, size_t); static enum rofferr roff_line_ignore(ROFF_ARGS); @@ -1052,25 +1053,13 @@ roff_ds(ROFF_ARGS) * will have `bar " ' as its value. */ - name = *bufp + pos; + string = *bufp + pos; + name = roff_getname(r, &string, ln, pos); if ('\0' == *name) return(ROFF_IGN); - string = name; - /* Read until end of name. */ - while (*string && ' ' != *string) - string++; - - /* Nil-terminate name. */ - if (*string) - *(string++) = '\0'; - - /* Read past spaces. */ - while (*string && ' ' == *string) - string++; - - /* Read passed initial double-quote. */ - if (*string && '"' == *string) + /* Read past initial double-quote. */ + if ('"' == *string) string++; /* The rest is the value. */ @@ -1083,31 +1072,14 @@ roff_ds(ROFF_ARGS) static enum rofferr roff_nr(ROFF_ARGS) { - const char *key, *val; + const char *key; + char *val; struct reg *rg; - key = &(*bufp)[pos]; + val = *bufp + pos; + key = roff_getname(r, &val, ln, pos); rg = r->regs->regs; - /* Parse register request. */ - while ((*bufp)[pos] && ' ' != (*bufp)[pos]) - pos++; - - /* - * Set our nil terminator. Because this line is going to be - * ignored anyway, we can munge it as we please. - */ - if ((*bufp)[pos]) - (*bufp)[pos++] = '\0'; - - /* Skip whitespace to register token. */ - while ((*bufp)[pos] && ' ' == (*bufp)[pos]) - pos++; - - val = &(*bufp)[pos]; - - /* Process register token. */ - if (0 == strcmp(key, "nS")) { rg[(int)REG_nS].set = 1; if ( ! roff_parse_nat(val, &rg[(int)REG_nS].v.u)) @@ -1246,6 +1218,41 @@ roff_userdef(ROFF_ARGS) ROFF_REPARSE : ROFF_APPEND); } + +static char * +roff_getname(struct roff *r, char **cpp, int ln, int pos) +{ + char *name, *cp; + + name = *cpp; + if ('\0' == *name) + return(name); + + /* Read until end of name. */ + for (cp = name; '\0' != *cp && ' ' != *cp; cp++) { + if ('\\' != *cp) + continue; + cp++; + if ('\\' == *cp) + continue; + (*r->msg)(MANDOCERR_NAMESC, r->data, ln, pos, NULL); + *cp = '\0'; + name = cp; + } + + /* Nil-terminate name. */ + if ('\0' != *cp) + *(cp++) = '\0'; + + /* Read past spaces. */ + while (' ' == *cp) + cp++; + + *cpp = cp; + return(name); +} + + /* * Store *string into the user-defined string called *name. * In multiline mode, append to an existing entry and append '\n'; |