-/* $Id: argv.c,v 1.26 2009/01/22 14:56:21 kristaps Exp $ */
+/* $Id: argv.c,v 1.34 2009/02/28 12:16:02 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
#include "private.h"
/*
- * Parse arguments and parameters of macros. Arguments follow the
- * syntax of `-arg [val [valN...]]', while parameters are free-form text
- * following arguments (if any). This file must correctly handle the
- * strange punctuation rules dictated by groff.
+ * Routines to parse arguments of macros. Arguments follow the syntax
+ * of `-arg [val [valN...]]'. Arguments come in all types: quoted
+ * arguments, multiple arguments per value, no-value arguments, etc.
*/
#define ARGS_QUOTED (1 << 0)
#define ARGS_DELIM (1 << 1)
#define ARGS_TABSEP (1 << 2)
-static int lookup(int, const char *);
+static int argv_a2arg(int, const char *);
static int args(struct mdoc *, int, int *,
char *, int, char **);
static int argv(struct mdoc *, int,
struct mdoc_arg *, int *, char *);
static int argv_multi(struct mdoc *, int,
struct mdoc_arg *, int *, char *);
-static int postargv(struct mdoc *, int,
- const struct mdoc_arg *, int);
static int pwarn(struct mdoc *, int, int, int);
static int perr(struct mdoc *, int, int, int);
/* Error messages. */
#define EQUOTTERM (0)
-#define EOFFSET (1)
-#define EARGVAL (2)
-#define EARGMANY (3)
+#define EARGVAL (1)
+#define EARGMANY (2)
static int mdoc_argflags[MDOC_MAX] = {
0, /* \" */
0, /* Ed */
0, /* Bl */
0, /* El */
- ARGS_DELIM, /* It */
+ 0, /* It */
ARGS_DELIM, /* Ad */
ARGS_DELIM, /* An */
ARGS_DELIM, /* Ar */
c = mdoc_perr(mdoc, line, pos,
"unterminated quoted parameter");
break;
- case (EOFFSET):
- c = mdoc_perr(mdoc, line, pos,
- "invalid value for offset argument");
- break;
case (EARGVAL):
c = mdoc_perr(mdoc, line, pos,
"argument requires a value");
args(struct mdoc *mdoc, int line,
int *pos, char *buf, int fl, char **v)
{
- int i, c;
+ int i;
char *p, *pp;
assert(*pos > 0);
*/
if ((fl & ARGS_DELIM) && mdoc_iscdelim(buf[*pos])) {
- for (i = *pos; (c = buf[i]); ) {
- if ( ! mdoc_iscdelim(c))
+ for (i = *pos; buf[i]; ) {
+ if ( ! mdoc_iscdelim(buf[i]))
break;
i++;
- if (0 == buf[i] || ! isspace(c))
+ /* There must be at least one space... */
+ if (0 == buf[i] || ! isspace((int)buf[i]))
break;
i++;
- while (buf[i] && isspace(c))
+ while (buf[i] && isspace((int)buf[i]))
i++;
}
if (0 == buf[i]) {
p++;
if (0 != *p)
*(p - 1) = 0;
- *pos += p - *v;
+ *pos += (int)(p - *v);
}
if (p && 0 == *p)
if (p > *v && ' ' == *(p - 1))
if ( ! pwarn(mdoc, line, *pos, WTAILWS))
return(0);
- *pos += p - *v;
+ *pos += (int)(p - *v);
return(ARGS_WORD);
}
/* Do non-tabsep look-ahead here. */
if ( ! (ARGS_TABSEP & fl))
- while ((c = buf[*pos])) {
- if (isspace(c))
+ while (buf[*pos]) {
+ if (isspace((int)buf[*pos]))
if ('\\' != buf[*pos - 1])
break;
(*pos)++;
static int
-lookup(int tok, const char *argv)
+argv_a2arg(int tok, const char *argv)
{
switch (tok) {
}
-static int
-postargv(struct mdoc *mdoc, int line, 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(perr(mdoc, line, pos, EOFFSET));
- default:
- break;
- }
-
- return(1);
-}
-
-
static int
argv_multi(struct mdoc *mdoc, int line,
struct mdoc_arg *v, int *pos, char *buf)
return(0);
} else if (ARGS_EOLN == c)
break;
- v->value[v->sz] = p;
+ v->value[(int)v->sz] = p;
}
if (0 < v->sz && v->sz < MDOC_LINEARG_MAX)
mdoc_argv(struct mdoc *mdoc, int line, int tok,
struct mdoc_arg *v, int *pos, char *buf)
{
- int i, ppos;
+ int i;
char *p;
(void)memset(v, 0, sizeof(struct mdoc_arg));
if (buf[*pos])
buf[(*pos)++] = 0;
- if (MDOC_ARG_MAX == (v->arg = lookup(tok, p))) {
+ if (MDOC_ARG_MAX == (v->arg = argv_a2arg(tok, p))) {
if ( ! pwarn(mdoc, line, i, WARGVPARM))
return(ARGV_ERROR);
return(ARGV_WORD);
/* FIXME: whitespace if no value. */
- ppos = *pos;
if ( ! argv(mdoc, line, v, pos, buf))
return(ARGV_ERROR);
- if ( ! postargv(mdoc, line, v, ppos))
- return(ARGV_ERROR);
return(ARGV_ARG);
}