version 1.147, 2016/01/08 02:13:39 |
version 1.159, 2017/02/03 17:56:59 |
|
|
/* $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) 2010-2015 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org> |
* Copyright (c) 2010, 2012 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 |
|
|
#include "config.h" |
#include "config.h" |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#if HAVE_MMAP |
|
#include <sys/mman.h> |
#include <sys/mman.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#endif |
|
|
|
#include <assert.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
Line 110 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
Line 108 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
"no document body", |
"no document body", |
"content before first section header", |
"content before first section header", |
"first section is not \"NAME\"", |
"first section is not \"NAME\"", |
"NAME section without name", |
"NAME section without Nm before Nd", |
"NAME section without description", |
"NAME section without description", |
"description not at the end of NAME", |
"description not at the end of NAME", |
"bad NAME section content", |
"bad NAME section content", |
|
"missing comma before name", |
"missing description line, using \"\"", |
"missing description line, using \"\"", |
"sections out of conventional order", |
"sections out of conventional order", |
"duplicate section title", |
"duplicate section title", |
Line 143 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
Line 142 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
"empty argument, using 0n", |
"empty argument, using 0n", |
"missing display type, using -ragged", |
"missing display type, using -ragged", |
"list type is not the first argument", |
"list type is not the first argument", |
"missing -width in -tag list, using 8n", |
"missing -width in -tag list, using 6n", |
"missing utility name, using \"\"", |
"missing utility name, using \"\"", |
"missing function name, using \"\"", |
"missing function name, using \"\"", |
"empty head in list item", |
"empty head in list item", |
Line 152 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
Line 151 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
"unknown font type, using \\fR", |
"unknown font type, using \\fR", |
"nothing follows prefix", |
"nothing follows prefix", |
"empty reference block", |
"empty reference block", |
|
"missing section argument", |
"missing -std argument, adding it", |
"missing -std argument, adding it", |
"missing option string, using \"\"", |
"missing option string, using \"\"", |
"missing resource identifier, using \"\"", |
"missing resource identifier, using \"\"", |
Line 177 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
Line 177 static const char * const mandocerrs[MANDOCERR_MAX] = |
|
"blank line in fill mode, using .sp", |
"blank line in fill mode, using .sp", |
"tab in filled text", |
"tab in filled text", |
"whitespace at end of input line", |
"whitespace at end of input line", |
|
"new sentence, new line", |
"bad comment style", |
"bad comment style", |
"invalid escape sequence", |
"invalid escape sequence", |
"undefined string, using \"\"", |
"undefined string, using \"\"", |
Line 291 choose_parser(struct mparse *curp) |
|
Line 292 choose_parser(struct mparse *curp) |
|
} |
} |
} |
} |
|
|
if (curp->man == NULL) { |
|
curp->man = roff_man_alloc(curp->roff, curp, curp->defos, |
|
curp->options & MPARSE_QUICK ? 1 : 0); |
|
curp->man->macroset = MACROSET_MAN; |
|
curp->man->first->tok = TOKEN_NONE; |
|
} |
|
|
|
if (format == MPARSE_MDOC) { |
if (format == MPARSE_MDOC) { |
mdoc_hash_init(); |
mdoc_hash_init(); |
curp->man->macroset = MACROSET_MDOC; |
curp->man->macroset = MACROSET_MDOC; |
Line 324 mparse_buf_r(struct mparse *curp, struct buf blk, size |
|
Line 318 mparse_buf_r(struct mparse *curp, struct buf blk, size |
|
const char *save_file; |
const char *save_file; |
char *cp; |
char *cp; |
size_t pos; /* byte number in the ln buffer */ |
size_t pos; /* byte number in the ln buffer */ |
|
size_t j; /* auxiliary byte number in the blk buffer */ |
enum rofferr rr; |
enum rofferr rr; |
int of; |
int of; |
int lnn; /* line number in the real file */ |
int lnn; /* line number in the real file */ |
Line 429 mparse_buf_r(struct mparse *curp, struct buf blk, size |
|
Line 424 mparse_buf_r(struct mparse *curp, struct buf blk, size |
|
} |
} |
|
|
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { |
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { |
|
j = i; |
i += 2; |
i += 2; |
/* Comment, skip to end of line */ |
/* Comment, skip to end of line */ |
for (; i < blk.sz; ++i) { |
for (; i < blk.sz; ++i) { |
if ('\n' == blk.buf[i]) { |
if (blk.buf[i] != '\n') |
++i; |
continue; |
++lnn; |
if (blk.buf[i - 1] == ' ' || |
break; |
blk.buf[i - 1] == '\t') |
} |
mandoc_msg( |
|
MANDOCERR_SPACE_EOL, |
|
curp, curp->line, |
|
pos + i-1 - j, NULL); |
|
++i; |
|
++lnn; |
|
break; |
} |
} |
|
|
/* Backout trailing whitespaces */ |
/* Backout trailing whitespaces */ |
|
|
if (curp->secondary) |
if (curp->secondary) |
curp->secondary->sz -= pos + 1; |
curp->secondary->sz -= pos + 1; |
save_file = curp->file; |
save_file = curp->file; |
if (mparse_open(curp, &fd, ln.buf + of) == |
if ((fd = mparse_open(curp, ln.buf + of)) != -1) { |
MANDOCLEVEL_OK) { |
|
mparse_readfd(curp, fd, ln.buf + of); |
mparse_readfd(curp, fd, ln.buf + of); |
close(fd); |
close(fd); |
curp->file = save_file; |
curp->file = save_file; |
|
|
break; |
break; |
} |
} |
|
|
/* |
if (curp->man->macroset == MACROSET_NONE) |
* If input parsers have not been allocated, do so now. |
|
* We keep these instanced between parsers, but set them |
|
* locally per parse routine since we can use different |
|
* parsers with each one. |
|
*/ |
|
|
|
if (curp->man == NULL || |
|
curp->man->macroset == MACROSET_NONE) |
|
choose_parser(curp); |
choose_parser(curp); |
|
|
/* |
/* |
Line 614 read_whole_file(struct mparse *curp, const char *file, |
|
Line 607 read_whole_file(struct mparse *curp, const char *file, |
|
size_t off; |
size_t off; |
ssize_t ssz; |
ssize_t ssz; |
|
|
#if HAVE_MMAP |
|
struct stat st; |
struct stat st; |
|
|
if (fstat(fd, &st) == -1) |
if (fstat(fd, &st) == -1) |
Line 638 read_whole_file(struct mparse *curp, const char *file, |
|
Line 630 read_whole_file(struct mparse *curp, const char *file, |
|
if (fb->buf != MAP_FAILED) |
if (fb->buf != MAP_FAILED) |
return 1; |
return 1; |
} |
} |
#endif |
|
|
|
if (curp->gzip) { |
if (curp->gzip) { |
if ((gz = gzdopen(fd, "rb")) == NULL) |
if ((gz = gzdopen(fd, "rb")) == NULL) |
Line 684 read_whole_file(struct mparse *curp, const char *file, |
|
Line 675 read_whole_file(struct mparse *curp, const char *file, |
|
static void |
static void |
mparse_end(struct mparse *curp) |
mparse_end(struct mparse *curp) |
{ |
{ |
|
|
if (curp->man == NULL && curp->sodest == NULL) |
|
curp->man = roff_man_alloc(curp->roff, curp, curp->defos, |
|
curp->options & MPARSE_QUICK ? 1 : 0); |
|
if (curp->man->macroset == MACROSET_NONE) |
if (curp->man->macroset == MACROSET_NONE) |
curp->man->macroset = MACROSET_MAN; |
curp->man->macroset = MACROSET_MAN; |
if (curp->man->macroset == MACROSET_MDOC) |
if (curp->man->macroset == MACROSET_MDOC) |
Line 767 mparse_readfd(struct mparse *curp, int fd, const char |
|
Line 754 mparse_readfd(struct mparse *curp, int fd, const char |
|
(MPARSE_UTF8 | MPARSE_LATIN1); |
(MPARSE_UTF8 | MPARSE_LATIN1); |
mparse_parse_buffer(curp, blk, file); |
mparse_parse_buffer(curp, blk, file); |
curp->filenc = save_filenc; |
curp->filenc = save_filenc; |
#if HAVE_MMAP |
|
if (with_mmap) |
if (with_mmap) |
munmap(blk.buf, blk.sz); |
munmap(blk.buf, blk.sz); |
else |
else |
#endif |
|
free(blk.buf); |
free(blk.buf); |
} |
} |
return curp->file_status; |
return curp->file_status; |
} |
} |
|
|
enum mandoclevel |
int |
mparse_open(struct mparse *curp, int *fd, const char *file) |
mparse_open(struct mparse *curp, const char *file) |
{ |
{ |
char *cp; |
char *cp; |
|
int fd; |
|
|
curp->file = file; |
curp->file = file; |
cp = strrchr(file, '.'); |
cp = strrchr(file, '.'); |
Line 788 mparse_open(struct mparse *curp, int *fd, const char * |
|
Line 774 mparse_open(struct mparse *curp, int *fd, const char * |
|
|
|
/* First try to use the filename as it is. */ |
/* First try to use the filename as it is. */ |
|
|
if ((*fd = open(file, O_RDONLY)) != -1) |
if ((fd = open(file, O_RDONLY)) != -1) |
return MANDOCLEVEL_OK; |
return fd; |
|
|
/* |
/* |
* If that doesn't work and the filename doesn't |
* If that doesn't work and the filename doesn't |
Line 798 mparse_open(struct mparse *curp, int *fd, const char * |
|
Line 784 mparse_open(struct mparse *curp, int *fd, const char * |
|
|
|
if ( ! curp->gzip) { |
if ( ! curp->gzip) { |
mandoc_asprintf(&cp, "%s.gz", file); |
mandoc_asprintf(&cp, "%s.gz", file); |
*fd = open(file, O_RDONLY); |
fd = open(cp, O_RDONLY); |
free(cp); |
free(cp); |
if (*fd != -1) { |
if (fd != -1) { |
curp->gzip = 1; |
curp->gzip = 1; |
return MANDOCLEVEL_OK; |
return fd; |
} |
} |
} |
} |
|
|
/* Neither worked, give up. */ |
/* Neither worked, give up. */ |
|
|
mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno)); |
mandoc_msg(MANDOCERR_FILE, curp, 0, 0, strerror(errno)); |
return MANDOCLEVEL_ERROR; |
return -1; |
} |
} |
|
|
struct mparse * |
struct mparse * |
Line 842 mparse_alloc(int options, enum mandoclevel wlevel, man |
|
Line 828 mparse_alloc(int options, enum mandoclevel wlevel, man |
|
void |
void |
mparse_reset(struct mparse *curp) |
mparse_reset(struct mparse *curp) |
{ |
{ |
|
|
roff_reset(curp->roff); |
roff_reset(curp->roff); |
|
roff_man_reset(curp->man); |
if (curp->man != NULL) |
|
roff_man_reset(curp->man); |
|
if (curp->secondary) |
if (curp->secondary) |
curp->secondary->sz = 0; |
curp->secondary->sz = 0; |
|
|
Line 854 mparse_reset(struct mparse *curp) |
|
Line 837 mparse_reset(struct mparse *curp) |
|
|
|
free(curp->sodest); |
free(curp->sodest); |
curp->sodest = NULL; |
curp->sodest = NULL; |
|
curp->gzip = 0; |
} |
} |
|
|
void |
void |
Line 882 mparse_result(struct mparse *curp, struct roff_man **m |
|
Line 866 mparse_result(struct mparse *curp, struct roff_man **m |
|
} |
} |
if (man) |
if (man) |
*man = curp->man; |
*man = curp->man; |
|
} |
|
|
|
void |
|
mparse_updaterc(struct mparse *curp, enum mandoclevel *rc) |
|
{ |
|
if (curp->file_status > *rc) |
|
*rc = curp->file_status; |
} |
} |
|
|
void |
void |