-/* $Id: mdoc_argv.c,v 1.35 2010/03/31 07:13:53 kristaps Exp $ */
+/* $Id: mdoc_argv.c,v 1.43 2010/05/08 07:30:19 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#define MULTI_STEP 5
static int argv_a2arg(enum mdoct, const char *);
-static int args(struct mdoc *, int, int *,
+static enum margserr args(struct mdoc *, int, int *,
char *, int, char **);
static int argv(struct mdoc *, int,
struct mdoc_argv *, int *, char *);
* [value0...], which may either have a single mandatory value, at least
* one mandatory value, an optional single value, or no value.
*/
-int
+enum margverr
mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
struct mdoc_arg **v, int *pos, char *buf)
{
void
mdoc_argv_free(struct mdoc_arg *p)
{
- int i, j;
+ int i;
if (NULL == p)
return;
}
assert(p->argc);
- /* LINTED */
- for (i = 0; i < (int)p->argc; i++) {
- if (0 == p->argv[i].sz)
- continue;
- if (NULL == p->argv[i].value)
- continue;
+ for (i = (int)p->argc - 1; i >= 0; i--)
+ mdoc_argn_free(p, i);
+
+ free(p->argv);
+ free(p);
+}
- /* LINTED */
- for (j = 0; j < (int)p->argv[i].sz; j++)
- if (p->argv[i].value[j])
- free(p->argv[i].value[j]);
- free(p->argv[i].value);
+void
+mdoc_argn_free(struct mdoc_arg *p, int iarg)
+{
+ struct mdoc_argv *arg = &p->argv[iarg];
+ int j;
+
+ if (arg->sz && arg->value) {
+ for (j = (int)arg->sz - 1; j >= 0; j--)
+ free(arg->value[j]);
+ free(arg->value);
}
- free(p->argv);
- free(p);
+ for (--p->argc; iarg < (int)p->argc; iarg++)
+ p->argv[iarg] = p->argv[iarg+1];
}
-int
+enum margserr
mdoc_zargs(struct mdoc *m, int line, int *pos,
char *buf, int flags, char **v)
{
}
-int
+enum margserr
mdoc_args(struct mdoc *m, int line, int *pos,
char *buf, enum mdoct tok, char **v)
{
int fl, c, i;
struct mdoc_node *n;
- assert(tok && tok < MDOC_MAX);
fl = mdoc_argflags[tok];
if (MDOC_It != tok)
}
-static int
+static enum margserr
args(struct mdoc *m, int line, int *pos,
char *buf, int fl, char **v)
{
int i;
char *p, *pp;
+ enum margserr rc;
/*
* Parse out the terms (like `val' in `.Xx -arg val' or simply
assert(*pos);
assert(' ' != buf[*pos]);
- if (0 == buf[*pos])
+ if ('\0' == buf[*pos])
return(ARGS_EOLN);
/*
break;
}
+ /* By default, assume a phrase. */
+ rc = ARGS_PHRASE;
+
/*
* Adjust new-buffer position to be beyond delimiter
* mark (e.g., Ta -> end + 2).
*/
if (p && pp) {
*pos += pp < p ? 2 : 1;
+ rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE;
p = pp < p ? pp : p;
} else if (p && ! pp) {
+ rc = ARGS_PPHRASE;
*pos += 1;
} else if (pp && ! p) {
p = pp;
for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++)
/* Skip ahead. */ ;
- return(ARGS_PHRASE);
+ return(rc);
}
/*
argv_multi(struct mdoc *m, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
- int c;
+ enum margserr ac;
char *p;
for (v->sz = 0; ; v->sz++) {
if ('-' == buf[*pos])
break;
- c = args(m, line, pos, buf, 0, &p);
- if (ARGS_ERROR == c)
+ ac = args(m, line, pos, buf, 0, &p);
+ if (ARGS_ERROR == ac)
return(0);
- else if (ARGS_EOLN == c)
+ else if (ARGS_EOLN == ac)
break;
if (0 == v->sz % MULTI_STEP)
argv_opt_single(struct mdoc *m, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
- int c;
+ enum margserr ac;
char *p;
if ('-' == buf[*pos])
return(1);
- c = args(m, line, pos, buf, 0, &p);
- if (ARGS_ERROR == c)
+ ac = args(m, line, pos, buf, 0, &p);
+ if (ARGS_ERROR == ac)
return(0);
- if (ARGS_EOLN == c)
+ if (ARGS_EOLN == ac)
return(1);
v->sz = 1;
argv_single(struct mdoc *m, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
- int c, ppos;
+ int ppos;
+ enum margserr ac;
char *p;
ppos = *pos;
- c = args(m, line, pos, buf, 0, &p);
- if (ARGS_ERROR == c)
+ ac = args(m, line, pos, buf, 0, &p);
+ if (ARGS_ERROR == ac)
return(0);
- if (ARGS_EOLN == c)
+ if (ARGS_EOLN == ac)
return(mdoc_perr(m, line, ppos, EARGVAL));
v->sz = 1;