version 1.194, 2013/10/05 22:08:12 |
version 1.201, 2014/01/07 09:10:45 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org> |
|
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.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 "config.h" |
#include "config.h" |
#endif |
#endif |
|
|
#ifndef OSNAME |
#ifndef OSNAME |
#include <sys/utsname.h> |
#include <sys/utsname.h> |
#endif |
#endif |
|
|
Line 97 static int post_bl_block_width(POST_ARGS); |
|
Line 98 static int post_bl_block_width(POST_ARGS); |
|
static int post_bl_block_tag(POST_ARGS); |
static int post_bl_block_tag(POST_ARGS); |
static int post_bl_head(POST_ARGS); |
static int post_bl_head(POST_ARGS); |
static int post_bx(POST_ARGS); |
static int post_bx(POST_ARGS); |
|
static int post_defaults(POST_ARGS); |
static int post_dd(POST_ARGS); |
static int post_dd(POST_ARGS); |
static int post_dt(POST_ARGS); |
static int post_dt(POST_ARGS); |
static int post_defaults(POST_ARGS); |
|
static int post_literal(POST_ARGS); |
|
static int post_eoln(POST_ARGS); |
static int post_eoln(POST_ARGS); |
|
static int post_hyph(POST_ARGS); |
|
static int post_ignpar(POST_ARGS); |
static int post_it(POST_ARGS); |
static int post_it(POST_ARGS); |
static int post_lb(POST_ARGS); |
static int post_lb(POST_ARGS); |
|
static int post_literal(POST_ARGS); |
static int post_nm(POST_ARGS); |
static int post_nm(POST_ARGS); |
static int post_ns(POST_ARGS); |
static int post_ns(POST_ARGS); |
static int post_os(POST_ARGS); |
static int post_os(POST_ARGS); |
static int post_par(POST_ARGS); |
static int post_par(POST_ARGS); |
static int post_ignpar(POST_ARGS); |
|
static int post_prol(POST_ARGS); |
static int post_prol(POST_ARGS); |
static int post_root(POST_ARGS); |
static int post_root(POST_ARGS); |
static int post_rs(POST_ARGS); |
static int post_rs(POST_ARGS); |
Line 142 static v_post posts_bx[] = { post_bx, NULL }; |
|
Line 144 static v_post posts_bx[] = { post_bx, NULL }; |
|
static v_post posts_bool[] = { ebool, NULL }; |
static v_post posts_bool[] = { ebool, NULL }; |
static v_post posts_eoln[] = { post_eoln, NULL }; |
static v_post posts_eoln[] = { post_eoln, NULL }; |
static v_post posts_defaults[] = { post_defaults, NULL }; |
static v_post posts_defaults[] = { post_defaults, NULL }; |
|
static v_post posts_d1[] = { bwarn_ge1, post_hyph, NULL }; |
static v_post posts_dd[] = { post_dd, post_prol, NULL }; |
static v_post posts_dd[] = { post_dd, post_prol, NULL }; |
static v_post posts_dl[] = { post_literal, bwarn_ge1, NULL }; |
static v_post posts_dl[] = { post_literal, bwarn_ge1, NULL }; |
static v_post posts_dt[] = { post_dt, post_prol, NULL }; |
static v_post posts_dt[] = { post_dt, post_prol, NULL }; |
static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL }; |
static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL }; |
|
static v_post posts_hyph[] = { post_hyph, NULL }; |
|
static v_post posts_hyphtext[] = { ewarn_ge1, post_hyph, NULL }; |
static v_post posts_it[] = { post_it, NULL }; |
static v_post posts_it[] = { post_it, NULL }; |
static v_post posts_lb[] = { post_lb, NULL }; |
static v_post posts_lb[] = { post_lb, NULL }; |
static v_post posts_nd[] = { berr_ge1, NULL }; |
static v_post posts_nd[] = { berr_ge1, post_hyph, NULL }; |
static v_post posts_nm[] = { post_nm, NULL }; |
static v_post posts_nm[] = { post_nm, NULL }; |
static v_post posts_notext[] = { ewarn_eq0, NULL }; |
static v_post posts_notext[] = { ewarn_eq0, NULL }; |
static v_post posts_ns[] = { post_ns, NULL }; |
static v_post posts_ns[] = { post_ns, NULL }; |
static v_post posts_os[] = { post_os, post_prol, NULL }; |
static v_post posts_os[] = { post_os, post_prol, NULL }; |
static v_post posts_pp[] = { post_par, ewarn_eq0, NULL }; |
static v_post posts_pp[] = { post_par, ewarn_eq0, NULL }; |
static v_post posts_rs[] = { post_rs, NULL }; |
static v_post posts_rs[] = { post_rs, NULL }; |
static v_post posts_sh[] = { post_ignpar, hwarn_ge1, post_sh, NULL }; |
static v_post posts_sh[] = { post_ignpar,hwarn_ge1,post_sh,post_hyph,NULL }; |
static v_post posts_sp[] = { post_par, ewarn_le1, NULL }; |
static v_post posts_sp[] = { post_par, ewarn_le1, NULL }; |
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, NULL }; |
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, post_hyph, NULL }; |
static v_post posts_st[] = { post_st, NULL }; |
static v_post posts_st[] = { post_st, NULL }; |
static v_post posts_std[] = { post_std, NULL }; |
static v_post posts_std[] = { post_std, NULL }; |
static v_post posts_text[] = { ewarn_ge1, NULL }; |
static v_post posts_text[] = { ewarn_ge1, NULL }; |
static v_post posts_text1[] = { ewarn_eq1, NULL }; |
static v_post posts_text1[] = { ewarn_eq1, NULL }; |
static v_post posts_vt[] = { post_vt, NULL }; |
static v_post posts_vt[] = { post_vt, NULL }; |
static v_post posts_wline[] = { bwarn_ge1, NULL }; |
|
static v_pre pres_an[] = { pre_an, NULL }; |
static v_pre pres_an[] = { pre_an, NULL }; |
static v_pre pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL }; |
static v_pre pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL }; |
static v_pre pres_bl[] = { pre_bl, pre_par, NULL }; |
static v_pre pres_bl[] = { pre_bl, pre_par, NULL }; |
Line 171 static v_pre pres_d1[] = { pre_display, NULL }; |
|
Line 175 static v_pre pres_d1[] = { pre_display, NULL }; |
|
static v_pre pres_dl[] = { pre_literal, pre_display, NULL }; |
static v_pre pres_dl[] = { pre_literal, pre_display, NULL }; |
static v_pre pres_dd[] = { pre_dd, NULL }; |
static v_pre pres_dd[] = { pre_dd, NULL }; |
static v_pre pres_dt[] = { pre_dt, NULL }; |
static v_pre pres_dt[] = { pre_dt, NULL }; |
static v_pre pres_er[] = { NULL, NULL }; |
|
static v_pre pres_fd[] = { NULL, NULL }; |
|
static v_pre pres_it[] = { pre_it, pre_par, NULL }; |
static v_pre pres_it[] = { pre_it, pre_par, NULL }; |
static v_pre pres_os[] = { pre_os, NULL }; |
static v_pre pres_os[] = { pre_os, NULL }; |
static v_pre pres_pp[] = { pre_par, NULL }; |
static v_pre pres_pp[] = { pre_par, NULL }; |
Line 188 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 190 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ pres_sh, posts_sh }, /* Sh */ |
{ pres_sh, posts_sh }, /* Sh */ |
{ pres_ss, posts_ss }, /* Ss */ |
{ pres_ss, posts_ss }, /* Ss */ |
{ pres_pp, posts_pp }, /* Pp */ |
{ pres_pp, posts_pp }, /* Pp */ |
{ pres_d1, posts_wline }, /* D1 */ |
{ pres_d1, posts_d1 }, /* D1 */ |
{ pres_dl, posts_dl }, /* Dl */ |
{ pres_dl, posts_dl }, /* Dl */ |
{ pres_bd, posts_bd }, /* Bd */ |
{ pres_bd, posts_bd }, /* Bd */ |
{ NULL, NULL }, /* Ed */ |
{ NULL, NULL }, /* Ed */ |
Line 201 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 203 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* Cd */ |
{ NULL, NULL }, /* Cd */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Cm */ |
{ NULL, NULL }, /* Dv */ |
{ NULL, NULL }, /* Dv */ |
{ pres_er, NULL }, /* Er */ |
{ NULL, NULL }, /* Er */ |
{ NULL, NULL }, /* Ev */ |
{ NULL, NULL }, /* Ev */ |
{ pres_std, posts_std }, /* Ex */ |
{ pres_std, posts_std }, /* Ex */ |
{ NULL, NULL }, /* Fa */ |
{ NULL, NULL }, /* Fa */ |
{ pres_fd, posts_text }, /* Fd */ |
{ NULL, posts_text }, /* Fd */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, NULL }, /* Fl */ |
{ NULL, NULL }, /* Fn */ |
{ NULL, NULL }, /* Fn */ |
{ NULL, NULL }, /* Ft */ |
{ NULL, NULL }, /* Ft */ |
Line 223 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 225 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, posts_vt }, /* Vt */ |
{ NULL, posts_vt }, /* Vt */ |
{ NULL, posts_text }, /* Xr */ |
{ NULL, posts_text }, /* Xr */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_text }, /* %A */ |
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_hyphtext }, /* %B */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_text }, /* %D */ |
{ NULL, posts_text }, /* %D */ |
{ NULL, posts_text }, /* %I */ |
{ NULL, posts_text }, /* %I */ |
{ NULL, posts_text }, /* %J */ |
{ NULL, posts_text }, /* %J */ |
{ NULL, posts_text }, /* %N */ |
{ NULL, posts_hyphtext }, /* %N */ |
{ NULL, posts_text }, /* %O */ |
{ NULL, posts_hyphtext }, /* %O */ |
{ NULL, posts_text }, /* %P */ |
{ NULL, posts_text }, /* %P */ |
{ NULL, posts_text }, /* %R */ |
{ NULL, posts_hyphtext }, /* %R */ |
{ NULL, posts_text }, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_hyphtext }, /* %T */ /* FIXME: can be used outside Rs/Re. */ |
{ NULL, posts_text }, /* %V */ |
{ NULL, posts_text }, /* %V */ |
{ NULL, NULL }, /* Ac */ |
{ NULL, NULL }, /* Ac */ |
{ NULL, NULL }, /* Ao */ |
{ NULL, NULL }, /* Ao */ |
Line 271 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
Line 273 static const struct valids mdoc_valids[MDOC_MAX] = { |
|
{ NULL, NULL }, /* So */ |
{ NULL, NULL }, /* So */ |
{ NULL, NULL }, /* Sq */ |
{ NULL, NULL }, /* Sq */ |
{ NULL, posts_bool }, /* Sm */ |
{ NULL, posts_bool }, /* Sm */ |
{ NULL, NULL }, /* Sx */ |
{ NULL, posts_hyph }, /* Sx */ |
{ NULL, NULL }, /* Sy */ |
{ NULL, NULL }, /* Sy */ |
{ NULL, NULL }, /* Tn */ |
{ NULL, NULL }, /* Tn */ |
{ NULL, NULL }, /* Ux */ |
{ NULL, NULL }, /* Ux */ |
Line 1590 post_bl_head(POST_ARGS) |
|
Line 1592 post_bl_head(POST_ARGS) |
|
static int |
static int |
post_bl(POST_ARGS) |
post_bl(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
struct mdoc_node *nparent, *nprev; /* of the Bl block */ |
|
struct mdoc_node *nblock, *nbody; /* of the Bl */ |
|
struct mdoc_node *nchild, *nnext; /* of the Bl body */ |
|
|
if (MDOC_HEAD == mdoc->last->type) |
nbody = mdoc->last; |
return(post_bl_head(mdoc)); |
switch (nbody->type) { |
if (MDOC_BLOCK == mdoc->last->type) |
case (MDOC_BLOCK): |
return(post_bl_block(mdoc)); |
return(post_bl_block(mdoc)); |
if (MDOC_BODY != mdoc->last->type) |
case (MDOC_HEAD): |
|
return(post_bl_head(mdoc)); |
|
case (MDOC_BODY): |
|
break; |
|
default: |
return(1); |
return(1); |
|
} |
|
|
for (n = mdoc->last->child; n; n = n->next) { |
nchild = nbody->child; |
switch (n->tok) { |
while (NULL != nchild) { |
case (MDOC_Lp): |
if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) { |
/* FALLTHROUGH */ |
nchild = nchild->next; |
case (MDOC_Pp): |
|
mdoc_nmsg(mdoc, n, MANDOCERR_CHILD); |
|
/* FALLTHROUGH */ |
|
case (MDOC_It): |
|
/* FALLTHROUGH */ |
|
case (MDOC_Sm): |
|
continue; |
continue; |
default: |
|
break; |
|
} |
} |
|
|
mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD); |
mdoc_nmsg(mdoc, nchild, MANDOCERR_CHILD); |
return(0); |
|
|
/* |
|
* Move the node out of the Bl block. |
|
* First, collect all required node pointers. |
|
*/ |
|
|
|
nblock = nbody->parent; |
|
nprev = nblock->prev; |
|
nparent = nblock->parent; |
|
nnext = nchild->next; |
|
|
|
/* |
|
* Unlink this child. |
|
*/ |
|
|
|
assert(NULL == nchild->prev); |
|
if (0 == --nbody->nchild) { |
|
nbody->child = NULL; |
|
nbody->last = NULL; |
|
assert(NULL == nnext); |
|
} else { |
|
nbody->child = nnext; |
|
nnext->prev = NULL; |
|
} |
|
|
|
/* |
|
* Relink this child. |
|
*/ |
|
|
|
nchild->parent = nparent; |
|
nchild->prev = nprev; |
|
nchild->next = nblock; |
|
|
|
nblock->prev = nchild; |
|
nparent->nchild++; |
|
if (NULL == nprev) |
|
nparent->child = nchild; |
|
else |
|
nprev->next = nchild; |
|
|
|
nchild = nnext; |
} |
} |
|
|
return(1); |
return(1); |
Line 1634 ebool(struct mdoc *mdoc) |
|
Line 1675 ebool(struct mdoc *mdoc) |
|
|
|
assert(MDOC_TEXT == mdoc->last->child->type); |
assert(MDOC_TEXT == mdoc->last->child->type); |
|
|
if (0 == strcmp(mdoc->last->child->string, "on")) |
if (0 == strcmp(mdoc->last->child->string, "on")) { |
|
if (MDOC_Sm == mdoc->last->tok) |
|
mdoc->flags &= ~MDOC_SMOFF; |
return(1); |
return(1); |
if (0 == strcmp(mdoc->last->child->string, "off")) |
} |
|
if (0 == strcmp(mdoc->last->child->string, "off")) { |
|
if (MDOC_Sm == mdoc->last->tok) |
|
mdoc->flags |= MDOC_SMOFF; |
return(1); |
return(1); |
|
} |
|
|
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL); |
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL); |
return(1); |
return(1); |
Line 1817 post_rs(POST_ARGS) |
|
Line 1864 post_rs(POST_ARGS) |
|
return(1); |
return(1); |
} |
} |
|
|
|
/* |
|
* For some arguments of some macros, |
|
* convert all breakable hyphens into ASCII_HYPH. |
|
*/ |
static int |
static int |
|
post_hyph(POST_ARGS) |
|
{ |
|
struct mdoc_node *n, *nch; |
|
char *cp; |
|
|
|
n = mdoc->last; |
|
switch (n->type) { |
|
case (MDOC_HEAD): |
|
if (MDOC_Sh == n->tok || MDOC_Ss == n->tok) |
|
break; |
|
return(1); |
|
case (MDOC_BODY): |
|
if (MDOC_D1 == n->tok || MDOC_Nd == n->tok) |
|
break; |
|
return(1); |
|
case (MDOC_ELEM): |
|
break; |
|
default: |
|
return(1); |
|
} |
|
|
|
for (nch = n->child; nch; nch = nch->next) { |
|
if (MDOC_TEXT != nch->type) |
|
continue; |
|
cp = nch->string; |
|
if (3 > strnlen(cp, 3)) |
|
continue; |
|
while ('\0' != *(++cp)) |
|
if ('-' == *cp && |
|
isalpha((unsigned char)cp[-1]) && |
|
isalpha((unsigned char)cp[1])) |
|
*cp = ASCII_HYPH; |
|
} |
|
return(1); |
|
} |
|
|
|
static int |
post_ns(POST_ARGS) |
post_ns(POST_ARGS) |
{ |
{ |
|
|
Line 1904 post_sh_head(POST_ARGS) |
|
Line 1992 post_sh_head(POST_ARGS) |
|
/* The SYNOPSIS gets special attention in other areas. */ |
/* The SYNOPSIS gets special attention in other areas. */ |
|
|
if (SEC_SYNOPSIS == sec) { |
if (SEC_SYNOPSIS == sec) { |
roff_setreg(mdoc->roff, "nS", 1); |
roff_setreg(mdoc->roff, "nS", 1, '='); |
mdoc->flags |= MDOC_SYNOPSIS; |
mdoc->flags |= MDOC_SYNOPSIS; |
} else { |
} else { |
roff_setreg(mdoc->roff, "nS", 0); |
roff_setreg(mdoc->roff, "nS", 0, '='); |
mdoc->flags &= ~MDOC_SYNOPSIS; |
mdoc->flags &= ~MDOC_SYNOPSIS; |
} |
} |
|
|
Line 2096 post_dd(POST_ARGS) |
|
Line 2184 post_dd(POST_ARGS) |
|
|
|
n = mdoc->last; |
n = mdoc->last; |
if (NULL == n->child || '\0' == n->child->string[0]) { |
if (NULL == n->child || '\0' == n->child->string[0]) { |
mdoc->meta.date = mandoc_normdate |
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") : |
(mdoc->parse, NULL, n->line, n->pos); |
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos); |
return(1); |
return(1); |
} |
} |
|
|
Line 2108 post_dd(POST_ARGS) |
|
Line 2196 post_dd(POST_ARGS) |
|
} |
} |
|
|
assert(c); |
assert(c); |
mdoc->meta.date = mandoc_normdate |
mdoc->meta.date = mdoc->quick ? mandoc_strdup(buf) : |
(mdoc->parse, buf, n->line, n->pos); |
mandoc_normdate(mdoc->parse, buf, n->line, n->pos); |
|
|
return(1); |
return(1); |
} |
} |
Line 2260 post_bx(POST_ARGS) |
|
Line 2348 post_bx(POST_ARGS) |
|
static int |
static int |
post_os(POST_ARGS) |
post_os(POST_ARGS) |
{ |
{ |
struct mdoc_node *n; |
|
char buf[BUFSIZ]; |
char buf[BUFSIZ]; |
int c; |
|
#ifndef OSNAME |
#ifndef OSNAME |
struct utsname utsname; |
struct utsname utsname; |
|
static char *defbuf; |
#endif |
#endif |
|
struct mdoc_node *n; |
|
int c; |
|
|
n = mdoc->last; |
n = mdoc->last; |
|
|
Line 2288 post_os(POST_ARGS) |
|
Line 2377 post_os(POST_ARGS) |
|
|
|
assert(c); |
assert(c); |
|
|
if ('\0' == buf[0]) { |
if ('\0' != *buf) { |
if (mdoc->defos) { |
mdoc->meta.os = mandoc_strdup(buf); |
mdoc->meta.os = mandoc_strdup(mdoc->defos); |
return(1); |
return(1); |
} |
} |
|
|
if (mdoc->defos) { |
|
mdoc->meta.os = mandoc_strdup(mdoc->defos); |
|
return(1); |
|
} |
|
|
#ifdef OSNAME |
#ifdef OSNAME |
if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) { |
mdoc->meta.os = mandoc_strdup(OSNAME); |
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
#else /*!OSNAME */ |
#else /*!OSNAME */ |
|
if (NULL == defbuf) { |
if (-1 == uname(&utsname)) { |
if (-1 == uname(&utsname)) { |
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME); |
mdoc_nmsg(mdoc, n, MANDOCERR_UNAME); |
mdoc->meta.os = mandoc_strdup("UNKNOWN"); |
defbuf = mandoc_strdup("UNKNOWN"); |
return(post_prol(mdoc)); |
} else if (-1 == asprintf(&defbuf, "%s %s", |
} |
utsname.sysname, utsname.release)) { |
|
perror(NULL); |
if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) { |
exit((int)MANDOCLEVEL_SYSERR); |
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
} |
if (strlcat(buf, " ", BUFSIZ) >= BUFSIZ) { |
|
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) { |
|
mdoc_nmsg(mdoc, n, MANDOCERR_MEM); |
|
return(0); |
|
} |
|
#endif /*!OSNAME*/ |
|
} |
} |
|
mdoc->meta.os = mandoc_strdup(defbuf); |
mdoc->meta.os = mandoc_strdup(buf); |
#endif /*!OSNAME*/ |
return(1); |
return(1); |
} |
} |
|
|