Annotation of mandoc/soelim.c, Revision 1.5
1.5 ! schwarze 1: /* $Id: soelim.c,v 1.4 2015/05/21 00:18:52 schwarze Exp $ */
1.2 schwarze 2: /*
1.1 schwarze 3: * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer
11: * in this position and unchanged.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: */
1.4 schwarze 27: #include "config.h"
1.1 schwarze 28:
1.2 schwarze 29: #include <sys/types.h>
1.1 schwarze 30:
1.2 schwarze 31: #include <ctype.h>
1.5 ! schwarze 32: #if HAVE_ERR
1.2 schwarze 33: #include <err.h>
1.5 ! schwarze 34: #endif
1.3 schwarze 35: #include <limits.h>
1.1 schwarze 36: #include <stdio.h>
37: #include <stdlib.h>
38: #include <string.h>
1.2 schwarze 39: #if HAVE_STRINGLIST
1.1 schwarze 40: #include <stringlist.h>
1.2 schwarze 41: #else
42: #include "compat_stringlist.h"
43: #endif
44: #include <unistd.h>
1.1 schwarze 45:
46: #define C_OPTION 0x1
47:
48: static StringList *includes;
49:
50: static void
51: usage(void)
52: {
53:
54: fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n");
55:
56: exit(EXIT_FAILURE);
57: }
58:
59: static FILE *
60: soelim_fopen(const char *name)
61: {
62: FILE *f;
1.3 schwarze 63: char path[PATH_MAX];
1.1 schwarze 64: size_t i;
65:
66: if (strcmp(name, "-") == 0)
67: return (stdin);
68:
69: if ((f = fopen(name, "r")) != NULL)
70: return (f);
71:
72: if (*name == '/') {
73: warn("can't open '%s'", name);
74: return (NULL);
75: }
76:
77: for (i = 0; i < includes->sl_cur; i++) {
78: snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i],
79: name);
80: if ((f = fopen(path, "r")) != NULL)
81: return (f);
82: }
83:
84: warn("can't open '%s'", name);
85:
86: return (f);
87: }
88:
89: static int
90: soelim_file(FILE *f, int flag)
91: {
92: char *line = NULL;
93: char *walk, *cp;
94: size_t linecap = 0;
95: ssize_t linelen;
96:
97: if (f == NULL)
98: return (1);
99:
100: while ((linelen = getline(&line, &linecap, f)) > 0) {
101: if (strncmp(line, ".so", 3) != 0) {
102: printf("%s", line);
103: continue;
104: }
105:
106: walk = line + 3;
107: if (!isspace(*walk) && ((flag & C_OPTION) == 0)) {
108: printf("%s", line);
109: continue;
110: }
111:
112: while (isspace(*walk))
113: walk++;
114:
115: cp = walk;
116: while (*cp != '\0' && !isspace(*cp))
117: cp++;
118: *cp = 0;
119: if (cp < line + linelen)
120: cp++;
121:
122: if (*walk == '\0') {
123: printf("%s", line);
124: continue;
125: }
126: if (soelim_file(soelim_fopen(walk), flag) == 1) {
127: free(line);
128: return (1);
129: }
130: if (*cp != '\0')
131: printf("%s", cp);
132: }
133:
134: free(line);
135: fclose(f);
136:
137: return (0);
138: }
139:
140: int
141: main(int argc, char **argv)
142: {
143: int ch, i;
144: int ret = 0;
145: int flags = 0;
146:
147: includes = sl_init();
148: if (includes == NULL)
149: err(EXIT_FAILURE, "sl_init()");
150:
151: while ((ch = getopt(argc, argv, "CrtvI:")) != -1) {
152: switch (ch) {
153: case 'C':
154: flags |= C_OPTION;
155: break;
156: case 'r':
157: case 'v':
158: case 't':
159: /* stub compatibility with groff's soelim */
160: break;
161: case 'I':
162: sl_add(includes, optarg);
163: break;
164: default:
165: sl_free(includes, 0);
166: usage();
167: }
168: }
169:
170: argc -= optind;
171: argv += optind;
172:
173: if (argc == 0)
174: ret = soelim_file(stdin, flags);
175:
176: for (i = 0; i < argc; i++)
177: ret = soelim_file(soelim_fopen(argv[i]), flags);
178:
179: sl_free(includes, 0);
180:
181: return (ret);
182: }
CVSweb