-/* $Id: argv.c,v 1.51 2009/03/14 05:21:58 kristaps Exp $ */
+/* $Id: argv.c,v 1.52 2009/03/16 22:19:19 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
#define ARGV_MULTI (1 << 2)
#define ARGV_OPT_SINGLE (1 << 3)
+#define MULTI_STEP 5
+
enum mwarn {
WQUOTPARM,
WARGVPARM,
0, /* Bro */
ARGS_DELIM, /* Brc */
ARGS_QUOTED, /* %C */
+ 0, /* Es */
+ 0, /* En */
};
if (0 == buf[*pos])
return(ARGV_EOLN);
- assert( ! isspace((u_char)buf[*pos]));
+ assert(' ' != buf[*pos]);
- if ('-' != buf[*pos])
+ if ('-' != buf[*pos] || ARGS_ARGVLIKE & mdoc_argflags[tok])
return(ARGV_WORD);
+ /* Parse through to the first unescaped space. */
+
i = *pos;
p = &buf[++(*pos)];
/* LINTED */
while (buf[*pos]) {
- if (isspace((u_char)buf[*pos]))
+ if (' ' == buf[*pos])
if ('\\' != buf[*pos - 1])
break;
(*pos)++;
}
- /*
- * XXX: save the nullified byte as we'll restore it if this
- * doesn't end up being a command after all. This is a little
- * bit hacky. I don't like it, but it works for now.
- */
+ /* XXX - save zeroed byte, if not an argument. */
sv = 0;
if (buf[*pos]) {
tmp.line = line;
tmp.pos = *pos;
- /*
- * We now parse out the per-macro arguments. XXX - this can be
- * made much cleaner using per-argument tables. See argv_a2arg
- * for details.
- */
+ /* See if our token accepts the argument. */
if (MDOC_ARG_MAX == (tmp.arg = argv_a2arg(tok, p))) {
- /* XXX - restore saved byte. */
+ /* XXX - restore saved zeroed byte. */
if (sv)
buf[*pos - 1] = sv;
if ( ! pwarn(mdoc, line, i, WARGVPARM))
return(ARGV_WORD);
}
- while (buf[*pos] && isspace((u_char)buf[*pos]))
+ while (buf[*pos] && ' ' == buf[*pos])
(*pos)++;
- /* FIXME: whitespace if no value. */
-
if ( ! argv(mdoc, line, &tmp, pos, buf))
return(ARGV_ERROR);
break;
}
- /* Continue parsing the arguments themselves... */
-
return(args(mdoc, line, pos, buf, fl, v));
}
break;
i++;
/* There must be at least one space... */
- if (0 == buf[i] || ! isspace((u_char)buf[i]))
+ if (0 == buf[i] || ' ' != buf[i])
break;
i++;
- while (buf[i] && isspace((u_char)buf[i]))
+ while (buf[i] && ' ' == buf[i])
i++;
}
if (0 == buf[i]) {
/*
* Thar be dragons here! If we're tab-separated, search
- * ahead for either a tab or the `Ta' macro. If a tab
- * is detected, it mustn't be escaped; if a `Ta' is
- * detected, it must be space-buffered before and after.
- * If either of these hold true, then prune out the
+ * ahead for either a tab or the `Ta' macro.
+ * If a `Ta' is detected, it must be space-buffered before and
+ * after. If either of these hold true, then prune out the
* extra spaces and call it an argument.
*/
if (ARGS_TABSEP & fl) {
/* Scan ahead to unescaped tab. */
- for (p = *v; ; p++) {
- if (NULL == (p = strchr(p, '\t')))
- break;
- if (p == *v)
- break;
- if ('\\' != *(p - 1))
- break;
- }
+ p = strchr(*v, '\t');
/* Scan ahead to unescaped `Ta'. */
if ( ! (ARGS_TABSEP & fl))
while (buf[*pos]) {
- if (isspace((u_char)buf[*pos]))
+ if (' ' == buf[*pos])
if ('\\' != buf[*pos - 1])
break;
(*pos)++;
return(ARGS_WORD);
if ( ! (ARGS_TABSEP & fl))
- while (buf[*pos] && isspace((u_char)buf[*pos]))
+ while (buf[*pos] && ' ' == buf[*pos])
(*pos)++;
if (buf[*pos])
if (0 == buf[*pos])
return(ARGS_QWORD);
- while (buf[*pos] && isspace((u_char)buf[*pos]))
+ while (buf[*pos] && ' ' == buf[*pos])
(*pos)++;
if (buf[*pos])
else if (ARGS_EOLN == c)
break;
- if (0 == v->sz % 5)
+ if (0 == v->sz % MULTI_STEP)
v->value = xrealloc(v->value,
- (v->sz + 5) * sizeof(char *));
+ (v->sz + MULTI_STEP) * sizeof(char *));
v->value[(int)v->sz] = xstrdup(p);
}