Annotation of mandoc/mdocml.c, Revision 1.16
1.16 ! kristaps 1: /* $Id: mdocml.c,v 1.15 2008/12/02 00:10:37 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
4: *
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
8: * copies.
9: *
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.
18: */
19: #include <sys/param.h>
20: #include <sys/stat.h>
21:
22: #include <assert.h>
23: #include <err.h>
24: #include <fcntl.h>
25: #include <getopt.h>
26: #include <stdio.h>
27: #include <stdlib.h>
28: #include <string.h>
29: #include <unistd.h>
30:
31: #include "libmdocml.h"
32:
1.9 kristaps 33: #define BUFFER_IN_DEF BUFSIZ /* See begin_bufs. */
34: #define BUFFER_OUT_DEF BUFSIZ /* See begin_bufs. */
1.2 kristaps 35:
1.9 kristaps 36: static void usage(void);
37:
38: static int begin_io(const struct md_args *,
1.5 kristaps 39: char *, char *);
1.9 kristaps 40: static int leave_io(const struct md_buf *,
1.5 kristaps 41: const struct md_buf *, int);
1.9 kristaps 42: static int begin_bufs(const struct md_args *,
1.5 kristaps 43: struct md_buf *, struct md_buf *);
44: static int leave_bufs(const struct md_buf *,
45: const struct md_buf *, int);
1.1 kristaps 46:
47: int
48: main(int argc, char *argv[])
49: {
50: int c;
1.16 ! kristaps 51: char *out, *in, *filter;
1.5 kristaps 52: struct md_args args;
1.1 kristaps 53:
54: extern char *optarg;
55: extern int optind;
56:
1.16 ! kristaps 57: out = in = filter = NULL;
1.10 kristaps 58:
59: (void)memset(&args, 0, sizeof(struct md_args));
1.1 kristaps 60:
1.16 ! kristaps 61: while (-1 != (c = getopt(argc, argv, "f:o:vW")))
1.1 kristaps 62: switch (c) {
1.16 ! kristaps 63: case ('f'):
! 64: filter = optarg;
! 65: break;
1.1 kristaps 66: case ('o'):
67: out = optarg;
68: break;
1.13 kristaps 69: case ('v'):
70: args.verbosity++;
71: break;
72: case ('W'):
73: args.warnings |= MD_WARN_ALL;
74: break;
1.1 kristaps 75: default:
76: usage();
77: return(1);
78: }
79:
80: argv += optind;
1.4 kristaps 81: argc -= optind;
1.1 kristaps 82:
1.4 kristaps 83: if (1 == argc)
84: in = *argv++;
1.1 kristaps 85:
1.16 ! kristaps 86: if (filter) {
! 87: if (0 == strcmp(filter, "html"))
! 88: args.type = MD_HTML;
! 89: else if (0 == strcmp(filter, "xml"))
! 90: args.type = MD_XML;
! 91: else
! 92: errx(1, "invalid filter type");
! 93: } else
! 94: args.type = MD_XML;
! 95:
1.5 kristaps 96: return(begin_io(&args, out ? out : "-", in ? in : "-"));
1.1 kristaps 97: }
98:
99:
1.9 kristaps 100: /*
101: * Close out file descriptors opened in begin_io. If the descriptor
102: * refers to stdin/stdout, then do nothing.
103: */
1.1 kristaps 104: static int
1.5 kristaps 105: leave_io(const struct md_buf *out,
106: const struct md_buf *in, int c)
1.1 kristaps 107: {
1.4 kristaps 108: assert(out);
1.1 kristaps 109: assert(in);
110:
1.4 kristaps 111: if (-1 != in->fd && -1 == close(in->fd)) {
112: assert(in->name);
113: warn("%s", in->name);
114: c = 1;
115: }
116: if (-1 != out->fd && STDOUT_FILENO != out->fd &&
117: -1 == close(out->fd)) {
118: assert(out->name);
119: warn("%s", out->name);
120: c = 1;
121: }
1.15 kristaps 122: if (1 == c && STDOUT_FILENO != out->fd)
123: if (-1 == unlink(out->name))
124: warn("%s", out->name);
1.1 kristaps 125:
1.4 kristaps 126: return(c);
1.1 kristaps 127: }
128:
129:
1.9 kristaps 130: /*
131: * Open file descriptors or assign stdin/stdout, if dictated by the "-"
132: * token instead of a filename.
133: */
1.1 kristaps 134: static int
1.5 kristaps 135: begin_io(const struct md_args *args, char *out, char *in)
1.1 kristaps 136: {
1.5 kristaps 137: struct md_buf fi;
138: struct md_buf fo;
1.4 kristaps 139:
140: #define FI_FL O_RDONLY
141: #define FO_FL O_WRONLY|O_CREAT|O_TRUNC
1.1 kristaps 142:
1.5 kristaps 143: assert(args);
1.1 kristaps 144: assert(out);
145: assert(in);
146:
1.5 kristaps 147: bzero(&fi, sizeof(struct md_buf));
148: bzero(&fo, sizeof(struct md_buf));
1.1 kristaps 149:
1.4 kristaps 150: fi.fd = STDIN_FILENO;
151: fo.fd = STDOUT_FILENO;
1.1 kristaps 152:
1.4 kristaps 153: fi.name = in;
154: fo.name = out;
1.1 kristaps 155:
1.4 kristaps 156: if (0 != strncmp(fi.name, "-", 1))
157: if (-1 == (fi.fd = open(fi.name, FI_FL, 0))) {
158: warn("%s", fi.name);
159: return(leave_io(&fo, &fi, 1));
160: }
1.1 kristaps 161:
1.4 kristaps 162: if (0 != strncmp(fo.name, "-", 1))
163: if (-1 == (fo.fd = open(fo.name, FO_FL, 0644))) {
164: warn("%s", fo.name);
165: return(leave_io(&fo, &fi, 1));
166: }
1.1 kristaps 167:
1.5 kristaps 168: return(leave_io(&fo, &fi, begin_bufs(args, &fo, &fi)));
1.4 kristaps 169: }
1.1 kristaps 170:
171:
1.9 kristaps 172: /*
173: * Free buffers allocated in begin_bufs.
174: */
1.4 kristaps 175: static int
1.5 kristaps 176: leave_bufs(const struct md_buf *out,
177: const struct md_buf *in, int c)
1.4 kristaps 178: {
179: assert(out);
180: assert(in);
181: if (out->buf)
182: free(out->buf);
183: if (in->buf)
184: free(in->buf);
1.1 kristaps 185: return(c);
186: }
187:
188:
1.9 kristaps 189: /*
190: * Allocate buffers to the maximum of either the input file's blocksize
191: * or BUFFER_IN_DEF/BUFFER_OUT_DEF, which should be around BUFSIZE.
192: */
1.1 kristaps 193: static int
1.5 kristaps 194: begin_bufs(const struct md_args *args,
195: struct md_buf *out, struct md_buf *in)
1.1 kristaps 196: {
197: struct stat stin, stout;
1.5 kristaps 198: int c;
1.1 kristaps 199:
1.5 kristaps 200: assert(args);
1.1 kristaps 201: assert(in);
202: assert(out);
203:
204: if (-1 == fstat(in->fd, &stin)) {
1.3 kristaps 205: warn("%s", in->name);
1.1 kristaps 206: return(1);
1.12 kristaps 207: } else if (STDIN_FILENO != in->fd && 0 == stin.st_size) {
1.8 kristaps 208: warnx("%s: empty file", in->name);
209: return(1);
1.1 kristaps 210: } else if (-1 == fstat(out->fd, &stout)) {
1.3 kristaps 211: warn("%s", out->name);
1.1 kristaps 212: return(1);
213: }
214:
1.3 kristaps 215: in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
216: out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
1.1 kristaps 217:
1.3 kristaps 218: if (NULL == (in->buf = malloc(in->bufsz))) {
1.1 kristaps 219: warn("malloc");
1.4 kristaps 220: return(leave_bufs(out, in, 1));
1.3 kristaps 221: } else if (NULL == (out->buf = malloc(out->bufsz))) {
1.1 kristaps 222: warn("malloc");
1.4 kristaps 223: return(leave_bufs(out, in, 1));
1.1 kristaps 224: }
225:
1.5 kristaps 226: c = md_run(args, out, in);
227: return(leave_bufs(out, in, -1 == c ? 1 : 0));
1.1 kristaps 228: }
229:
230:
231: static void
232: usage(void)
233: {
234: extern char *__progname;
235:
1.16 ! kristaps 236: (void)printf("usage: %s [-vW] [-f filter] [-o outfile] "
! 237: "[infile]\n", __progname);
1.1 kristaps 238: }
CVSweb