version 1.33, 2009/08/20 08:59:12 |
version 1.42, 2010/02/17 19:28:11 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
*/ |
*/ |
|
#ifdef HAVE_CONFIG_H |
|
#include "config.h" |
|
#endif |
|
|
#include <assert.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
|
#include <time.h> |
|
|
#include "libmdoc.h" |
#include "libmdoc.h" |
|
|
|
|
#define REWIND_NOHALT (1 << 1) |
#define REWIND_NOHALT (1 << 1) |
#define REWIND_HALT (1 << 2) |
#define REWIND_HALT (1 << 2) |
|
|
|
static int ctx_synopsis(MACRO_PROT_ARGS); |
static int obsolete(MACRO_PROT_ARGS); |
static int obsolete(MACRO_PROT_ARGS); |
static int blk_part_exp(MACRO_PROT_ARGS); |
static int blk_part_exp(MACRO_PROT_ARGS); |
static int in_line_eoln(MACRO_PROT_ARGS); |
static int in_line_eoln(MACRO_PROT_ARGS); |
Line 46 static int rew_sub(enum mdoc_type, struct mdoc *, |
|
Line 52 static int rew_sub(enum mdoc_type, struct mdoc *, |
|
static int rew_last(struct mdoc *, |
static int rew_last(struct mdoc *, |
const struct mdoc_node *); |
const struct mdoc_node *); |
static int append_delims(struct mdoc *, int, int *, char *); |
static int append_delims(struct mdoc *, int, int *, char *); |
static int lookup(struct mdoc *, int, const char *); |
static int lookup(int, const char *); |
static int lookup_raw(struct mdoc *, const char *); |
static int lookup_raw(const char *); |
static int swarn(struct mdoc *, enum mdoc_type, int, int, |
static int swarn(struct mdoc *, enum mdoc_type, int, int, |
const struct mdoc_node *); |
const struct mdoc_node *); |
|
|
Line 93 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { |
|
Line 99 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { |
|
{ in_line_eoln, 0 }, /* Rv */ |
{ in_line_eoln, 0 }, /* Rv */ |
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ |
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ |
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ |
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ |
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ |
{ ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ |
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ |
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ |
{ in_line_eoln, 0 }, /* %A */ |
{ in_line_eoln, 0 }, /* %A */ |
{ in_line_eoln, 0 }, /* %B */ |
{ in_line_eoln, 0 }, /* %B */ |
{ in_line_eoln, 0 }, /* %D */ |
{ in_line_eoln, 0 }, /* %D */ |
Line 174 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { |
|
Line 180 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { |
|
{ in_line_eoln, 0 }, /* %Q */ |
{ in_line_eoln, 0 }, /* %Q */ |
{ in_line_eoln, 0 }, /* br */ |
{ in_line_eoln, 0 }, /* br */ |
{ in_line_eoln, 0 }, /* sp */ |
{ in_line_eoln, 0 }, /* sp */ |
|
{ in_line_eoln, 0 }, /* %U */ |
}; |
}; |
|
|
const struct mdoc_macro * const mdoc_macros = __mdoc_macros; |
const struct mdoc_macro * const mdoc_macros = __mdoc_macros; |
Line 258 mdoc_macroend(struct mdoc *m) |
|
Line 265 mdoc_macroend(struct mdoc *m) |
|
* Look up a macro from within a subsequent context. |
* Look up a macro from within a subsequent context. |
*/ |
*/ |
static int |
static int |
lookup(struct mdoc *mdoc, int from, const char *p) |
lookup(int from, const char *p) |
{ |
{ |
|
/* FIXME: make -diag lists be un-PARSED. */ |
|
|
if ( ! (MDOC_PARSED & mdoc_macros[from].flags)) |
if ( ! (MDOC_PARSED & mdoc_macros[from].flags)) |
return(MDOC_MAX); |
return(MDOC_MAX); |
return(lookup_raw(mdoc, p)); |
return(lookup_raw(p)); |
} |
} |
|
|
|
|
Line 271 lookup(struct mdoc *mdoc, int from, const char *p) |
|
Line 279 lookup(struct mdoc *mdoc, int from, const char *p) |
|
* Lookup a macro following the initial line macro. |
* Lookup a macro following the initial line macro. |
*/ |
*/ |
static int |
static int |
lookup_raw(struct mdoc *mdoc, const char *p) |
lookup_raw(const char *p) |
{ |
{ |
int res; |
int res; |
|
|
if (MDOC_MAX == (res = mdoc_hash_find(mdoc->htab, p))) |
if (MDOC_MAX == (res = mdoc_hash_find(p))) |
return(MDOC_MAX); |
return(MDOC_MAX); |
if (MDOC_CALLABLE & mdoc_macros[res].flags) |
if (MDOC_CALLABLE & mdoc_macros[res].flags) |
return(res); |
return(res); |
Line 391 rew_dohalt(int tok, enum mdoc_type type, const struct |
|
Line 399 rew_dohalt(int tok, enum mdoc_type type, const struct |
|
case (MDOC_Qq): |
case (MDOC_Qq): |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case (MDOC_Sq): |
case (MDOC_Sq): |
|
/* FALLTHROUGH */ |
|
case (MDOC_Vt): |
assert(MDOC_TAIL != type); |
assert(MDOC_TAIL != type); |
if (type == p->type && tok == p->tok) |
if (type == p->type && tok == p->tok) |
return(REWIND_REWIND); |
return(REWIND_REWIND); |
Line 669 blk_exp_close(MACRO_PROT_ARGS) |
|
Line 679 blk_exp_close(MACRO_PROT_ARGS) |
|
if (ARGS_EOLN == c) |
if (ARGS_EOLN == c) |
break; |
break; |
|
|
if (MDOC_MAX != (c = lookup(m, tok, p))) { |
if (MDOC_MAX != (c = lookup(tok, p))) { |
if ( ! flushed) { |
if ( ! flushed) { |
if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) |
if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) |
return(0); |
return(0); |
Line 753 in_line(MACRO_PROT_ARGS) |
|
Line 763 in_line(MACRO_PROT_ARGS) |
|
|
|
/* Quoted words shouldn't be looked-up. */ |
/* Quoted words shouldn't be looked-up. */ |
|
|
c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p); |
c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p); |
|
|
/* |
/* |
* In this case, we've located a submacro and must |
* In this case, we've located a submacro and must |
Line 805 in_line(MACRO_PROT_ARGS) |
|
Line 815 in_line(MACRO_PROT_ARGS) |
|
cnt++; |
cnt++; |
if ( ! mdoc_word_alloc(m, line, la, p)) |
if ( ! mdoc_word_alloc(m, line, la, p)) |
return(0); |
return(0); |
|
|
|
/* |
|
* `Fl' macros have their scope re-opened with each new |
|
* word so that the `-' can be added to each one without |
|
* having to parse out spaces. |
|
*/ |
|
if (0 == lastpunct && MDOC_Fl == tok) { |
|
if ( ! rew_elem(m, tok)) |
|
return(0); |
|
lastpunct = 1; |
|
} |
} |
} |
|
|
if (0 == lastpunct && ! rew_elem(m, tok)) |
if (0 == lastpunct && ! rew_elem(m, tok)) |
Line 932 blk_full(MACRO_PROT_ARGS) |
|
Line 953 blk_full(MACRO_PROT_ARGS) |
|
continue; |
continue; |
} |
} |
|
|
if (MDOC_MAX == (c = lookup(m, tok, p))) { |
if (MDOC_MAX == (c = lookup(tok, p))) { |
if ( ! mdoc_word_alloc(m, line, lastarg, p)) |
if ( ! mdoc_word_alloc(m, line, lastarg, p)) |
return(0); |
return(0); |
continue; |
continue; |
Line 995 blk_part_imp(MACRO_PROT_ARGS) |
|
Line 1016 blk_part_imp(MACRO_PROT_ARGS) |
|
if (ARGS_EOLN == c) |
if (ARGS_EOLN == c) |
break; |
break; |
|
|
if (MDOC_MAX == (c = lookup(m, tok, p))) { |
if (MDOC_MAX == (c = lookup(tok, p))) { |
if ( ! mdoc_word_alloc(m, line, la, p)) |
if ( ! mdoc_word_alloc(m, line, la, p)) |
return(0); |
return(0); |
continue; |
continue; |
Line 1098 blk_part_exp(MACRO_PROT_ARGS) |
|
Line 1119 blk_part_exp(MACRO_PROT_ARGS) |
|
if (ARGS_EOLN == c) |
if (ARGS_EOLN == c) |
break; |
break; |
|
|
if (MDOC_MAX != (c = lookup(m, tok, p))) { |
if (MDOC_MAX != (c = lookup(tok, p))) { |
if ( ! flushed) { |
if ( ! flushed) { |
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) |
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) |
return(0); |
return(0); |
Line 1159 in_line_argn(MACRO_PROT_ARGS) |
|
Line 1180 in_line_argn(MACRO_PROT_ARGS) |
|
case (MDOC_Ux): |
case (MDOC_Ux): |
maxargs = 0; |
maxargs = 0; |
break; |
break; |
|
case (MDOC_Xr): |
|
maxargs = 2; |
|
break; |
default: |
default: |
maxargs = 1; |
maxargs = 1; |
break; |
break; |
Line 1209 in_line_argn(MACRO_PROT_ARGS) |
|
Line 1233 in_line_argn(MACRO_PROT_ARGS) |
|
if (ARGS_EOLN == c) |
if (ARGS_EOLN == c) |
break; |
break; |
|
|
if (MDOC_MAX != (c = lookup(m, tok, p))) { |
if (MDOC_MAX != (c = lookup(tok, p))) { |
if ( ! flushed && ! rew_elem(m, tok)) |
if ( ! flushed && ! rew_elem(m, tok)) |
return(0); |
return(0); |
flushed = 1; |
flushed = 1; |
Line 1224 in_line_argn(MACRO_PROT_ARGS) |
|
Line 1248 in_line_argn(MACRO_PROT_ARGS) |
|
return(0); |
return(0); |
flushed = 1; |
flushed = 1; |
} |
} |
|
|
|
/* |
|
* XXX: this is a hack to work around groff's ugliness |
|
* as regards `Xr' and extraneous arguments. It should |
|
* ideally be deprecated behaviour, but because this is |
|
* code is no here, it's unlikely to be removed. |
|
*/ |
|
if (MDOC_Xr == tok && j == maxargs) { |
|
if ( ! mdoc_elem_alloc(m, line, ppos, MDOC_Ns, NULL)) |
|
return(0); |
|
if ( ! rew_elem(m, MDOC_Ns)) |
|
return(0); |
|
} |
|
|
if ( ! mdoc_word_alloc(m, line, la, p)) |
if ( ! mdoc_word_alloc(m, line, la, p)) |
return(0); |
return(0); |
} |
} |
Line 1284 in_line_eoln(MACRO_PROT_ARGS) |
|
Line 1321 in_line_eoln(MACRO_PROT_ARGS) |
|
if (ARGS_EOLN == w) |
if (ARGS_EOLN == w) |
break; |
break; |
|
|
c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p); |
c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p); |
|
|
if (MDOC_MAX != c) { |
if (MDOC_MAX != c) { |
if ( ! rew_elem(m, tok)) |
if ( ! rew_elem(m, tok)) |
Line 1304 in_line_eoln(MACRO_PROT_ARGS) |
|
Line 1341 in_line_eoln(MACRO_PROT_ARGS) |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static int |
static int |
|
ctx_synopsis(MACRO_PROT_ARGS) |
|
{ |
|
|
|
/* If we're not in the SYNOPSIS, go straight to in-line. */ |
|
if (SEC_SYNOPSIS != m->lastsec) |
|
return(in_line(m, tok, line, ppos, pos, buf)); |
|
|
|
/* If we're a nested call, same place. */ |
|
if (ppos > 1) |
|
return(in_line(m, tok, line, ppos, pos, buf)); |
|
|
|
/* |
|
* XXX: this will open a block scope; however, if later we end |
|
* up formatting the block scope, then child nodes will inherit |
|
* the formatting. Be careful. |
|
*/ |
|
|
|
return(blk_part_imp(m, tok, line, ppos, pos, buf)); |
|
} |
|
|
|
|
|
/* ARGSUSED */ |
|
static int |
obsolete(MACRO_PROT_ARGS) |
obsolete(MACRO_PROT_ARGS) |
{ |
{ |
|
|
Line 1333 phrase(struct mdoc *m, int line, int ppos, char *buf) |
|
Line 1393 phrase(struct mdoc *m, int line, int ppos, char *buf) |
|
if (ARGS_EOLN == w) |
if (ARGS_EOLN == w) |
break; |
break; |
|
|
c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(m, p); |
c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(p); |
|
|
if (MDOC_MAX != c) { |
if (MDOC_MAX != c) { |
if ( ! mdoc_macro(m, c, line, la, &pos, buf)) |
if ( ! mdoc_macro(m, c, line, la, &pos, buf)) |