summaryrefslogtreecommitdiffstats
path: root/contrib/mdocml/mdoc_argv.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/mdocml/mdoc_argv.c')
-rw-r--r--contrib/mdocml/mdoc_argv.c200
1 files changed, 95 insertions, 105 deletions
diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mdocml/mdoc_argv.c
index e48516c..3e7fabd 100644
--- a/contrib/mdocml/mdoc_argv.c
+++ b/contrib/mdocml/mdoc_argv.c
@@ -1,7 +1,7 @@
-/* $Id: mdoc_argv.c,v 1.95 2014/07/06 19:09:00 schwarze Exp $ */
+/* $OpenBSD$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,9 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include <sys/types.h>
@@ -56,9 +54,9 @@ static void argn_free(struct mdoc_arg *, int);
static enum margserr args(struct mdoc *, int, int *,
char *, enum argsflag, char **);
static int args_checkpunct(const char *, int);
-static int argv_multi(struct mdoc *, int,
+static void argv_multi(struct mdoc *, int,
struct mdoc_argv *, int *, char *);
-static int argv_single(struct mdoc *, int,
+static void argv_single(struct mdoc *, int,
struct mdoc_argv *, int *, char *);
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
@@ -272,100 +270,105 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
/*
- * Parse an argument from line text. This comes in the form of -key
- * [value0...], which may either have a single mandatory value, at least
- * one mandatory value, an optional single value, or no value.
+ * Parse flags and their arguments from the input line.
+ * These come in the form -flag [argument ...].
+ * Some flags take no argument, some one, some multiple.
*/
-enum margverr
+void
mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
- struct mdoc_arg **v, int *pos, char *buf)
+ struct mdoc_arg **reta, int *pos, char *buf)
{
- char *p, sv;
- struct mdoc_argv tmp;
- struct mdoc_arg *arg;
- const enum mdocargt *ap;
+ struct mdoc_argv tmpv;
+ struct mdoc_argv **retv;
+ const enum mdocargt *argtable;
+ char *argname;
+ int ipos, retc;
+ char savechar;
- if ('\0' == buf[*pos])
- return(ARGV_EOLN);
- else if (NULL == (ap = mdocargs[tok].argvs))
- return(ARGV_WORD);
- else if ('-' != buf[*pos])
- return(ARGV_WORD);
+ *reta = NULL;
- /* Seek to the first unescaped space. */
+ /* Which flags does this macro support? */
- p = &buf[++(*pos)];
+ argtable = mdocargs[tok].argvs;
+ if (argtable == NULL)
+ return;
- assert(*pos > 0);
+ /* Loop over the flags on the input line. */
- for ( ; buf[*pos] ; (*pos)++)
- if (' ' == buf[*pos] && '\\' != buf[*pos - 1])
- break;
+ ipos = *pos;
+ while (buf[ipos] == '-') {
- /*
- * We want to nil-terminate the word to look it up (it's easier
- * that way). But we may not have a flag, in which case we need
- * to restore the line as-is. So keep around the stray byte,
- * which we'll reset upon exiting (if necessary).
- */
+ /* Seek to the first unescaped space. */
- if ('\0' != (sv = buf[*pos]))
- buf[(*pos)++] = '\0';
+ for (argname = buf + ++ipos; buf[ipos] != '\0'; ipos++)
+ if (buf[ipos] == ' ' && buf[ipos - 1] != '\\')
+ break;
- /*
- * Now look up the word as a flag. Use temporary storage that
- * we'll copy into the node's flags, if necessary.
- */
+ /*
+ * We want to nil-terminate the word to look it up.
+ * But we may not have a flag, in which case we need
+ * to restore the line as-is. So keep around the
+ * stray byte, which we'll reset upon exiting.
+ */
+
+ if ((savechar = buf[ipos]) != '\0')
+ buf[ipos++] = '\0';
- memset(&tmp, 0, sizeof(struct mdoc_argv));
+ /*
+ * Now look up the word as a flag. Use temporary
+ * storage that we'll copy into the node's flags.
+ */
+
+ while ((tmpv.arg = *argtable++) != MDOC_ARG_MAX)
+ if ( ! strcmp(argname, mdoc_argnames[tmpv.arg]))
+ break;
- tmp.line = line;
- tmp.pos = *pos;
- tmp.arg = MDOC_ARG_MAX;
+ /* If it isn't a flag, restore the saved byte. */
- while (MDOC_ARG_MAX != (tmp.arg = *ap++))
- if (0 == strcmp(p, mdoc_argnames[tmp.arg]))
+ if (tmpv.arg == MDOC_ARG_MAX) {
+ if (savechar != '\0')
+ buf[ipos - 1] = savechar;
break;
+ }
- if (MDOC_ARG_MAX == tmp.arg) {
- /*
- * The flag was not found.
- * Restore saved zeroed byte and return as a word.
- */
- if (sv)
- buf[*pos - 1] = sv;
- return(ARGV_WORD);
- }
+ /* Read to the next word (the first argument). */
- /* Read to the next word (the argument). */
-
- while (buf[*pos] && ' ' == buf[*pos])
- (*pos)++;
-
- switch (argvflags[tmp.arg]) {
- case ARGV_SINGLE:
- if ( ! argv_single(mdoc, line, &tmp, pos, buf))
- return(ARGV_ERROR);
- break;
- case ARGV_MULTI:
- if ( ! argv_multi(mdoc, line, &tmp, pos, buf))
- return(ARGV_ERROR);
- break;
- case ARGV_NONE:
- break;
- }
+ while (buf[ipos] == ' ')
+ ipos++;
- if (NULL == (arg = *v))
- arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
+ /* Parse the arguments of the flag. */
- arg->argc++;
- arg->argv = mandoc_reallocarray(arg->argv,
- arg->argc, sizeof(struct mdoc_argv));
+ tmpv.line = line;
+ tmpv.pos = ipos;
+ tmpv.sz = 0;
+ tmpv.value = NULL;
- memcpy(&arg->argv[(int)arg->argc - 1], &tmp,
- sizeof(struct mdoc_argv));
+ switch (argvflags[tmpv.arg]) {
+ case ARGV_SINGLE:
+ argv_single(mdoc, line, &tmpv, &ipos, buf);
+ break;
+ case ARGV_MULTI:
+ argv_multi(mdoc, line, &tmpv, &ipos, buf);
+ break;
+ case ARGV_NONE:
+ break;
+ }
+
+ /* Append to the return values. */
+
+ if (*reta == NULL)
+ *reta = mandoc_calloc(1, sizeof(**reta));
- return(ARGV_ARG);
+ retc = ++(*reta)->argc;
+ retv = &(*reta)->argv;
+ *retv = mandoc_reallocarray(*retv, retc, sizeof(**retv));
+ memcpy(*retv + retc - 1, &tmpv, sizeof(**retv));
+
+ /* Prepare for parsing the next flag. */
+
+ *pos = ipos;
+ argtable = mdocargs[tok].argvs;
+ }
}
void
@@ -409,22 +412,17 @@ argn_free(struct mdoc_arg *p, int iarg)
}
enum margserr
-mdoc_zargs(struct mdoc *mdoc, int line, int *pos, char *buf, char **v)
-{
-
- return(args(mdoc, line, pos, buf, ARGSFL_NONE, v));
-}
-
-enum margserr
mdoc_args(struct mdoc *mdoc, int line, int *pos,
char *buf, enum mdoct tok, char **v)
{
- enum argsflag fl;
struct mdoc_node *n;
+ char *v_local;
+ enum argsflag fl;
- fl = mdocargs[tok].flags;
-
- if (MDOC_It != tok)
+ if (v == NULL)
+ v = &v_local;
+ fl = tok == MDOC_MAX ? ARGSFL_NONE : mdocargs[tok].flags;
+ if (tok != MDOC_It)
return(args(mdoc, line, pos, buf, fl, v));
/*
@@ -654,7 +652,7 @@ args_checkpunct(const char *buf, int i)
return('\0' == buf[i]);
}
-static int
+static void
argv_multi(struct mdoc *mdoc, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
@@ -662,25 +660,21 @@ argv_multi(struct mdoc *mdoc, int line,
char *p;
for (v->sz = 0; ; v->sz++) {
- if ('-' == buf[*pos])
+ if (buf[*pos] == '-')
break;
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
- if (ARGS_ERROR == ac)
- return(0);
- else if (ARGS_EOLN == ac)
+ if (ac == ARGS_EOLN)
break;
- if (0 == v->sz % MULTI_STEP)
+ if (v->sz % MULTI_STEP == 0)
v->value = mandoc_reallocarray(v->value,
v->sz + MULTI_STEP, sizeof(char *));
v->value[(int)v->sz] = mandoc_strdup(p);
}
-
- return(1);
}
-static int
+static void
argv_single(struct mdoc *mdoc, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
@@ -688,14 +682,10 @@ argv_single(struct mdoc *mdoc, int line,
char *p;
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
- if (ARGS_ERROR == ac)
- return(0);
- if (ARGS_EOLN == ac)
- return(1);
+ if (ac == ARGS_EOLN)
+ return;
v->sz = 1;
v->value = mandoc_malloc(sizeof(char *));
v->value[0] = mandoc_strdup(p);
-
- return(1);
}
OpenPOWER on IntegriCloud