2 /* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 #include "stringclass.h"
32 static size_t include_list_length;
33 static char **include_list;
35 int compatible_flag = 0;
37 extern int interpret_lf_args(const char *);
38 extern "C" const char *Version_string;
40 int do_file(const char *filename);
44 include_path_append(char *path)
46 ++include_list_length;
47 size_t nbytes = include_list_length * sizeof(char *);
49 include_list = (char **)realloc((void *)include_list, nbytes);
51 include_list = (char **)malloc(nbytes);
52 if (include_list == NULL)
54 fprintf(stderr, "%s: out of memory\n", program_name);
57 include_list[include_list_length - 1] = path;
61 void usage(FILE *stream)
63 fprintf(stream, "usage: %s [ -vC ] [ -I file ] [ files ]\n", program_name);
66 int main(int argc, char **argv)
68 program_name = argv[0];
69 include_path_append(".");
71 static const struct option long_options[] = {
72 { "help", no_argument, 0, CHAR_MAX + 1 },
73 { "version", no_argument, 0, 'v' },
76 while ((opt = getopt_long(argc, argv, "CI:v", long_options, NULL)) != EOF)
80 printf("GNU soelim (groff) version %s\n", Version_string);
88 include_path_append(optarg);
90 case CHAR_MAX + 1: // --help
103 nbad += !do_file("-");
105 for (int i = optind; i < argc; i++)
106 nbad += !do_file(argv[i]);
107 if (ferror(stdout) || fflush(stdout) < 0)
108 fatal("output error");
114 printf(".lf %d %s\n", current_lineno, current_filename);
117 void do_so(const char *line)
119 const char *p = line;
124 for (const char *q = p;
125 success && *q != '\0' && *q != '\n' && *q != ' ';
142 filename += char(*q);
143 if (success && filename.length() > 0) {
145 const char *fn = current_filename;
146 int ln = current_lineno;
148 if (do_file(filename.contents())) {
149 current_filename = fn;
156 fputs(".so", stdout);
160 int do_file(const char *filename)
163 string whole_filename;
164 if (strcmp(filename, "-") == 0) {
166 whole_filename = filename;
167 whole_filename += '\0';
169 else if (IS_ABSOLUTE(filename)) {
170 whole_filename = filename;
171 whole_filename += '\0';
173 fp = fopen(filename, "r");
175 error("can't open `%1': %2", filename, strerror(errno));
181 for (j = 0; j < include_list_length; ++j)
183 char *path = include_list[j];
184 if (0 == strcmp(path, "."))
185 whole_filename = filename;
187 whole_filename = string(path) + "/" + filename;
188 whole_filename += '\0';
190 fp = fopen(whole_filename.contents(), "r");
193 if (errno != ENOENT) {
194 error("can't open `%1': %2",
195 whole_filename.contents(), strerror(errno));
199 if (j >= include_list_length)
202 error("can't open `%1': %2", filename, strerror(errno));
206 current_filename = whole_filename.contents();
209 enum { START, MIDDLE, HAD_DOT, HAD_s, HAD_so, HAD_l, HAD_lf } state = START;
267 if (c == ' ' || c == '\n' || compatible_flag) {
269 for (; c != EOF && c != '\n'; c = getc(fp))
274 do_so(line.contents());
278 fputs(".so", stdout);
299 if (c == ' ' || c == '\n' || compatible_flag) {
301 for (; c != EOF && c != '\n'; c = getc(fp))
306 interpret_lf_args(line.contents());
307 printf(".lf%s", line.contents());
311 fputs(".lf", stdout);
322 fputs(".\n", stdout);
325 fputs(".l\n", stdout);
328 fputs(".s\n", stdout);
331 fputs(".lf\n", stdout);
334 fputs(".so\n", stdout);
344 current_filename = 0;