version 1.4, 2009/03/19 18:30:26 |
version 1.7, 2009/03/20 21:58:38 |
Line 35 extern int getsubopt(char **, char * const *, char |
|
Line 35 extern int getsubopt(char **, char * const *, char |
|
# endif |
# endif |
#endif |
#endif |
|
|
|
struct buf { |
|
char *buf; |
|
size_t sz; |
|
}; |
|
|
|
struct curparse { |
|
const char *file; |
|
int wflags; |
#define WARN_WALL 0x03 /* All-warnings mask. */ |
#define WARN_WALL 0x03 /* All-warnings mask. */ |
#define WARN_WCOMPAT (1 << 0) /* Compatibility warnings. */ |
#define WARN_WCOMPAT (1 << 0) /* Compatibility warnings. */ |
#define WARN_WSYNTAX (1 << 1) /* Syntax warnings. */ |
#define WARN_WSYNTAX (1 << 1) /* Syntax warnings. */ |
#define WARN_WERR (1 << 2) /* Warnings->errors. */ |
#define WARN_WERR (1 << 2) /* Warnings->errors. */ |
|
}; |
|
|
enum outt { |
enum outt { |
OUTT_ASCII, |
OUTT_ASCII, |
Line 68 static int woptions(int *, char *); |
|
Line 77 static int woptions(int *, char *); |
|
static int merr(void *, int, int, const char *); |
static int merr(void *, int, int, const char *); |
static int mwarn(void *, int, int, |
static int mwarn(void *, int, int, |
enum mdoc_warn, const char *); |
enum mdoc_warn, const char *); |
static int file(char **, size_t *, char **, size_t *, |
static int file(struct buf *, struct buf *, |
const char *, struct mdoc *); |
const char *, struct mdoc *); |
static int fdesc(char **, size_t *, char **, size_t *, |
static int fdesc(struct buf *, struct buf *, |
const char *, int, struct mdoc *); |
const char *, int, struct mdoc *); |
|
|
|
|
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
{ |
{ |
int c, rc, fflags, wflags; |
int c, rc, fflags; |
struct mdoc_cb cb; |
struct mdoc_cb cb; |
struct mdoc *mdoc; |
struct mdoc *mdoc; |
char *buf, *line; |
|
size_t bufsz, linesz; |
|
void *outdata; |
void *outdata; |
enum outt outtype; |
enum outt outtype; |
|
struct buf ln, blk; |
out_run outrun; |
out_run outrun; |
out_free outfree; |
out_free outfree; |
|
struct curparse curp; |
|
|
fflags = wflags = 0; |
fflags = 0; |
outtype = OUTT_ASCII; |
outtype = OUTT_ASCII; |
|
|
|
bzero(&curp, sizeof(struct curparse)); |
|
|
/* LINTED */ |
/* LINTED */ |
while (-1 != (c = getopt(argc, argv, "f:VW:T:"))) |
while (-1 != (c = getopt(argc, argv, "f:VW:T:"))) |
switch (c) { |
switch (c) { |
Line 102 main(int argc, char *argv[]) |
|
Line 113 main(int argc, char *argv[]) |
|
return(0); |
return(0); |
break; |
break; |
case ('W'): |
case ('W'): |
if ( ! woptions(&wflags, optarg)) |
if ( ! woptions(&curp.wflags, optarg)) |
return(0); |
return(0); |
break; |
break; |
case ('V'): |
case ('V'): |
Line 160 main(int argc, char *argv[]) |
|
Line 171 main(int argc, char *argv[]) |
|
cb.mdoc_err = merr; |
cb.mdoc_err = merr; |
cb.mdoc_warn = mwarn; |
cb.mdoc_warn = mwarn; |
|
|
buf = line = NULL; |
bzero(&ln, sizeof(struct buf)); |
bufsz = linesz = 0; |
bzero(&blk, sizeof(struct buf)); |
|
|
mdoc = mdoc_alloc(&wflags, fflags, &cb); |
mdoc = mdoc_alloc(&curp, fflags, &cb); |
|
|
/* |
/* |
* Loop around available files. |
* Loop around available files. |
*/ |
*/ |
|
|
if (NULL == *argv) { |
if (NULL == *argv) { |
c = fdesc(&line, &linesz, &buf, &bufsz, |
curp.file = "<stdin>"; |
"stdin", STDIN_FILENO, mdoc); |
c = fdesc(&blk, &ln, "stdin", STDIN_FILENO, mdoc); |
rc = 0; |
rc = 0; |
if (c && NULL == outrun) |
if (c && NULL == outrun) |
rc = 1; |
rc = 1; |
Line 179 main(int argc, char *argv[]) |
|
Line 190 main(int argc, char *argv[]) |
|
rc = 1; |
rc = 1; |
} else { |
} else { |
while (*argv) { |
while (*argv) { |
c = file(&line, &linesz, &buf, |
curp.file = *argv; |
&bufsz, *argv, mdoc); |
c = file(&blk, &ln, *argv, mdoc); |
if ( ! c) |
if ( ! c) |
break; |
break; |
if (outrun && ! (*outrun)(outdata, mdoc)) |
if (outrun && ! (*outrun)(outdata, mdoc)) |
Line 192 main(int argc, char *argv[]) |
|
Line 203 main(int argc, char *argv[]) |
|
rc = NULL == *argv; |
rc = NULL == *argv; |
} |
} |
|
|
if (buf) |
if (blk.buf) |
free(buf); |
free(blk.buf); |
if (line) |
if (ln.buf) |
free(line); |
free(ln.buf); |
if (outfree) |
if (outfree) |
(*outfree)(outdata); |
(*outfree)(outdata); |
|
|
|
|
|
|
|
|
static int |
static int |
file(char **ln, size_t *lnsz, char **buf, size_t *bufsz, |
file(struct buf *blk, struct buf *ln, |
const char *file, struct mdoc *mdoc) |
const char *file, struct mdoc *mdoc) |
{ |
{ |
int fd, c; |
int fd, c; |
Line 236 file(char **ln, size_t *lnsz, char **buf, size_t *bufs |
|
Line 247 file(char **ln, size_t *lnsz, char **buf, size_t *bufs |
|
return(0); |
return(0); |
} |
} |
|
|
c = fdesc(ln, lnsz, buf, bufsz, file, fd, mdoc); |
c = fdesc(blk, ln, file, fd, mdoc); |
|
|
if (-1 == close(fd)) |
if (-1 == close(fd)) |
warn("%s", file); |
warn("%s", file); |
Line 246 file(char **ln, size_t *lnsz, char **buf, size_t *bufs |
|
Line 257 file(char **ln, size_t *lnsz, char **buf, size_t *bufs |
|
|
|
|
|
static int |
static int |
fdesc(char **lnp, size_t *lnsz, char **bufp, size_t *bufsz, |
fdesc(struct buf *blk, struct buf *ln, |
const char *f, int fd, struct mdoc *mdoc) |
const char *f, int fd, struct mdoc *mdoc) |
{ |
{ |
size_t sz; |
size_t sz; |
ssize_t ssz; |
ssize_t ssz; |
struct stat st; |
struct stat st; |
int j, i, pos, lnn; |
int j, i, pos, lnn; |
char *ln, *buf; |
|
|
|
buf = *bufp; |
|
ln = *lnp; |
|
|
|
/* |
/* |
* Two buffers: ln and buf. buf is the input buffer, optimised |
* Two buffers: ln and buf. buf is the input buffer, optimised |
* for each file's block size. ln is a line buffer. Both |
* for each file's block size. ln is a line buffer. Both |
* growable, hence passed in by ptr-ptr. |
* growable, hence passed in by ptr-ptr. |
*/ |
*/ |
|
|
if (-1 == fstat(fd, &st)) { |
sz = BUFSIZ; |
|
|
|
if (-1 == fstat(fd, &st)) |
warnx("%s", f); |
warnx("%s", f); |
sz = BUFSIZ; |
else if ((size_t)st.st_blksize > sz) |
} else |
sz = st.st_blksize; |
sz = (unsigned)BUFSIZ > st.st_blksize ? |
|
(size_t)BUFSIZ : st.st_blksize; |
|
|
|
if (sz > *bufsz) { |
if (sz > blk->sz) { |
if (NULL == (buf = realloc(buf, sz))) |
blk->buf = realloc(blk->buf, sz); |
|
if (NULL == blk->buf) |
err(1, "realloc"); |
err(1, "realloc"); |
*bufp = buf; |
blk->sz = sz; |
*bufsz = sz; |
|
} |
} |
|
|
/* |
/* |
Line 283 fdesc(char **lnp, size_t *lnsz, char **bufp, size_t *b |
|
Line 290 fdesc(char **lnp, size_t *lnsz, char **bufp, size_t *b |
|
*/ |
*/ |
|
|
for (lnn = 1, pos = 0; ; ) { |
for (lnn = 1, pos = 0; ; ) { |
if (-1 == (ssz = read(fd, buf, sz))) { |
if (-1 == (ssz = read(fd, blk->buf, sz))) { |
warn("%s", f); |
warn("%s", f); |
return(0); |
return(0); |
} else if (0 == ssz) |
} else if (0 == ssz) |
break; |
break; |
|
|
for (i = 0; i < (int)ssz; i++) { |
for (i = 0; i < (int)ssz; i++) { |
if (pos >= (int)*lnsz) { |
if (pos >= (int)ln->sz) { |
*lnsz += 256; /* Step-size. */ |
ln->sz += 256; /* Step-size. */ |
ln = realloc(ln, *lnsz); |
ln->buf = realloc(ln->buf, ln->sz); |
if (NULL == ln) |
if (NULL == ln->buf) |
err(1, "realloc"); |
err(1, "realloc"); |
*lnp = ln; |
|
} |
} |
|
|
if ('\n' != buf[i]) { |
if ('\n' != blk->buf[i]) { |
ln[pos++] = buf[i]; |
ln->buf[pos++] = blk->buf[i]; |
continue; |
continue; |
} |
} |
|
|
/* Check for CPP-escaped newline. */ |
/* Check for CPP-escaped newline. */ |
|
|
if (pos > 0 && '\\' == ln[pos - 1]) { |
if (pos > 0 && '\\' == ln->buf[pos - 1]) { |
for (j = pos - 1; j >= 0; j--) |
for (j = pos - 1; j >= 0; j--) |
if ('\\' != ln[j]) |
if ('\\' != ln->buf[j]) |
break; |
break; |
|
|
if ( ! ((pos - j) % 2)) { |
if ( ! ((pos - j) % 2)) { |
Line 317 fdesc(char **lnp, size_t *lnsz, char **bufp, size_t *b |
|
Line 323 fdesc(char **lnp, size_t *lnsz, char **bufp, size_t *b |
|
} |
} |
} |
} |
|
|
ln[pos] = 0; |
ln->buf[pos] = 0; |
if ( ! mdoc_parseln(mdoc, lnn, ln)) |
if ( ! mdoc_parseln(mdoc, lnn, ln->buf)) |
return(0); |
return(0); |
lnn++; |
lnn++; |
pos = 0; |
pos = 0; |
Line 430 woptions(int *wflags, char *arg) |
|
Line 436 woptions(int *wflags, char *arg) |
|
static int |
static int |
merr(void *arg, int line, int col, const char *msg) |
merr(void *arg, int line, int col, const char *msg) |
{ |
{ |
|
struct curparse *curp; |
|
|
warnx("error: %s (line %d, column %d)", msg, line, col); |
curp = (struct curparse *)arg; |
|
|
|
warnx("%s:%d: error: %s (column %d)", |
|
curp->file, line, msg, col); |
return(0); |
return(0); |
} |
} |
|
|
|
|
mwarn(void *arg, int line, int col, |
mwarn(void *arg, int line, int col, |
enum mdoc_warn type, const char *msg) |
enum mdoc_warn type, const char *msg) |
{ |
{ |
int flags; |
struct curparse *curp; |
char *wtype; |
char *wtype; |
|
|
flags = *(int *)arg; |
curp = (struct curparse *)arg; |
wtype = NULL; |
wtype = NULL; |
|
|
switch (type) { |
switch (type) { |
case (WARN_COMPAT): |
case (WARN_COMPAT): |
wtype = "compat"; |
wtype = "compat"; |
if (flags & WARN_WCOMPAT) |
if (curp->wflags & WARN_WCOMPAT) |
break; |
break; |
return(1); |
return(1); |
case (WARN_SYNTAX): |
case (WARN_SYNTAX): |
wtype = "syntax"; |
wtype = "syntax"; |
if (flags & WARN_WSYNTAX) |
if (curp->wflags & WARN_WSYNTAX) |
break; |
break; |
return(1); |
return(1); |
} |
} |
|
|
assert(wtype); |
assert(wtype); |
warnx("%s warning: %s (line %d, column %d)", |
warnx("%s:%d: %s warning: %s (column %d)", |
wtype, msg, line, col); |
curp->file, line, wtype, msg, col); |
|
|
if ( ! (flags & WARN_WERR)) |
if ( ! (curp->wflags & WARN_WERR)) |
return(1); |
return(1); |
|
|
warnx("%s: considering warnings as errors", |
warnx("%s: considering warnings as errors", |