diff options
author | Ruslan Ermilov <ru@FreeBSD.org> | 2001-04-17 12:12:05 +0000 |
---|---|---|
committer | Ruslan Ermilov <ru@FreeBSD.org> | 2001-04-17 12:12:05 +0000 |
commit | 1d5f6a94a87add2c3eb035043f48bb7fe1906661 (patch) | |
tree | f3137c4283de8869ebcae1dd0fe43f590276c1dc /contrib/groff/src/preproc/soelim | |
parent | c8d1b47c7fde3a8a3f5530bd5e3939bba340ab4b (diff) | |
download | src-1d5f6a94a87add2c3eb035043f48bb7fe1906661.tar.gz src-1d5f6a94a87add2c3eb035043f48bb7fe1906661.zip |
Virgin import of FSF groff v1.17
Notes
Notes:
svn path=/vendor/groff/dist/; revision=75584
Diffstat (limited to 'contrib/groff/src/preproc/soelim')
-rw-r--r-- | contrib/groff/src/preproc/soelim/Makefile.sub | 6 | ||||
-rw-r--r-- | contrib/groff/src/preproc/soelim/TODO | 1 | ||||
-rw-r--r-- | contrib/groff/src/preproc/soelim/soelim.cc | 347 | ||||
-rw-r--r-- | contrib/groff/src/preproc/soelim/soelim.man | 85 |
4 files changed, 439 insertions, 0 deletions
diff --git a/contrib/groff/src/preproc/soelim/Makefile.sub b/contrib/groff/src/preproc/soelim/Makefile.sub new file mode 100644 index 000000000000..77007e25f452 --- /dev/null +++ b/contrib/groff/src/preproc/soelim/Makefile.sub @@ -0,0 +1,6 @@ +PROG=soelim +MAN1=soelim.n +XLIBS=$(LIBGROFF) +OBJS=soelim.o +CCSRCS=$(srcdir)/soelim.cc +NAMEPREFIX=$(g) diff --git a/contrib/groff/src/preproc/soelim/TODO b/contrib/groff/src/preproc/soelim/TODO new file mode 100644 index 000000000000..f2a3924ef89f --- /dev/null +++ b/contrib/groff/src/preproc/soelim/TODO @@ -0,0 +1 @@ +Understand .pso. diff --git a/contrib/groff/src/preproc/soelim/soelim.cc b/contrib/groff/src/preproc/soelim/soelim.cc new file mode 100644 index 000000000000..e05f24065ad4 --- /dev/null +++ b/contrib/groff/src/preproc/soelim/soelim.cc @@ -0,0 +1,347 @@ +// -*- C++ -*- +/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with groff; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <errno.h> +#include "lib.h" +#include "errarg.h" +#include "error.h" +#include "stringclass.h" +#include "nonposix.h" + +static int include_list_length; +static char **include_list; + +int compatible_flag = 0; + +extern int interpret_lf_args(const char *); + +int do_file(const char *filename); + + +static void +include_path_append(char *path) +{ + ++include_list_length; + size_t nbytes = include_list_length * sizeof(char *); + if (include_list) + include_list = (char **)realloc((void *)include_list, nbytes); + else + include_list = (char **)malloc(nbytes); + if (include_list == NULL) + { + fprintf(stderr, "%s: out of memory\n", program_name); + exit(2); + } + include_list[include_list_length - 1] = path; +} + + +void usage(FILE *stream) +{ + fprintf(stream, "usage: %s [ -vC ] [ -I file ] [ files ]\n", program_name); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + include_path_append("."); + int opt; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, + { "version", no_argument, 0, 'v' }, + { NULL, 0, 0, 0 } + }; + while ((opt = getopt_long(argc, argv, "CI:v", long_options, NULL)) != EOF) + switch (opt) { + case 'v': + { + extern const char *Version_string; + printf("GNU soelim (groff) version %s\n", Version_string); + exit(0); + break; + } + case 'C': + compatible_flag = 1; + break; + case 'I': + include_path_append(optarg); + break; + case CHAR_MAX + 1: // --help + usage(stdout); + exit(0); + break; + case '?': + usage(stderr); + exit(1); + break; + default: + assert(0); + } + int nbad = 0; + if (optind >= argc) + nbad += !do_file("-"); + else + for (int i = optind; i < argc; i++) + nbad += !do_file(argv[i]); + if (ferror(stdout) || fflush(stdout) < 0) + fatal("output error"); + return nbad != 0; +} + +void set_location() +{ + printf(".lf %d %s\n", current_lineno, current_filename); +} + +void do_so(const char *line) +{ + const char *p = line; + while (*p == ' ') + p++; + string filename; + int success = 1; + for (const char *q = p; + success && *q != '\0' && *q != '\n' && *q != ' '; + q++) + if (*q == '\\') { + switch (*++q) { + case 'e': + case '\\': + filename += '\\'; + break; + case ' ': + filename += ' '; + break; + default: + success = 0; + break; + } + } + else + filename += char(*q); + if (success && filename.length() > 0) { + filename += '\0'; + const char *fn = current_filename; + int ln = current_lineno; + current_lineno--; + if (do_file(filename.contents())) { + current_filename = fn; + current_lineno = ln; + set_location(); + return; + } + current_lineno++; + } + fputs(".so", stdout); + fputs(line, stdout); +} + +int do_file(const char *filename) +{ + FILE *fp; + string whole_filename; + if (strcmp(filename, "-") == 0) { + fp = stdin; + whole_filename = filename; + whole_filename += '\0'; + } + else if (IS_ABSOLUTE(filename)) { + whole_filename = filename; + whole_filename += '\0'; + errno = 0; + fp = fopen(filename, "r"); + if (fp == 0) { + error("can't open `%1': %2", filename, strerror(errno)); + return 0; + } + } + else { + size_t j; + for (j = 0; j < include_list_length; ++j) + { + char *path = include_list[j]; + if (0 == strcmp(path, ".")) + whole_filename = filename; + else + whole_filename = string(path) + "/" + filename; + whole_filename += '\0'; + errno = 0; + fp = fopen(whole_filename.contents(), "r"); + if (fp != 0) + break; + if (errno != ENOENT) { + error("can't open `%1': %2", + whole_filename.contents(), strerror(errno)); + return 0; + } + } + if (j >= include_list_length) + { + errno = ENOENT; + error("can't open `%1': %2", filename, strerror(errno)); + return 0; + } + } + current_filename = whole_filename.contents(); + current_lineno = 1; + set_location(); + enum { START, MIDDLE, HAD_DOT, HAD_s, HAD_so, HAD_l, HAD_lf } state = START; + for (;;) { + int c = getc(fp); + if (c == EOF) + break; + switch (state) { + case START: + if (c == '.') + state = HAD_DOT; + else { + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case MIDDLE: + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + break; + case HAD_DOT: + if (c == 's') + state = HAD_s; + else if (c == 'l') + state = HAD_l; + else { + putchar('.'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_s: + if (c == 'o') + state = HAD_so; + else { + putchar('.'); + putchar('s'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_so: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + for (; c != EOF && c != '\n'; c = getc(fp)) + line += c; + current_lineno++; + line += '\n'; + line += '\0'; + do_so(line.contents()); + state = START; + } + else { + fputs(".so", stdout); + putchar(c); + state = MIDDLE; + } + break; + case HAD_l: + if (c == 'f') + state = HAD_lf; + else { + putchar('.'); + putchar('l'); + putchar(c); + if (c == '\n') { + current_lineno++; + state = START; + } + else + state = MIDDLE; + } + break; + case HAD_lf: + if (c == ' ' || c == '\n' || compatible_flag) { + string line; + for (; c != EOF && c != '\n'; c = getc(fp)) + line += c; + current_lineno++; + line += '\n'; + line += '\0'; + interpret_lf_args(line.contents()); + printf(".lf%s", line.contents()); + state = START; + } + else { + fputs(".lf", stdout); + putchar(c); + state = MIDDLE; + } + break; + default: + assert(0); + } + } + switch (state) { + case HAD_DOT: + fputs(".\n", stdout); + break; + case HAD_l: + fputs(".l\n", stdout); + break; + case HAD_s: + fputs(".s\n", stdout); + break; + case HAD_lf: + fputs(".lf\n", stdout); + break; + case HAD_so: + fputs(".so\n", stdout); + break; + case MIDDLE: + putc('\n', stdout); + break; + case START: + break; + } + if (fp != stdin) + fclose(fp); + current_filename = 0; + return 1; +} diff --git a/contrib/groff/src/preproc/soelim/soelim.man b/contrib/groff/src/preproc/soelim/soelim.man new file mode 100644 index 000000000000..b97ea61262e2 --- /dev/null +++ b/contrib/groff/src/preproc/soelim/soelim.man @@ -0,0 +1,85 @@ +.ig \"-*- nroff -*- +Copyright (C) 1989-2000 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH @G@SOELIM @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@" +.SH NAME +@g@soelim \- interpret .so requests in groff input +.SH SYNOPSIS +.B @g@soelim +[ +.B \-Cv +] +[ +.BI \-I dir +] +[ +.IR files \|.\|.\|.\| +] +.PP +It is possible to have whitespace between the +.B \-I +command line option and its parameter. +.SH DESCRIPTION +.B @g@soelim +reads +.I files +and replaces lines of the form +.IP +.BI .so\ file +.LP +by the contents of +.IR file . +It is useful if files included with +.B so +need to be preprocessed. +Normally, +.B @g@soelim +should be invoked with the +.B \-s +option of +.BR groff . +.PP +Note that there must be no whitespace between the leading dot and +the two characters `s' and `o'. Otherwise, only +.B groff +interprets the +.B .so +request (and +.B soelim +ignores it). +.SH OPTIONS +.TP +.B \-C +Recognize +.B .so +even when followed by a character other than space or newline. +.TP +.BI \-I dir +This option may be used to specify a directory to search for +files (both those on the command line and those named in +.B \&.so +lines). +The current directory is always searched first. +This option may be specified more than once, +the directories will be searched in the order specified. +No directory search is performed for files specified using an absolute path. +.TP +.B \-v +Print the version number. +.SH "SEE ALSO" +.BR groff (@MAN1EXT@) |