version 1.1, 2008/12/23 05:30:49 |
version 1.2, 2008/12/28 00:34:20 |
|
|
#include "private.h" |
#include "private.h" |
|
|
|
|
static int parse_next(struct mdoc *, int, |
static int lookup(int, const char *); |
int *, char *, char **); |
static int parse(struct mdoc *, int, |
|
struct mdoc_arg *, int *, char *); |
|
static int postparse(struct mdoc *, int, |
|
const struct mdoc_arg *, int); |
|
|
|
|
static int |
int |
parse_next(struct mdoc *mdoc, int tok, |
mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) |
int *pos, char *buf, char **v) |
|
{ |
{ |
|
int i; |
|
|
if (0 == buf[*pos]) |
if (0 == buf[*pos]) |
return(0); |
return(ARGS_EOLN); |
|
|
|
if ('\"' == buf[*pos] && ! (fl & ARGS_QUOTED)) |
|
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_QUOTED)) |
|
return(ARGS_ERROR); |
|
|
|
if ('-' == buf[*pos]) |
|
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_ARGLIKE)) |
|
return(ARGS_ERROR); |
|
|
|
if ((fl & ARGS_DELIM) && mdoc_iscdelim(buf[*pos])) { |
|
for (i = *pos; buf[i]; ) { |
|
if ( ! mdoc_iscdelim(buf[i])) |
|
break; |
|
i++; |
|
if (0 == buf[i] || ! isspace(buf[i])) |
|
break; |
|
i++; |
|
while (buf[i] && isspace(buf[i])) |
|
i++; |
|
} |
|
if (0 == buf[i]) { |
|
*v = &buf[*pos]; |
|
return(ARGS_PUNCT); |
|
} |
|
} |
|
|
|
/* |
|
* Parse routine for non-quoted string. |
|
*/ |
|
|
if ('\"' != buf[*pos]) { |
if ('\"' != buf[*pos]) { |
*v = &buf[*pos]; |
*v = &buf[*pos]; |
|
|
Line 45 parse_next(struct mdoc *mdoc, int tok, |
|
Line 77 parse_next(struct mdoc *mdoc, int tok, |
|
(*pos)++; |
(*pos)++; |
|
|
if (0 == buf[*pos]) |
if (0 == buf[*pos]) |
return(1); |
return(ARGS_WORD); |
|
|
buf[(*pos)++] = 0; |
buf[(*pos)++] = 0; |
if (0 == buf[*pos]) |
if (0 == buf[*pos]) |
return(1); |
return(ARGS_WORD); |
|
|
while (buf[*pos] && isspace(buf[*pos])) |
while (buf[*pos] && isspace(buf[*pos])) |
(*pos)++; |
(*pos)++; |
|
|
if (buf[*pos]) |
if (buf[*pos]) |
return(1); |
return(ARGS_WORD); |
|
|
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) |
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) |
return(-1); |
return(ARGS_ERROR); |
return(1); |
|
} |
|
|
|
if ('-' == buf[*pos]) |
return(ARGS_WORD); |
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_ARGLIKE)) |
} |
return(-1); |
|
|
|
|
/* |
|
* If we're a quoted string (and quoted strings are allowed), |
|
* then parse ahead to the next quote. If none's found, it's an |
|
* error. After, parse to the next word. We're not allowed to |
|
* also be DELIM requests (for now). |
|
*/ |
|
assert( ! (fl & ARGS_DELIM)); |
|
|
*v = &buf[++(*pos)]; |
*v = &buf[++(*pos)]; |
|
|
while (buf[*pos] && '\"' != buf[*pos]) |
while (buf[*pos] && '\"' != buf[*pos]) |
Line 73 parse_next(struct mdoc *mdoc, int tok, |
|
Line 110 parse_next(struct mdoc *mdoc, int tok, |
|
|
|
if (0 == buf[*pos]) { |
if (0 == buf[*pos]) { |
(void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_UNQUOTE); |
(void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_UNQUOTE); |
return(-1); |
return(ARGS_ERROR); |
} |
} |
|
|
buf[(*pos)++] = 0; |
buf[(*pos)++] = 0; |
if (0 == buf[*pos]) |
if (0 == buf[*pos]) |
return(1); |
return(ARGS_WORD); |
|
|
while (buf[*pos] && isspace(buf[*pos])) |
while (buf[*pos] && isspace(buf[*pos])) |
(*pos)++; |
(*pos)++; |
|
|
if (buf[*pos]) |
if (buf[*pos]) |
return(1); |
return(ARGS_WORD); |
|
|
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) |
if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) |
return(-1); |
return(ARGS_ERROR); |
return(1); |
|
|
return(ARGS_WORD); |
} |
} |
|
|
|
|
int |
static int |
mdoc_argv_lookup(int tok, const char *argv) |
lookup(int tok, const char *argv) |
{ |
{ |
|
|
switch (tok) { |
switch (tok) { |
case (MDOC_Bl): |
case (MDOC_Bd): |
if (xstrcmp(argv, "ragged")) |
if (xstrcmp(argv, "ragged")) |
return(MDOC_Ragged); |
return(MDOC_Ragged); |
else if (xstrcmp(argv, "unfilled")) |
else if (xstrcmp(argv, "unfilled")) |
Line 108 mdoc_argv_lookup(int tok, const char *argv) |
|
Line 146 mdoc_argv_lookup(int tok, const char *argv) |
|
return(MDOC_File); |
return(MDOC_File); |
else if (xstrcmp(argv, "offset")) |
else if (xstrcmp(argv, "offset")) |
return(MDOC_Offset); |
return(MDOC_Offset); |
else if (xstrcmp(argv, "bullet")) |
break; |
|
|
|
case (MDOC_Bl): |
|
if (xstrcmp(argv, "bullet")) |
return(MDOC_Bullet); |
return(MDOC_Bullet); |
else if (xstrcmp(argv, "dash")) |
else if (xstrcmp(argv, "dash")) |
return(MDOC_Dash); |
return(MDOC_Dash); |
Line 132 mdoc_argv_lookup(int tok, const char *argv) |
|
Line 173 mdoc_argv_lookup(int tok, const char *argv) |
|
return(MDOC_Column); |
return(MDOC_Column); |
else if (xstrcmp(argv, "width")) |
else if (xstrcmp(argv, "width")) |
return(MDOC_Width); |
return(MDOC_Width); |
|
else if (xstrcmp(argv, "offset")) |
|
return(MDOC_Offset); |
else if (xstrcmp(argv, "compact")) |
else if (xstrcmp(argv, "compact")) |
return(MDOC_Compact); |
return(MDOC_Compact); |
|
|
break; |
break; |
|
|
default: |
default: |
abort(); |
abort(); |
/* NOTREACHED */ |
/* NOTREACHED */ |
Line 145 mdoc_argv_lookup(int tok, const char *argv) |
|
Line 188 mdoc_argv_lookup(int tok, const char *argv) |
|
} |
} |
|
|
|
|
int |
static int |
mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
postparse(struct mdoc *mdoc, int tok, const struct mdoc_arg *v, int pos) |
|
{ |
|
|
|
switch (v->arg) { |
|
case (MDOC_Offset): |
|
assert(v->value); |
|
assert(v->value[0]); |
|
if (xstrcmp(v->value[0], "left")) |
|
break; |
|
if (xstrcmp(v->value[0], "right")) |
|
break; |
|
if (xstrcmp(v->value[0], "center")) |
|
break; |
|
if (xstrcmp(v->value[0], "indent")) |
|
break; |
|
if (xstrcmp(v->value[0], "indent-two")) |
|
break; |
|
return(mdoc_err(mdoc, tok, pos, ERR_SYNTAX_ARGBAD)); |
|
default: |
|
break; |
|
} |
|
|
|
return(1); |
|
} |
|
|
|
|
|
static int |
|
parse(struct mdoc *mdoc, int tok, |
struct mdoc_arg *v, int *pos, char *buf) |
struct mdoc_arg *v, int *pos, char *buf) |
{ |
{ |
char *p; |
char *p; |
int c, ppos, i; |
int c, ppos, i; |
|
|
v->arg = arg; |
|
ppos = *pos; |
ppos = *pos; |
|
|
switch (arg) { |
switch (v->arg) { |
case(MDOC_Compact): |
case(MDOC_Compact): |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case(MDOC_Ragged): |
case(MDOC_Ragged): |
Line 195 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
Line 264 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
/* |
/* |
* This has a single value for an argument. |
* This has a single value for an argument. |
*/ |
*/ |
c = parse_next(mdoc, tok, pos, buf, &p); |
c = mdoc_args(mdoc, tok, pos, buf, ARGS_QUOTED, &p); |
if (-1 == c) |
if (ARGS_ERROR == c) |
return(0); |
return(0); |
else if (0 == c) |
else if (ARGS_EOLN == c) |
return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL)); |
return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL)); |
|
|
v->sz = 1; |
v->sz = 1; |
Line 215 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
Line 284 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
v->sz = 0; |
v->sz = 0; |
v->value = xcalloc(MDOC_LINEARG_MAX, sizeof(char *)); |
v->value = xcalloc(MDOC_LINEARG_MAX, sizeof(char *)); |
for (i = 0; i < MDOC_LINEARG_MAX; i++) { |
for (i = 0; i < MDOC_LINEARG_MAX; i++) { |
c = parse_next(mdoc, tok, pos, buf, &p); |
c = mdoc_args(mdoc, tok, pos, buf, ARGS_QUOTED, &p); |
if (-1 == c) { |
if (ARGS_ERROR == c) { |
free(v->value); |
free(v->value); |
return(0); |
return(0); |
} else if (0 == c) |
} else if (ARGS_EOLN == c) |
break; |
break; |
v->value[i] = p; |
v->value[i] = p; |
} |
} |
Line 240 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
Line 309 mdoc_argv_parse(struct mdoc *mdoc, int tok, int arg, |
|
} |
} |
|
|
|
|
|
int |
|
mdoc_argv(struct mdoc *mdoc, int tok, |
|
struct mdoc_arg *v, int *pos, char *buf) |
|
{ |
|
int i, ppos; |
|
char *argv; |
|
|
|
(void)memset(v, 0, sizeof(struct mdoc_arg)); |
|
|
|
if (0 == buf[*pos]) |
|
return(0); |
|
|
|
assert( ! isspace(buf[*pos])); |
|
|
|
if ('-' != buf[*pos]) { |
|
(void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_ARGFORM); |
|
return(-1); |
|
} |
|
|
|
i = *pos; |
|
argv = &buf[++(*pos)]; |
|
|
|
while (buf[*pos] && ! isspace(buf[*pos])) |
|
(*pos)++; |
|
|
|
if (buf[*pos]) |
|
buf[(*pos)++] = 0; |
|
|
|
if (MDOC_ARG_MAX == (v->arg = lookup(tok, argv))) { |
|
(void)mdoc_err(mdoc, tok, i, ERR_SYNTAX_ARG); |
|
return(-1); |
|
} |
|
|
|
while (buf[*pos] && isspace(buf[*pos])) |
|
(*pos)++; |
|
|
|
/* FIXME: whitespace if no value. */ |
|
|
|
ppos = *pos; |
|
if ( ! parse(mdoc, tok, v, pos, buf)) |
|
return(-1); |
|
if ( ! postparse(mdoc, tok, v, ppos)) |
|
return(-1); |
|
|
|
return(1); |
|
} |
|
|
|
|
void |
void |
mdoc_argv_free(int sz, struct mdoc_arg *arg) |
mdoc_argv_free(int sz, struct mdoc_arg *arg) |
{ |
{ |
Line 254 mdoc_argv_free(int sz, struct mdoc_arg *arg) |
|
Line 371 mdoc_argv_free(int sz, struct mdoc_arg *arg) |
|
free(arg[i].value); |
free(arg[i].value); |
} |
} |
} |
} |
|
|