-/* $Id: macro.c,v 1.37 2009/01/15 17:38:57 kristaps Exp $ */
+/* $Id: macro.c,v 1.40 2009/01/17 16:15:27 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
static int rewind_elem(struct mdoc *, int);
-static int rewind_impblock(struct mdoc *, int);
-static int rewind_expblock(struct mdoc *, int);
+static int rewind_impblock(struct mdoc *, int, int, int);
+static int rewind_expblock(struct mdoc *, int, int, int);
static int rewind_subblock(enum mdoc_type, struct mdoc *, int);
static int rewind_last(int, int,
struct mdoc *, struct mdoc_node *);
if (MDOC_MAX == res)
return(res);
- if ( ! mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX_MACLIKE))
+ if ( ! mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX, "macro-like parameter"))
return(-1);
return(MDOC_MAX);
}
static int
-rewind_expblock(struct mdoc *mdoc, int tok)
+rewind_expblock(struct mdoc *mdoc, int tok, int line, int ppos)
{
struct mdoc_node *n;
int c;
c = rewind_dohalt(tok, MDOC_BLOCK, mdoc->last);
if (REWIND_HALT == c)
- return(mdoc_err(mdoc, ERR_SCOPE_NOCTX));
+ return(mdoc_perr(mdoc, line, ppos, "closing macro has no context"));
if (REWIND_REWIND == c)
return(rewind_last(tok, MDOC_BLOCK, mdoc, mdoc->last));
for (n = mdoc->last->parent; n; n = n->parent) {
c = rewind_dohalt(tok, MDOC_BLOCK, n);
if (REWIND_HALT == c)
- return(mdoc_err(mdoc, ERR_SCOPE_NOCTX));
+ return(mdoc_perr(mdoc, line, ppos, "closing macro has no context"));
if (REWIND_REWIND == c)
break;
else if (rewind_dobreak(tok, MDOC_BLOCK, n))
continue;
- return(mdoc_nerr(mdoc, n, "macro scope broken"));
+ return(mdoc_nerr(mdoc, n, "block scope broken"));
}
assert(n);
static int
-rewind_impblock(struct mdoc *mdoc, int tok)
+rewind_impblock(struct mdoc *mdoc, int tok, int line, int ppos)
{
struct mdoc_node *n;
int c;
- printf("1\n");
c = rewind_dohalt(tok, MDOC_BLOCK, mdoc->last);
if (REWIND_HALT == c)
return(1);
break;
else if (rewind_dobreak(tok, MDOC_BLOCK, n))
continue;
- return(mdoc_nerr(mdoc, n, "macro scope broken"));
+ return(mdoc_nerr(mdoc, n, "block scope broken"));
}
assert(n);
if (0 == buf[*pos]) {
if ( ! rewind_subblock(MDOC_BODY, mdoc, tok))
return(0);
- return(rewind_expblock(mdoc, tok));
+ return(rewind_expblock(mdoc, tok, line, ppos));
}
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0));
+ return(mdoc_perr(mdoc, line, ppos, "macro expects no parameters"));
}
if ( ! rewind_subblock(MDOC_BODY, mdoc, tok))
lastarg = *pos;
if (j == maxargs && ! flushed) {
- if ( ! rewind_expblock(mdoc, tok))
+ if ( ! rewind_expblock(mdoc, tok, line, ppos))
return(0);
flushed = 1;
}
return(0);
else if (MDOC_MAX != c) {
if ( ! flushed) {
- if ( ! rewind_expblock(mdoc, tok))
+ if ( ! rewind_expblock(mdoc, tok, line, ppos))
return(0);
flushed = 1;
}
}
if (MDOC_LINEARG_MAX == j)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
- if ( ! flushed && ! rewind_expblock(mdoc, tok))
+ if ( ! flushed && ! rewind_expblock(mdoc, tok, line, ppos))
return(0);
if (ppos > 1)
la = *pos;
c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
- if (ARGV_EOLN == c || ARGV_WORD == c)
+ if (ARGV_EOLN == c)
break;
- else if (ARGV_ARG == c)
+ if (ARGV_WORD == c) {
+ *pos = la;
+ break;
+ } else if (ARGV_ARG == c)
continue;
+
mdoc_argv_free(argc, argv);
return(0);
}
if (MDOC_LINEARG_MAX == argc) {
mdoc_argv_free(argc, argv);
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
}
- c = mdoc_elem_alloc(mdoc, line, la, tok, argc, argv);
+ c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv);
if (0 == c) {
mdoc_argv_free(argc, argv);
lastpunct = 1;
} else if (lastpunct) {
c = mdoc_elem_alloc(mdoc, line,
- la, tok, argc, argv);
+ ppos, tok, argc, argv);
if (0 == c) {
mdoc_argv_free(argc, argv);
return(0);
mdoc_argv_free(argc, argv);
if (sz == MDOC_LINEARG_MAX)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
if (0 == lastpunct && ! rewind_elem(mdoc, tok))
return(0);
if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
if ( ! rewind_subblock(MDOC_BODY, mdoc, tok))
return(0);
- if ( ! rewind_impblock(mdoc, tok))
+ if ( ! rewind_impblock(mdoc, tok, line, ppos))
return(0);
}
for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
lastarg = *pos;
c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
- if (ARGV_EOLN == c || ARGV_WORD == c)
+ if (ARGV_EOLN == c)
break;
- else if (ARGV_ARG == c)
+ if (ARGV_WORD == c) {
+ *pos = lastarg;
+ break;
+ } else if (ARGV_ARG == c)
continue;
mdoc_argv_free(argc, argv);
return(0);
if (MDOC_LINEARG_MAX == argc) {
mdoc_argv_free(argc, argv);
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
}
c = mdoc_block_alloc(mdoc, line, ppos,
}
if (j == MDOC_LINEARG_MAX)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
if ( ! rewind_subblock(MDOC_HEAD, mdoc, tok))
return(0);
}
if (j == MDOC_LINEARG_MAX)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
if (1 == ppos) {
if ( ! rewind_subblock(MDOC_HEAD, mdoc, tok))
return(0);
} else if ( ! rewind_subblock(MDOC_HEAD, mdoc, tok))
return(0);
- return(rewind_impblock(mdoc, tok));
+ return(rewind_impblock(mdoc, tok, line, ppos));
}
}
if (MDOC_LINEARG_MAX == j)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
if ( ! flushed) {
if ( ! rewind_subblock(MDOC_HEAD, mdoc, tok))
/* FALLTHROUGH */
case (MDOC_Ns):
/* FALLTHROUGH */
+ case (MDOC_Pf):
+ /* FALLTHROUGH */
case (MDOC_Ux):
/* FALLTHROUGH */
case (MDOC_St):
for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
lastarg = *pos;
c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
- if (ARGV_EOLN == c || ARGV_WORD == c)
+ if (ARGV_EOLN == c)
break;
- else if (ARGV_ARG == c)
+ if (ARGV_WORD == c) {
+ *pos = lastarg;
+ break;
+ } else if (ARGV_ARG == c)
continue;
mdoc_argv_free(argc, argv);
return(0);
}
- c = mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv);
+ c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv);
mdoc_argv_free(argc, argv);
if (0 == c)
}
if (MDOC_LINEARG_MAX == j)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
if ( ! flushed && rewind_elem(mdoc, tok))
return(0);
struct mdoc_arg argv[MDOC_LINEARG_MAX];
char *p;
- /* FIXME: parsing macros! */
-
fl = 0;
if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
fl = ARGS_QUOTED;
c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
if (ARGV_EOLN == c)
break;
- else if (ARGV_ARG == c)
- continue;
- else if (ARGV_WORD == c)
+ if (ARGV_WORD == c) {
+ *pos = lastarg;
break;
+ } else if (ARGV_ARG == c)
+ continue;
mdoc_argv_free(argc, argv);
return(0);
mdoc->next = MDOC_NEXT_CHILD;
if (MDOC_LINEARG_MAX == argc)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
lastarg = *pos;
if (ARGS_EOLN == c)
break;
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX != c) {
+ if ( ! rewind_elem(mdoc, tok))
+ return(0);
+ return(mdoc_macro(mdoc, c, line,
+ lastarg, pos, buf));
+ }
+
if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
return(0);
mdoc->next = MDOC_NEXT_SIBLING;
}
if (MDOC_LINEARG_MAX == sz + argc)
- return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
+ return(mdoc_perr(mdoc, line, ppos, "too many arguments"));
return(rewind_elem(mdoc, tok));
}
macro_obsolete(MACRO_PROT_ARGS)
{
- return(mdoc_pwarn(mdoc, line, ppos, WARN_IGN_OBSOLETE));
+ return(mdoc_pwarn(mdoc, line, ppos, WARN_SYNTAX, "macro is obsolete"));
}