version 1.321, 2017/07/08 17:52:50 |
version 1.325, 2018/04/09 02:31:42 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2015, 2017, 2018 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 |
|
|
#define ROFFDEF_STD (1 << 4) /* mdoc(7) or man(7) macro. */ |
#define ROFFDEF_STD (1 << 4) /* mdoc(7) or man(7) macro. */ |
#define ROFFDEF_ANY (ROFFDEF_USER | ROFFDEF_PRE | \ |
#define ROFFDEF_ANY (ROFFDEF_USER | ROFFDEF_PRE | \ |
ROFFDEF_REN | ROFFDEF_STD) |
ROFFDEF_REN | ROFFDEF_STD) |
|
#define ROFFDEF_UNDEF (1 << 5) /* Completely undefined. */ |
|
|
/* --- data types --------------------------------------------------------- */ |
/* --- data types --------------------------------------------------------- */ |
|
|
Line 185 static int roff_getregn(const struct roff *, |
|
Line 186 static int roff_getregn(const struct roff *, |
|
const char *, size_t); |
const char *, size_t); |
static int roff_getregro(const struct roff *, |
static int roff_getregro(const struct roff *, |
const char *name); |
const char *name); |
static const char *roff_getstrn(const struct roff *, |
static const char *roff_getstrn(struct roff *, |
const char *, size_t, int *); |
const char *, size_t, int *); |
static int roff_hasregn(const struct roff *, |
static int roff_hasregn(const struct roff *, |
const char *, size_t); |
const char *, size_t); |
Line 1127 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1128 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
size_t maxl; /* expected length of the escape name */ |
size_t maxl; /* expected length of the escape name */ |
size_t naml; /* actual length of the escape name */ |
size_t naml; /* actual length of the escape name */ |
enum mandoc_esc esc; /* type of the escape sequence */ |
enum mandoc_esc esc; /* type of the escape sequence */ |
enum mandoc_os os_e; /* kind of RCS id seen */ |
|
int inaml; /* length returned from mandoc_escape() */ |
int inaml; /* length returned from mandoc_escape() */ |
int expand_count; /* to avoid infinite loops */ |
int expand_count; /* to avoid infinite loops */ |
int npos; /* position in numeric expression */ |
int npos; /* position in numeric expression */ |
int arg_complete; /* argument not interrupted by eol */ |
int arg_complete; /* argument not interrupted by eol */ |
int done; /* no more input available */ |
int done; /* no more input available */ |
int deftype; /* type of definition to paste */ |
int deftype; /* type of definition to paste */ |
|
int rcsid; /* kind of RCS id seen */ |
char term; /* character terminating the escape */ |
char term; /* character terminating the escape */ |
|
|
/* Search forward for comments. */ |
/* Search forward for comments. */ |
Line 1149 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
Line 1150 roff_res(struct roff *r, struct buf *buf, int ln, int |
|
|
|
/* Comment found, look for RCS id. */ |
/* Comment found, look for RCS id. */ |
|
|
|
rcsid = 0; |
if ((cp = strstr(stesc, "$" "OpenBSD")) != NULL) { |
if ((cp = strstr(stesc, "$" "OpenBSD")) != NULL) { |
os_e = MANDOC_OS_OPENBSD; |
rcsid = 1 << MANDOC_OS_OPENBSD; |
cp += 8; |
cp += 8; |
} else if ((cp = strstr(stesc, "$" "NetBSD")) != NULL) { |
} else if ((cp = strstr(stesc, "$" "NetBSD")) != NULL) { |
os_e = MANDOC_OS_NETBSD; |
rcsid = 1 << MANDOC_OS_NETBSD; |
cp += 7; |
cp += 7; |
} |
} |
if (cp != NULL && |
if (cp != NULL && |
isalnum((unsigned char)*cp) == 0 && |
isalnum((unsigned char)*cp) == 0 && |
strchr(cp, '$') != NULL) { |
strchr(cp, '$') != NULL) { |
if (r->man->meta.rcsids & (1 << os_e)) |
if (r->man->meta.rcsids & rcsid) |
mandoc_msg(MANDOCERR_RCS_REP, r->parse, |
mandoc_msg(MANDOCERR_RCS_REP, r->parse, |
ln, stesc + 1 - buf->buf, stesc + 1); |
ln, stesc + 1 - buf->buf, stesc + 1); |
r->man->meta.rcsids |= 1 << os_e; |
r->man->meta.rcsids |= rcsid; |
} |
} |
|
|
/* Handle trailing whitespace. */ |
/* Handle trailing whitespace. */ |
Line 1558 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
Line 1560 roff_parseln(struct roff *r, int ln, struct buf *buf, |
|
/* For now, let high level macros abort .ce mode. */ |
/* For now, let high level macros abort .ce mode. */ |
|
|
if (ctl && roffce_node != NULL && |
if (ctl && roffce_node != NULL && |
(t == TOKEN_NONE || t == ROFF_EQ || t == ROFF_TS)) { |
(t == TOKEN_NONE || t == ROFF_Dd || t == ROFF_EQ || |
|
t == ROFF_TH || t == ROFF_TS)) { |
r->man->last = roffce_node; |
r->man->last = roffce_node; |
r->man->next = ROFF_NEXT_SIBLING; |
r->man->next = ROFF_NEXT_SIBLING; |
roffce_lines = 0; |
roffce_lines = 0; |
Line 1637 roff_parse(struct roff *r, char *buf, int *pos, int ln |
|
Line 1640 roff_parse(struct roff *r, char *buf, int *pos, int ln |
|
} |
} |
if (t != TOKEN_NONE) |
if (t != TOKEN_NONE) |
*pos = cp - buf; |
*pos = cp - buf; |
|
else if (deftype == ROFFDEF_UNDEF) { |
|
/* Using an undefined macro defines it to be empty. */ |
|
roff_setstrn(&r->strtab, mac, maclen, "", 0, 0); |
|
roff_setstrn(&r->rentab, mac, maclen, NULL, 0, 0); |
|
} |
return t; |
return t; |
} |
} |
|
|
Line 2879 roff_EQ(ROFF_ARGS) |
|
Line 2887 roff_EQ(ROFF_ARGS) |
|
{ |
{ |
struct roff_node *n; |
struct roff_node *n; |
|
|
|
if (r->man->macroset == MACROSET_MAN) |
|
man_breakscope(r->man, ROFF_EQ); |
n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE); |
n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE); |
if (ln > r->man->last->line) |
if (ln > r->man->last->line) |
n->flags |= NODE_LINE; |
n->flags |= NODE_LINE; |
Line 3533 roff_setstrn(struct roffkv **r, const char *name, size |
|
Line 3543 roff_setstrn(struct roffkv **r, const char *name, size |
|
} |
} |
|
|
static const char * |
static const char * |
roff_getstrn(const struct roff *r, const char *name, size_t len, |
roff_getstrn(struct roff *r, const char *name, size_t len, |
int *deftype) |
int *deftype) |
{ |
{ |
const struct roffkv *n; |
const struct roffkv *n; |
int i; |
int found, i; |
enum roff_tok tok; |
enum roff_tok tok; |
|
|
if (*deftype & ROFFDEF_USER) { |
found = 0; |
for (n = r->strtab; n != NULL; n = n->next) { |
for (n = r->strtab; n != NULL; n = n->next) { |
if (strncmp(name, n->key.p, len) == 0 && |
if (strncmp(name, n->key.p, len) != 0 || |
n->key.p[len] == '\0' && |
n->key.p[len] != '\0' || n->val.p == NULL) |
n->val.p != NULL) { |
continue; |
*deftype = ROFFDEF_USER; |
if (*deftype & ROFFDEF_USER) { |
return n->val.p; |
*deftype = ROFFDEF_USER; |
} |
return n->val.p; |
|
} else { |
|
found = 1; |
|
break; |
} |
} |
} |
} |
if (*deftype & ROFFDEF_PRE) { |
for (n = r->rentab; n != NULL; n = n->next) { |
for (i = 0; i < PREDEFS_MAX; i++) { |
if (strncmp(name, n->key.p, len) != 0 || |
if (strncmp(name, predefs[i].name, len) == 0 && |
n->key.p[len] != '\0' || n->val.p == NULL) |
predefs[i].name[len] == '\0') { |
continue; |
*deftype = ROFFDEF_PRE; |
if (*deftype & ROFFDEF_REN) { |
return predefs[i].str; |
*deftype = ROFFDEF_REN; |
} |
return n->val.p; |
|
} else { |
|
found = 1; |
|
break; |
} |
} |
} |
} |
if (*deftype & ROFFDEF_REN) { |
for (i = 0; i < PREDEFS_MAX; i++) { |
for (n = r->rentab; n != NULL; n = n->next) { |
if (strncmp(name, predefs[i].name, len) != 0 || |
if (strncmp(name, n->key.p, len) == 0 && |
predefs[i].name[len] != '\0') |
n->key.p[len] == '\0' && |
continue; |
n->val.p != NULL) { |
if (*deftype & ROFFDEF_PRE) { |
*deftype = ROFFDEF_REN; |
*deftype = ROFFDEF_PRE; |
return n->val.p; |
return predefs[i].str; |
} |
} else { |
|
found = 1; |
|
break; |
} |
} |
} |
} |
if (*deftype & ROFFDEF_STD) { |
if (r->man->macroset != MACROSET_MAN) { |
if (r->man->macroset != MACROSET_MAN) { |
for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { |
for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { |
if (strncmp(name, roff_name[tok], len) != 0 || |
if (strncmp(name, roff_name[tok], len) == 0 && |
roff_name[tok][len] != '\0') |
roff_name[tok][len] == '\0') { |
continue; |
*deftype = ROFFDEF_STD; |
if (*deftype & ROFFDEF_STD) { |
return NULL; |
*deftype = ROFFDEF_STD; |
} |
return NULL; |
|
} else { |
|
found = 1; |
|
break; |
} |
} |
} |
} |
if (r->man->macroset != MACROSET_MDOC) { |
} |
for (tok = MAN_TH; tok < MAN_MAX; tok++) { |
if (r->man->macroset != MACROSET_MDOC) { |
if (strncmp(name, roff_name[tok], len) == 0 && |
for (tok = MAN_TH; tok < MAN_MAX; tok++) { |
roff_name[tok][len] == '\0') { |
if (strncmp(name, roff_name[tok], len) != 0 || |
*deftype = ROFFDEF_STD; |
roff_name[tok][len] != '\0') |
return NULL; |
continue; |
} |
if (*deftype & ROFFDEF_STD) { |
|
*deftype = ROFFDEF_STD; |
|
return NULL; |
|
} else { |
|
found = 1; |
|
break; |
} |
} |
} |
} |
} |
} |
|
|
|
if (found == 0 && *deftype != ROFFDEF_ANY) { |
|
if (*deftype & ROFFDEF_REN) { |
|
/* |
|
* This might still be a request, |
|
* so do not treat it as undefined yet. |
|
*/ |
|
*deftype = ROFFDEF_UNDEF; |
|
return NULL; |
|
} |
|
|
|
/* Using an undefined string defines it to be empty. */ |
|
|
|
roff_setstrn(&r->strtab, name, len, "", 0, 0); |
|
roff_setstrn(&r->rentab, name, len, NULL, 0, 0); |
|
} |
|
|
*deftype = 0; |
*deftype = 0; |
return NULL; |
return NULL; |
} |
} |