]>
git.cameronkatri.com Git - mandoc.git/blob - mdocml.c
1 /* $Id: mdocml.c,v 1.46 2009/01/16 14:15:12 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/param.h>
33 #define xfprintf (void)fprintf
34 #define xprintf (void)printf
35 #define xvfprintf (void)fvprintf
37 #define MD_LINE_SZ (256) /* Max input line size. */
40 int warn
; /* Warning flags. */
41 #define MD_WARN_SYNTAX (1 << 0) /* Show syntax warnings. */
42 #define MD_WARN_COMPAT (1 << 1) /* Show compat warnings. */
43 #define MD_WARN_ALL (0x03) /* Show all warnings. */
44 #define MD_WARN_ERR (1 << 2) /* Make warnings->errors. */
45 int dbg
; /* Debug level. */
46 struct mdoc
*mdoc
; /* Active parser. */
47 char *buf
; /* Input buffer. */
48 u_long bufsz
; /* Input buffer size. */
49 char *name
; /* Input file name. */
50 int fd
; /* Input file desc. */
53 extern char *__progname
;
55 static void usage(void);
57 static int parse_begin(struct md_parse
*);
58 static int parse_leave(struct md_parse
*, int);
59 static int io_begin(struct md_parse
*);
60 static int io_leave(struct md_parse
*, int);
61 static int buf_begin(struct md_parse
*);
62 static int buf_leave(struct md_parse
*, int);
64 static void msg_msg(void *, int, int, const char *);
65 static int msg_err(void *, int, int, const char *);
66 static int msg_warn(void *, int, int,
67 enum mdoc_warn
, const char *);
70 extern int getsubopt(char **, char *const *, char **);
74 main(int argc
, char *argv
[])
77 struct md_parse parser
;
83 char *toks
[] = { "all", "compat", "syntax",
89 (void)memset(&parser
, 0, sizeof(struct md_parse
));
91 while (-1 != (c
= getopt(argc
, argv
, "vW:")))
99 switch (getsubopt(&opts
, toks
, &v
)) {
101 parser
.warn
|= MD_WARN_ALL
;
104 parser
.warn
|= MD_WARN_COMPAT
;
107 parser
.warn
|= MD_WARN_SYNTAX
;
110 parser
.warn
|= MD_WARN_ERR
;
127 parser
.name
= *argv
++;
129 if ( ! io_begin(&parser
))
130 return(EXIT_FAILURE
);
132 return(EXIT_SUCCESS
);
137 io_leave(struct md_parse
*p
, int code
)
140 if (-1 == p
->fd
|| STDIN_FILENO
== p
->fd
)
143 if (-1 == close(p
->fd
)) {
152 io_begin(struct md_parse
*p
)
155 p
->fd
= STDIN_FILENO
;
156 if (0 != strncmp(p
->name
, "-", 1))
157 if (-1 == (p
->fd
= open(p
->name
, O_RDONLY
, 0))) {
159 return(io_leave(p
, 0));
162 return(io_leave(p
, buf_begin(p
)));
167 buf_leave(struct md_parse
*p
, int code
)
177 buf_begin(struct md_parse
*p
)
181 if (-1 == fstat(p
->fd
, &st
)) {
186 p
->bufsz
= MAX(st
.st_blksize
, BUFSIZ
);
188 if (NULL
== (p
->buf
= malloc(p
->bufsz
))) {
190 return(buf_leave(p
, 0));
193 return(buf_leave(p
, parse_begin(p
)));
197 /* TODO: remove this to a print-tree output filter. */
199 print_node(const struct mdoc_node
*n
, int indent
)
205 struct mdoc_arg
*argv
;
211 t
= mdoc_type2a(n
->type
);
215 p
= n
->data
.text
.string
;
218 p
= mdoc_macronames
[n
->tok
];
221 p
= mdoc_macronames
[n
->tok
];
224 p
= mdoc_macronames
[n
->tok
];
227 p
= mdoc_macronames
[n
->tok
];
228 argv
= n
->data
.elem
.argv
;
229 argc
= n
->data
.elem
.argc
;
232 p
= mdoc_macronames
[n
->tok
];
233 argv
= n
->data
.block
.argv
;
234 argc
= n
->data
.block
.argc
;
244 for (i
= 0; i
< indent
; i
++)
246 xprintf("%s (%s)", p
, t
);
248 for (i
= 0; i
< (int)argc
; i
++) {
249 xprintf(" -%s", mdoc_argnames
[argv
[i
].arg
]);
252 for (j
= 0; j
< (int)argv
[i
].sz
; j
++)
253 xprintf(" [%s]", argv
[i
].value
[j
]);
258 for (i
= 0; i
< (int)sz
; i
++)
259 xprintf(" [%s]", params
[i
]);
261 xprintf(" %d:%d\n", n
->line
, n
->pos
);
264 print_node(n
->child
, indent
+ 1);
266 print_node(n
->next
, indent
);
271 parse_leave(struct md_parse
*p
, int code
)
273 const struct mdoc_node
*n
;
278 if ( ! mdoc_endparse(p
->mdoc
))
280 if ((n
= mdoc_result(p
->mdoc
)))
290 parse_begin(struct md_parse
*p
)
294 char line
[MD_LINE_SZ
];
298 cb
.mdoc_err
= msg_err
;
299 cb
.mdoc_warn
= msg_warn
;
300 cb
.mdoc_msg
= msg_msg
;
302 if (NULL
== (p
->mdoc
= mdoc_alloc(p
, &cb
)))
303 return(parse_leave(p
, 0));
305 for (lnn
= 1, pos
= 0; ; ) {
306 if (-1 == (sz
= read(p
->fd
, p
->buf
, p
->bufsz
))) {
308 return(parse_leave(p
, 0));
312 for (i
= 0; i
< sz
; i
++) {
313 if ('\n' != p
->buf
[i
]) {
314 if (pos
< sizeof(line
)) {
315 line
[(int)pos
++] = p
->buf
[(int)i
];
318 warnx("%s: line %d too long",
320 return(parse_leave(p
, 0));
324 if ( ! mdoc_parseln(p
->mdoc
, lnn
, line
))
325 return(parse_leave(p
, 0));
332 return(parse_leave(p
, 1));
337 msg_err(void *arg
, int line
, int col
, const char *msg
)
341 p
= (struct md_parse
*)arg
;
343 xfprintf(stderr
, "%s:%d: error: %s (column %d)\n",
344 p
->name
, line
, msg
, col
);
350 msg_msg(void *arg
, int line
, int col
, const char *msg
)
354 p
= (struct md_parse
*)arg
;
359 xfprintf(stderr
, "%s:%d: debug: %s (column %d)\n",
360 p
->name
, line
, msg
, col
);
365 msg_warn(void *arg
, int line
, int col
,
366 enum mdoc_warn type
, const char *msg
)
370 p
= (struct md_parse
*)arg
;
374 if (p
->warn
& MD_WARN_COMPAT
)
378 if (p
->warn
& MD_WARN_SYNTAX
)
383 xfprintf(stderr
, "%s:%d: warning: %s (column %d)\n",
384 p
->name
, line
, msg
, col
);
386 if ( ! (p
->warn
& MD_WARN_ERR
))
389 xfprintf(stderr
, "%s: considering warnings as errors\n",
399 xfprintf(stderr
, "usage: %s [-v] [-Wwarn...] [infile]\n",