Annotation of mandoc/mdocml.c, Revision 1.9
1.9 ! kristaps 1: /* $Id: mdocml.c,v 1.8 2008/11/23 22:30:53 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;
51: char *out, *in;
1.5 kristaps 52: struct md_args args;
1.1 kristaps 53:
54: extern char *optarg;
55: extern int optind;
56:
1.4 kristaps 57: out = in = NULL;
1.1 kristaps 58:
1.9 ! kristaps 59: while (-1 != (c = getopt(argc, argv, "vo:")))
1.1 kristaps 60: switch (c) {
61: case ('o'):
62: out = optarg;
63: break;
1.9 ! kristaps 64: case ('v'):
! 65: args.dbg++;
! 66: break;
1.1 kristaps 67: default:
68: usage();
69: return(1);
70: }
71:
72: argv += optind;
1.4 kristaps 73: argc -= optind;
1.1 kristaps 74:
1.4 kristaps 75: if (1 == argc)
76: in = *argv++;
1.1 kristaps 77:
1.6 kristaps 78: args.type = MD_HTML4_STRICT;
1.5 kristaps 79:
80: return(begin_io(&args, out ? out : "-", in ? in : "-"));
1.1 kristaps 81: }
82:
83:
1.9 ! kristaps 84: /*
! 85: * Close out file descriptors opened in begin_io. If the descriptor
! 86: * refers to stdin/stdout, then do nothing.
! 87: */
1.1 kristaps 88: static int
1.5 kristaps 89: leave_io(const struct md_buf *out,
90: const struct md_buf *in, int c)
1.1 kristaps 91: {
1.4 kristaps 92: assert(out);
1.1 kristaps 93: assert(in);
94:
1.4 kristaps 95: if (-1 != in->fd && -1 == close(in->fd)) {
96: assert(in->name);
97: warn("%s", in->name);
98: c = 1;
99: }
100: if (-1 != out->fd && STDOUT_FILENO != out->fd &&
101: -1 == close(out->fd)) {
102: assert(out->name);
103: warn("%s", out->name);
104: c = 1;
105: }
1.1 kristaps 106:
1.4 kristaps 107: return(c);
1.1 kristaps 108: }
109:
110:
1.9 ! kristaps 111: /*
! 112: * Open file descriptors or assign stdin/stdout, if dictated by the "-"
! 113: * token instead of a filename.
! 114: */
1.1 kristaps 115: static int
1.5 kristaps 116: begin_io(const struct md_args *args, char *out, char *in)
1.1 kristaps 117: {
1.5 kristaps 118: struct md_buf fi;
119: struct md_buf fo;
1.4 kristaps 120:
121: #define FI_FL O_RDONLY
122: #define FO_FL O_WRONLY|O_CREAT|O_TRUNC
1.1 kristaps 123:
1.5 kristaps 124: assert(args);
1.1 kristaps 125: assert(out);
126: assert(in);
127:
1.5 kristaps 128: bzero(&fi, sizeof(struct md_buf));
129: bzero(&fo, sizeof(struct md_buf));
1.1 kristaps 130:
1.4 kristaps 131: fi.fd = STDIN_FILENO;
132: fo.fd = STDOUT_FILENO;
1.1 kristaps 133:
1.4 kristaps 134: fi.name = in;
135: fo.name = out;
1.1 kristaps 136:
1.4 kristaps 137: if (0 != strncmp(fi.name, "-", 1))
138: if (-1 == (fi.fd = open(fi.name, FI_FL, 0))) {
139: warn("%s", fi.name);
140: return(leave_io(&fo, &fi, 1));
141: }
1.1 kristaps 142:
1.4 kristaps 143: if (0 != strncmp(fo.name, "-", 1))
144: if (-1 == (fo.fd = open(fo.name, FO_FL, 0644))) {
145: warn("%s", fo.name);
146: return(leave_io(&fo, &fi, 1));
147: }
1.1 kristaps 148:
1.5 kristaps 149: return(leave_io(&fo, &fi, begin_bufs(args, &fo, &fi)));
1.4 kristaps 150: }
1.1 kristaps 151:
152:
1.9 ! kristaps 153: /*
! 154: * Free buffers allocated in begin_bufs.
! 155: */
1.4 kristaps 156: static int
1.5 kristaps 157: leave_bufs(const struct md_buf *out,
158: const struct md_buf *in, int c)
1.4 kristaps 159: {
160: assert(out);
161: assert(in);
162: if (out->buf)
163: free(out->buf);
164: if (in->buf)
165: free(in->buf);
1.1 kristaps 166: return(c);
167: }
168:
169:
1.9 ! kristaps 170: /*
! 171: * Allocate buffers to the maximum of either the input file's blocksize
! 172: * or BUFFER_IN_DEF/BUFFER_OUT_DEF, which should be around BUFSIZE.
! 173: */
1.1 kristaps 174: static int
1.5 kristaps 175: begin_bufs(const struct md_args *args,
176: struct md_buf *out, struct md_buf *in)
1.1 kristaps 177: {
178: struct stat stin, stout;
1.5 kristaps 179: int c;
1.1 kristaps 180:
1.5 kristaps 181: assert(args);
1.1 kristaps 182: assert(in);
183: assert(out);
184:
185: if (-1 == fstat(in->fd, &stin)) {
1.3 kristaps 186: warn("%s", in->name);
1.1 kristaps 187: return(1);
1.8 kristaps 188: } else if (0 == stin.st_size) {
189: warnx("%s: empty file", in->name);
190: return(1);
1.1 kristaps 191: } else if (-1 == fstat(out->fd, &stout)) {
1.3 kristaps 192: warn("%s", out->name);
1.1 kristaps 193: return(1);
194: }
195:
1.3 kristaps 196: in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
197: out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
1.1 kristaps 198:
1.3 kristaps 199: if (NULL == (in->buf = malloc(in->bufsz))) {
1.1 kristaps 200: warn("malloc");
1.4 kristaps 201: return(leave_bufs(out, in, 1));
1.3 kristaps 202: } else if (NULL == (out->buf = malloc(out->bufsz))) {
1.1 kristaps 203: warn("malloc");
1.4 kristaps 204: return(leave_bufs(out, in, 1));
1.1 kristaps 205: }
206:
1.5 kristaps 207: c = md_run(args, out, in);
208: return(leave_bufs(out, in, -1 == c ? 1 : 0));
1.1 kristaps 209: }
210:
211:
212: static void
213: usage(void)
214: {
215: extern char *__progname;
216:
1.9 ! kristaps 217: (void)printf("usage: %s [-v] [-o outfile] [infile]\n",
! 218: __progname);
1.1 kristaps 219: }
CVSweb