]> git.cameronkatri.com Git - mandoc.git/blob - mdocml.c
7f9142113ccd8afc7cbbfb683c5da0c0919ce2a7
[mandoc.git] / mdocml.c
1 /* $Id: mdocml.c,v 1.4 2008/11/22 18:34:06 kristaps Exp $ */
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
33 #define BUFFER_IN_DEF BUFSIZ
34 #define BUFFER_OUT_DEF BUFSIZ
35
36 static void usage(void);
37 static int begin_io(const char *, const char *);
38 static int leave_io(const struct md_mbuf *,
39 const struct md_rbuf *, int);
40 static int begin_bufs(struct md_mbuf *, struct md_rbuf *);
41 static int leave_bufs(const struct md_mbuf *,
42 const struct md_rbuf *, int);
43
44 int
45 main(int argc, char *argv[])
46 {
47 int c;
48 char *out, *in;
49
50 extern char *optarg;
51 extern int optind;
52
53 out = in = NULL;
54
55 while (-1 != (c = getopt(argc, argv, "o:")))
56 switch (c) {
57 case ('o'):
58 out = optarg;
59 break;
60 default:
61 usage();
62 return(1);
63 }
64
65 argv += optind;
66 argc -= optind;
67
68 if (1 == argc)
69 in = *argv++;
70
71 return(begin_io(out ? out : "-", in ? in : "-"));
72 }
73
74
75 static int
76 leave_io(const struct md_mbuf *out,
77 const struct md_rbuf *in, int c)
78 {
79 assert(out);
80 assert(in);
81
82 if (-1 != in->fd && -1 == close(in->fd)) {
83 assert(in->name);
84 warn("%s", in->name);
85 c = 1;
86 }
87 if (-1 != out->fd && STDOUT_FILENO != out->fd &&
88 -1 == close(out->fd)) {
89 assert(out->name);
90 warn("%s", out->name);
91 c = 1;
92 }
93
94 return(c);
95 }
96
97
98 static int
99 begin_io(const char *out, const char *in)
100 {
101 struct md_rbuf fi;
102 struct md_mbuf fo;
103
104 #define FI_FL O_RDONLY
105 #define FO_FL O_WRONLY|O_CREAT|O_TRUNC
106
107 assert(out);
108 assert(in);
109
110 bzero(&fi, sizeof(struct md_rbuf));
111 bzero(&fo, sizeof(struct md_mbuf));
112
113 fi.fd = STDIN_FILENO;
114 fo.fd = STDOUT_FILENO;
115
116 fi.name = in;
117 fo.name = out;
118
119 if (0 != strncmp(fi.name, "-", 1))
120 if (-1 == (fi.fd = open(fi.name, FI_FL, 0))) {
121 warn("%s", fi.name);
122 return(leave_io(&fo, &fi, 1));
123 }
124
125 if (0 != strncmp(fo.name, "-", 1))
126 if (-1 == (fo.fd = open(fo.name, FO_FL, 0644))) {
127 warn("%s", fo.name);
128 return(leave_io(&fo, &fi, 1));
129 }
130
131 return(leave_io(&fo, &fi, begin_bufs(&fo, &fi)));
132 }
133
134
135 static int
136 leave_bufs(const struct md_mbuf *out,
137 const struct md_rbuf *in, int c)
138 {
139 assert(out);
140 assert(in);
141 if (out->buf)
142 free(out->buf);
143 if (in->buf)
144 free(in->buf);
145 return(c);
146 }
147
148
149 static int
150 begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
151 {
152 struct stat stin, stout;
153
154 assert(in);
155 assert(out);
156
157 if (-1 == fstat(in->fd, &stin)) {
158 warn("%s", in->name);
159 return(1);
160 } else if (-1 == fstat(out->fd, &stout)) {
161 warn("%s", out->name);
162 return(1);
163 }
164
165 in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
166 out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
167
168 if (NULL == (in->buf = malloc(in->bufsz))) {
169 warn("malloc");
170 return(leave_bufs(out, in, 1));
171 } else if (NULL == (out->buf = malloc(out->bufsz))) {
172 warn("malloc");
173 return(leave_bufs(out, in, 1));
174 }
175
176 return(leave_bufs(out, in, md_run(MD_DUMMY, out, in)));
177 }
178
179
180 static void
181 usage(void)
182 {
183 extern char *__progname;
184
185 (void)printf("usage: %s [-o outfile] [infile]\n", __progname);
186 }