-/* $Id: mdoc_argv.c,v 1.78 2011/06/18 16:18:04 kristaps Exp $ */
+/* $Id: mdoc_argv.c,v 1.83 2012/04/15 15:26:49 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <sys/types.h>
#include <assert.h>
-#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
enum argvflag {
ARGV_NONE, /* no args to flag (e.g., -split) */
ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */
- ARGV_MULTI, /* multiple args (e.g., -column xxx yyy) */
- ARGV_OPT_SINGLE /* optional arg (e.g., -offset [xxx]) */
+ ARGV_MULTI /* multiple args (e.g., -column xxx yyy) */
};
struct mdocarg {
const enum mdocargt *argvs;
};
+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(struct mdoc *, int,
+static int argv_multi(struct mdoc *, int,
struct mdoc_argv *, int *, char *);
static int argv_single(struct mdoc *, int,
struct mdoc_argv *, int *, char *);
-static int argv_opt_single(struct mdoc *, int,
- struct mdoc_argv *, int *, char *);
-static int argv_multi(struct mdoc *, int,
- struct mdoc_argv *, int *, char *);
-static void argn_free(struct mdoc_arg *, int);
static const enum argvflag argvflags[MDOC_ARG_MAX] = {
ARGV_NONE, /* MDOC_Split */
ARGV_NONE, /* MDOC_Unfilled */
ARGV_NONE, /* MDOC_Literal */
ARGV_SINGLE, /* MDOC_File */
- ARGV_OPT_SINGLE, /* MDOC_Offset */
+ ARGV_SINGLE, /* MDOC_Offset */
ARGV_NONE, /* MDOC_Bullet */
ARGV_NONE, /* MDOC_Dash */
ARGV_NONE, /* MDOC_Hyphen */
return(ARGV_EOLN);
else if (NULL == (ap = mdocargs[tok].argvs))
return(ARGV_WORD);
-
- assert(' ' != buf[*pos]);
+ else if ('-' != buf[*pos])
+ return(ARGV_WORD);
/* Seek to the first unescaped space. */
while (buf[*pos] && ' ' == buf[*pos])
(*pos)++;
- if ( ! argv(m, line, &tmp, pos, buf))
- return(ARGV_ERROR);
+ switch (argvflags[tmp.arg]) {
+ case (ARGV_SINGLE):
+ if ( ! argv_single(m, line, &tmp, pos, buf))
+ return(ARGV_ERROR);
+ break;
+ case (ARGV_MULTI):
+ if ( ! argv_multi(m, line, &tmp, pos, buf))
+ return(ARGV_ERROR);
+ break;
+ case (ARGV_NONE):
+ break;
+ }
if (NULL == (arg = *v))
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
}
static int
-argv_opt_single(struct mdoc *m, int line,
+argv_single(struct mdoc *m, int line,
struct mdoc_argv *v, int *pos, char *buf)
{
enum margserr ac;
char *p;
- if ('-' == buf[*pos])
- return(1);
-
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
if (ARGS_ERROR == ac)
return(0);
return(1);
}
-
-/*
- * Parse a single, mandatory value from the stream.
- */
-static int
-argv_single(struct mdoc *m, int line,
- struct mdoc_argv *v, int *pos, char *buf)
-{
- int ppos;
- enum margserr ac;
- char *p;
-
- ppos = *pos;
-
- ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
- if (ARGS_EOLN == ac) {
- mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT);
- return(0);
- } else if (ARGS_ERROR == ac)
- return(0);
-
- v->sz = 1;
- v->value = mandoc_malloc(sizeof(char *));
- v->value[0] = mandoc_strdup(p);
-
- return(1);
-}
-
-/*
- * Determine rules for parsing arguments. Arguments can either accept
- * no parameters, an optional single parameter, one parameter, or
- * multiple parameters.
- */
-static int
-argv(struct mdoc *mdoc, int line,
- struct mdoc_argv *v, int *pos, char *buf)
-{
-
- v->sz = 0;
- v->value = NULL;
-
- switch (argvflags[v->arg]) {
- case (ARGV_SINGLE):
- return(argv_single(mdoc, line, v, pos, buf));
- case (ARGV_MULTI):
- return(argv_multi(mdoc, line, v, pos, buf));
- case (ARGV_OPT_SINGLE):
- return(argv_opt_single(mdoc, line, v, pos, buf));
- case (ARGV_NONE):
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- return(1);
-}