version 1.107, 2015/10/17 00:21:07 |
version 1.120, 2019/07/11 17:06:17 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
#include "roff.h" |
#include "roff.h" |
#include "mdoc.h" |
#include "mdoc.h" |
#include "libmandoc.h" |
#include "libmandoc.h" |
|
#include "roff_int.h" |
#include "libmdoc.h" |
#include "libmdoc.h" |
|
|
#define MULTI_STEP 5 /* pre-allocate argument values */ |
#define MULTI_STEP 5 /* pre-allocate argument values */ |
Line 143 static const enum mdocargt args_Bl[] = { |
|
Line 144 static const enum mdocargt args_Bl[] = { |
|
MDOC_ARG_MAX |
MDOC_ARG_MAX |
}; |
}; |
|
|
static const struct mdocarg mdocargs[MDOC_MAX] = { |
static const struct mdocarg mdocargs[MDOC_MAX - MDOC_Dd] = { |
{ ARGSFL_DELIM, NULL }, /* Ap */ |
|
{ ARGSFL_NONE, NULL }, /* Dd */ |
{ ARGSFL_NONE, NULL }, /* Dd */ |
{ ARGSFL_NONE, NULL }, /* Dt */ |
{ ARGSFL_NONE, NULL }, /* Dt */ |
{ ARGSFL_NONE, NULL }, /* Os */ |
{ ARGSFL_NONE, NULL }, /* Os */ |
Line 160 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
Line 160 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
{ ARGSFL_NONE, NULL }, /* It */ |
{ ARGSFL_NONE, NULL }, /* It */ |
{ ARGSFL_DELIM, NULL }, /* Ad */ |
{ ARGSFL_DELIM, NULL }, /* Ad */ |
{ ARGSFL_DELIM, args_An }, /* An */ |
{ ARGSFL_DELIM, args_An }, /* An */ |
|
{ ARGSFL_DELIM, NULL }, /* Ap */ |
{ ARGSFL_DELIM, NULL }, /* Ar */ |
{ ARGSFL_DELIM, NULL }, /* Ar */ |
{ ARGSFL_DELIM, NULL }, /* Cd */ |
{ ARGSFL_DELIM, NULL }, /* Cd */ |
{ ARGSFL_DELIM, NULL }, /* Cm */ |
{ ARGSFL_DELIM, NULL }, /* Cm */ |
Line 262 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
Line 263 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
{ ARGSFL_DELIM, NULL }, /* En */ |
{ ARGSFL_DELIM, NULL }, /* En */ |
{ ARGSFL_DELIM, NULL }, /* Dx */ |
{ ARGSFL_DELIM, NULL }, /* Dx */ |
{ ARGSFL_NONE, NULL }, /* %Q */ |
{ ARGSFL_NONE, NULL }, /* %Q */ |
{ ARGSFL_NONE, NULL }, /* br */ |
|
{ ARGSFL_NONE, NULL }, /* sp */ |
|
{ ARGSFL_NONE, NULL }, /* %U */ |
{ ARGSFL_NONE, NULL }, /* %U */ |
{ ARGSFL_NONE, NULL }, /* Ta */ |
{ ARGSFL_NONE, NULL }, /* Ta */ |
{ ARGSFL_NONE, NULL }, /* ll */ |
|
}; |
}; |
|
|
|
|
Line 276 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
Line 274 static const struct mdocarg mdocargs[MDOC_MAX] = { |
|
* Some flags take no argument, some one, some multiple. |
* Some flags take no argument, some one, some multiple. |
*/ |
*/ |
void |
void |
mdoc_argv(struct roff_man *mdoc, int line, int tok, |
mdoc_argv(struct roff_man *mdoc, int line, enum roff_tok tok, |
struct mdoc_arg **reta, int *pos, char *buf) |
struct mdoc_arg **reta, int *pos, char *buf) |
{ |
{ |
struct mdoc_argv tmpv; |
struct mdoc_argv tmpv; |
Line 290 mdoc_argv(struct roff_man *mdoc, int line, int tok, |
|
Line 288 mdoc_argv(struct roff_man *mdoc, int line, int tok, |
|
|
|
/* Which flags does this macro support? */ |
/* Which flags does this macro support? */ |
|
|
argtable = mdocargs[tok].argvs; |
assert(tok >= MDOC_Dd && tok < MDOC_MAX); |
|
argtable = mdocargs[tok - MDOC_Dd].argvs; |
if (argtable == NULL) |
if (argtable == NULL) |
return; |
return; |
|
|
Line 368 mdoc_argv(struct roff_man *mdoc, int line, int tok, |
|
Line 367 mdoc_argv(struct roff_man *mdoc, int line, int tok, |
|
/* Prepare for parsing the next flag. */ |
/* Prepare for parsing the next flag. */ |
|
|
*pos = ipos; |
*pos = ipos; |
argtable = mdocargs[tok].argvs; |
argtable = mdocargs[tok - MDOC_Dd].argvs; |
} |
} |
} |
} |
|
|
Line 414 argn_free(struct mdoc_arg *p, int iarg) |
|
Line 413 argn_free(struct mdoc_arg *p, int iarg) |
|
|
|
enum margserr |
enum margserr |
mdoc_args(struct roff_man *mdoc, int line, int *pos, |
mdoc_args(struct roff_man *mdoc, int line, int *pos, |
char *buf, int tok, char **v) |
char *buf, enum roff_tok tok, char **v) |
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
char *v_local; |
|
enum argsflag fl; |
enum argsflag fl; |
|
|
if (v == NULL) |
fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok - MDOC_Dd].flags; |
v = &v_local; |
|
fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok].flags; |
|
if (tok != MDOC_It) |
|
return args(mdoc, line, pos, buf, fl, v); |
|
|
|
/* |
/* |
* We know that we're in an `It', so it's reasonable to expect |
* We know that we're in an `It', so it's reasonable to expect |
Line 433 mdoc_args(struct roff_man *mdoc, int line, int *pos, |
|
Line 427 mdoc_args(struct roff_man *mdoc, int line, int *pos, |
|
* safe fall-back into the default behaviour. |
* safe fall-back into the default behaviour. |
*/ |
*/ |
|
|
for (n = mdoc->last; n; n = n->parent) |
if (tok == MDOC_It) { |
if (MDOC_Bl == n->tok) |
for (n = mdoc->last; n != NULL; n = n->parent) { |
if (LIST_column == n->norm->Bl.type) { |
if (n->tok != MDOC_Bl) |
|
continue; |
|
if (n->norm->Bl.type == LIST_column) |
fl = ARGSFL_TABSEP; |
fl = ARGSFL_TABSEP; |
break; |
break; |
} |
} |
|
} |
|
|
return args(mdoc, line, pos, buf, fl, v); |
return args(mdoc, line, pos, buf, fl, v); |
} |
} |
Line 448 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 445 args(struct roff_man *mdoc, int line, int *pos, |
|
char *buf, enum argsflag fl, char **v) |
char *buf, enum argsflag fl, char **v) |
{ |
{ |
char *p; |
char *p; |
|
char *v_local; |
int pairs; |
int pairs; |
|
|
if (buf[*pos] == '\0') { |
if (buf[*pos] == '\0') { |
if (mdoc->flags & MDOC_PHRASELIT && |
if (mdoc->flags & MDOC_PHRASELIT && |
! (mdoc->flags & MDOC_PHRASE)) { |
! (mdoc->flags & MDOC_PHRASE)) { |
mandoc_msg(MANDOCERR_ARG_QUOTE, |
mandoc_msg(MANDOCERR_ARG_QUOTE, line, *pos, NULL); |
mdoc->parse, line, *pos, NULL); |
|
mdoc->flags &= ~MDOC_PHRASELIT; |
mdoc->flags &= ~MDOC_PHRASELIT; |
} |
} |
|
mdoc->flags &= ~MDOC_PHRASEQL; |
return ARGS_EOLN; |
return ARGS_EOLN; |
} |
} |
|
|
|
if (v == NULL) |
|
v = &v_local; |
*v = buf + *pos; |
*v = buf + *pos; |
|
|
if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos)) |
if (fl == ARGSFL_DELIM && args_checkpunct(buf, *pos)) |
Line 479 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 479 args(struct roff_man *mdoc, int line, int *pos, |
|
* unless there is a blank in between. |
* unless there is a blank in between. |
*/ |
*/ |
|
|
if (p[-1] != ' ') |
if (p > buf && p[-1] != ' ') |
mdoc->flags |= MDOC_PHRASEQL; |
mdoc->flags |= MDOC_PHRASEQL; |
if (p[1] != ' ') |
if (p[1] != ' ') |
mdoc->flags |= MDOC_PHRASEQN; |
mdoc->flags |= MDOC_PHRASEQN; |
Line 505 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 505 args(struct roff_man *mdoc, int line, int *pos, |
|
p = strchr(*v, '\0'); |
p = strchr(*v, '\0'); |
if (p[-1] == ' ') |
if (p[-1] == ' ') |
mandoc_msg(MANDOCERR_SPACE_EOL, |
mandoc_msg(MANDOCERR_SPACE_EOL, |
mdoc->parse, line, *pos, NULL); |
line, *pos, NULL); |
*pos += (int)(p - *v); |
*pos += (int)(p - *v); |
} |
} |
|
|
Line 526 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 526 args(struct roff_man *mdoc, int line, int *pos, |
|
* Whitespace is NOT involved in literal termination. |
* Whitespace is NOT involved in literal termination. |
*/ |
*/ |
|
|
if (mdoc->flags & MDOC_PHRASELIT || buf[*pos] == '\"') { |
if (mdoc->flags & MDOC_PHRASELIT || |
if ( ! (mdoc->flags & MDOC_PHRASELIT)) |
(mdoc->flags & MDOC_PHRASE && buf[*pos] == '\"')) { |
|
if ((mdoc->flags & MDOC_PHRASELIT) == 0) { |
*v = &buf[++(*pos)]; |
*v = &buf[++(*pos)]; |
|
|
if (mdoc->flags & MDOC_PHRASE) |
|
mdoc->flags |= MDOC_PHRASELIT; |
mdoc->flags |= MDOC_PHRASELIT; |
|
} |
pairs = 0; |
pairs = 0; |
for ( ; buf[*pos]; (*pos)++) { |
for ( ; buf[*pos]; (*pos)++) { |
/* Move following text left after quoted quotes. */ |
/* Move following text left after quoted quotes. */ |
Line 553 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 552 args(struct roff_man *mdoc, int line, int *pos, |
|
if (buf[*pos] == '\0') { |
if (buf[*pos] == '\0') { |
if ( ! (mdoc->flags & MDOC_PHRASE)) |
if ( ! (mdoc->flags & MDOC_PHRASE)) |
mandoc_msg(MANDOCERR_ARG_QUOTE, |
mandoc_msg(MANDOCERR_ARG_QUOTE, |
mdoc->parse, line, *pos, NULL); |
line, *pos, NULL); |
return ARGS_QWORD; |
return ARGS_WORD; |
} |
} |
|
|
mdoc->flags &= ~MDOC_PHRASELIT; |
mdoc->flags &= ~MDOC_PHRASELIT; |
buf[(*pos)++] = '\0'; |
buf[(*pos)++] = '\0'; |
|
|
if ('\0' == buf[*pos]) |
if ('\0' == buf[*pos]) |
return ARGS_QWORD; |
return ARGS_WORD; |
|
|
while (' ' == buf[*pos]) |
while (' ' == buf[*pos]) |
(*pos)++; |
(*pos)++; |
|
|
if ('\0' == buf[*pos]) |
if ('\0' == buf[*pos]) |
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse, |
mandoc_msg(MANDOCERR_SPACE_EOL, line, *pos, NULL); |
line, *pos, NULL); |
|
|
|
return ARGS_QWORD; |
return ARGS_WORD; |
} |
} |
|
|
p = &buf[*pos]; |
p = &buf[*pos]; |
*v = mandoc_getarg(mdoc->parse, &p, line, pos); |
*v = roff_getarg(mdoc->roff, &p, line, pos); |
|
if (v == &v_local) |
|
free(*v); |
|
|
/* |
/* |
* After parsing the last word in this phrase, |
* After parsing the last word in this phrase, |
Line 585 args(struct roff_man *mdoc, int line, int *pos, |
|
Line 585 args(struct roff_man *mdoc, int line, int *pos, |
|
mdoc->flags &= ~MDOC_PHRASEQL; |
mdoc->flags &= ~MDOC_PHRASEQL; |
mdoc->flags |= MDOC_PHRASEQF; |
mdoc->flags |= MDOC_PHRASEQF; |
} |
} |
return ARGS_WORD; |
return ARGS_ALLOC; |
} |
} |
|
|
/* |
/* |
Line 656 argv_multi(struct roff_man *mdoc, int line, |
|
Line 656 argv_multi(struct roff_man *mdoc, int line, |
|
v->value = mandoc_reallocarray(v->value, |
v->value = mandoc_reallocarray(v->value, |
v->sz + MULTI_STEP, sizeof(char *)); |
v->sz + MULTI_STEP, sizeof(char *)); |
|
|
v->value[(int)v->sz] = mandoc_strdup(p); |
if (ac != ARGS_ALLOC) |
|
p = mandoc_strdup(p); |
|
v->value[(int)v->sz] = p; |
} |
} |
} |
} |
|
|
Line 671 argv_single(struct roff_man *mdoc, int line, |
|
Line 673 argv_single(struct roff_man *mdoc, int line, |
|
if (ac == ARGS_EOLN) |
if (ac == ARGS_EOLN) |
return; |
return; |
|
|
|
if (ac != ARGS_ALLOC) |
|
p = mandoc_strdup(p); |
|
|
v->sz = 1; |
v->sz = 1; |
v->value = mandoc_malloc(sizeof(char *)); |
v->value = mandoc_malloc(sizeof(char *)); |
v->value[0] = mandoc_strdup(p); |
v->value[0] = p; |
} |
} |