1363da138SBaptiste Daroussin /*-
2363da138SBaptiste Daroussin * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
3363da138SBaptiste Daroussin * All rights reserved.
4363da138SBaptiste Daroussin *
5363da138SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without
6363da138SBaptiste Daroussin * modification, are permitted provided that the following conditions
7363da138SBaptiste Daroussin * are met:
8363da138SBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright
9363da138SBaptiste Daroussin * notice, this list of conditions and the following disclaimer
10363da138SBaptiste Daroussin * in this position and unchanged.
11363da138SBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright
12363da138SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the
13363da138SBaptiste Daroussin * documentation and/or other materials provided with the distribution.
14363da138SBaptiste Daroussin *
15363da138SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16363da138SBaptiste Daroussin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17363da138SBaptiste Daroussin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18363da138SBaptiste Daroussin * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19363da138SBaptiste Daroussin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20363da138SBaptiste Daroussin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21363da138SBaptiste Daroussin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22363da138SBaptiste Daroussin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23363da138SBaptiste Daroussin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24363da138SBaptiste Daroussin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25363da138SBaptiste Daroussin */
26363da138SBaptiste Daroussin
27b704d1f2SBaptiste Daroussin #include <sys/types.h>
28b704d1f2SBaptiste Daroussin
290330f102SBaptiste Daroussin #include <ctype.h>
300330f102SBaptiste Daroussin #include <err.h>
3146cc6349SBaptiste Daroussin #include <limits.h>
32363da138SBaptiste Daroussin #include <stdio.h>
33363da138SBaptiste Daroussin #include <stdlib.h>
34363da138SBaptiste Daroussin #include <string.h>
35363da138SBaptiste Daroussin #include <stringlist.h>
360330f102SBaptiste Daroussin #include <unistd.h>
37363da138SBaptiste Daroussin
38b4a0618cSBaptiste Daroussin #define C_OPTION 0x1
39b4a0618cSBaptiste Daroussin
40363da138SBaptiste Daroussin static StringList *includes;
41363da138SBaptiste Daroussin
42363da138SBaptiste Daroussin static void
usage(void)43363da138SBaptiste Daroussin usage(void)
44363da138SBaptiste Daroussin {
45363da138SBaptiste Daroussin
46363da138SBaptiste Daroussin fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n");
47363da138SBaptiste Daroussin
48363da138SBaptiste Daroussin exit(EXIT_FAILURE);
49363da138SBaptiste Daroussin }
50363da138SBaptiste Daroussin
51224d9e3eSBaptiste Daroussin static FILE *
soelim_fopen(const char * name)52*3ba0c990SBaptiste Daroussin soelim_fopen(const char *name)
53224d9e3eSBaptiste Daroussin {
54*3ba0c990SBaptiste Daroussin FILE *f;
5546cc6349SBaptiste Daroussin char path[PATH_MAX];
56363da138SBaptiste Daroussin size_t i;
57363da138SBaptiste Daroussin
586f32f49cSXin LI if (strcmp(name, "-") == 0)
596f32f49cSXin LI return (stdin);
606f32f49cSXin LI
61*3ba0c990SBaptiste Daroussin if ((f = fopen(name, "r")) != NULL)
62*3ba0c990SBaptiste Daroussin return (f);
63363da138SBaptiste Daroussin
64363da138SBaptiste Daroussin if (*name == '/') {
65363da138SBaptiste Daroussin warn("can't open '%s'", name);
66363da138SBaptiste Daroussin return (NULL);
67363da138SBaptiste Daroussin }
68363da138SBaptiste Daroussin
69363da138SBaptiste Daroussin for (i = 0; i < includes->sl_cur; i++) {
70363da138SBaptiste Daroussin snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i],
71363da138SBaptiste Daroussin name);
72*3ba0c990SBaptiste Daroussin if ((f = fopen(path, "r")) != NULL)
73*3ba0c990SBaptiste Daroussin return (f);
74363da138SBaptiste Daroussin }
75363da138SBaptiste Daroussin
76363da138SBaptiste Daroussin warn("can't open '%s'", name);
77363da138SBaptiste Daroussin
78160af931SBaptiste Daroussin return (f);
79363da138SBaptiste Daroussin }
80363da138SBaptiste Daroussin
81363da138SBaptiste Daroussin static int
soelim_file(FILE * f,int flag)82*3ba0c990SBaptiste Daroussin soelim_file(FILE *f, int flag)
83363da138SBaptiste Daroussin {
84363da138SBaptiste Daroussin char *line = NULL;
85b4a0618cSBaptiste Daroussin char *walk, *cp;
86363da138SBaptiste Daroussin size_t linecap = 0;
87363da138SBaptiste Daroussin ssize_t linelen;
88363da138SBaptiste Daroussin
89363da138SBaptiste Daroussin if (f == NULL)
90363da138SBaptiste Daroussin return (1);
91363da138SBaptiste Daroussin
92363da138SBaptiste Daroussin while ((linelen = getline(&line, &linecap, f)) > 0) {
93363da138SBaptiste Daroussin if (strncmp(line, ".so", 3) != 0) {
94363da138SBaptiste Daroussin printf("%s", line);
95363da138SBaptiste Daroussin continue;
96363da138SBaptiste Daroussin }
97b4a0618cSBaptiste Daroussin
98363da138SBaptiste Daroussin walk = line + 3;
99b4a0618cSBaptiste Daroussin if (!isspace(*walk) && ((flag & C_OPTION) == 0)) {
100b4a0618cSBaptiste Daroussin printf("%s", line);
101b4a0618cSBaptiste Daroussin continue;
102b4a0618cSBaptiste Daroussin }
103b4a0618cSBaptiste Daroussin
104363da138SBaptiste Daroussin while (isspace(*walk))
105363da138SBaptiste Daroussin walk++;
106363da138SBaptiste Daroussin
1072b30fb26SBaptiste Daroussin cp = walk;
1082b30fb26SBaptiste Daroussin while (*cp != '\0' && !isspace(*cp))
1092b30fb26SBaptiste Daroussin cp++;
110b4a0618cSBaptiste Daroussin *cp = 0;
1112b30fb26SBaptiste Daroussin if (cp < line + linelen)
1122b30fb26SBaptiste Daroussin cp++;
113b4a0618cSBaptiste Daroussin
114b4a0618cSBaptiste Daroussin if (*walk == '\0') {
115b4a0618cSBaptiste Daroussin printf("%s", line);
116b4a0618cSBaptiste Daroussin continue;
117b4a0618cSBaptiste Daroussin }
118*3ba0c990SBaptiste Daroussin if (soelim_file(soelim_fopen(walk), flag) == 1) {
119363da138SBaptiste Daroussin free(line);
120363da138SBaptiste Daroussin return (1);
121363da138SBaptiste Daroussin }
1222b30fb26SBaptiste Daroussin if (*cp != '\0')
1232b30fb26SBaptiste Daroussin printf("%s", cp);
124363da138SBaptiste Daroussin }
125363da138SBaptiste Daroussin
126363da138SBaptiste Daroussin free(line);
127363da138SBaptiste Daroussin fclose(f);
128363da138SBaptiste Daroussin
129363da138SBaptiste Daroussin return (0);
130363da138SBaptiste Daroussin }
131363da138SBaptiste Daroussin
132363da138SBaptiste Daroussin int
main(int argc,char ** argv)133363da138SBaptiste Daroussin main(int argc, char **argv)
134363da138SBaptiste Daroussin {
135*3ba0c990SBaptiste Daroussin int ch, i;
136363da138SBaptiste Daroussin int ret = 0;
137b4a0618cSBaptiste Daroussin int flags = 0;
138363da138SBaptiste Daroussin
139363da138SBaptiste Daroussin includes = sl_init();
140363da138SBaptiste Daroussin if (includes == NULL)
141363da138SBaptiste Daroussin err(EXIT_FAILURE, "sl_init()");
142363da138SBaptiste Daroussin
143363da138SBaptiste Daroussin while ((ch = getopt(argc, argv, "CrtvI:")) != -1) {
144363da138SBaptiste Daroussin switch (ch) {
145363da138SBaptiste Daroussin case 'C':
146b4a0618cSBaptiste Daroussin flags |= C_OPTION;
147b4a0618cSBaptiste Daroussin break;
148363da138SBaptiste Daroussin case 'r':
149363da138SBaptiste Daroussin case 'v':
150363da138SBaptiste Daroussin case 't':
151363da138SBaptiste Daroussin /* stub compatibility with groff's soelim */
152363da138SBaptiste Daroussin break;
153363da138SBaptiste Daroussin case 'I':
154363da138SBaptiste Daroussin sl_add(includes, optarg);
155363da138SBaptiste Daroussin break;
156363da138SBaptiste Daroussin default:
157363da138SBaptiste Daroussin sl_free(includes, 0);
158363da138SBaptiste Daroussin usage();
159363da138SBaptiste Daroussin }
160363da138SBaptiste Daroussin }
161363da138SBaptiste Daroussin
162363da138SBaptiste Daroussin argc -= optind;
163363da138SBaptiste Daroussin argv += optind;
164363da138SBaptiste Daroussin
165363da138SBaptiste Daroussin if (argc == 0)
166*3ba0c990SBaptiste Daroussin ret = soelim_file(stdin, flags);
167363da138SBaptiste Daroussin
168363da138SBaptiste Daroussin for (i = 0; i < argc; i++)
169*3ba0c990SBaptiste Daroussin ret = soelim_file(soelim_fopen(argv[i]), flags);
170363da138SBaptiste Daroussin
171363da138SBaptiste Daroussin sl_free(includes, 0);
172363da138SBaptiste Daroussin
173363da138SBaptiste Daroussin return (ret);
174363da138SBaptiste Daroussin }
175