From 7578dcc6592a42a9ad7fbebacd5fcdfba0238f9e Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Wed, 20 May 2015 20:55:04 +0000 Subject: Initial revision --- compat_stringlist.c | 116 ++++++++++++++++++++++++++++++++++ compat_stringlist.h | 57 +++++++++++++++++ soelim.1 | 82 ++++++++++++++++++++++++ soelim.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 433 insertions(+) create mode 100644 compat_stringlist.c create mode 100644 compat_stringlist.h create mode 100644 soelim.1 create mode 100644 soelim.c diff --git a/compat_stringlist.c b/compat_stringlist.c new file mode 100644 index 00000000..a09a8e70 --- /dev/null +++ b/compat_stringlist.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1994 Christos Zoulas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#define _SL_CHUNKSIZE 20 + +/* + * sl_init(): Initialize a string list + */ +StringList * +sl_init(void) +{ + StringList *sl; + + sl = malloc(sizeof(StringList)); + if (sl == NULL) + _err(1, "stringlist: %m"); + + sl->sl_cur = 0; + sl->sl_max = _SL_CHUNKSIZE; + sl->sl_str = malloc(sl->sl_max * sizeof(char *)); + if (sl->sl_str == NULL) + _err(1, "stringlist: %m"); + return sl; +} + + +/* + * sl_add(): Add an item to the string list + */ +int +sl_add(StringList *sl, char *name) +{ + if (sl->sl_cur == sl->sl_max - 1) { + sl->sl_max += _SL_CHUNKSIZE; + sl->sl_str = reallocf(sl->sl_str, sl->sl_max * sizeof(char *)); + if (sl->sl_str == NULL) + return (-1); + } + sl->sl_str[sl->sl_cur++] = name; + return (0); +} + + +/* + * sl_free(): Free a stringlist + */ +void +sl_free(StringList *sl, int all) +{ + size_t i; + + if (sl == NULL) + return; + if (sl->sl_str) { + if (all) + for (i = 0; i < sl->sl_cur; i++) + free(sl->sl_str[i]); + free(sl->sl_str); + } + free(sl); +} + + +/* + * sl_find(): Find a name in the string list + */ +char * +sl_find(StringList *sl, const char *name) +{ + size_t i; + + for (i = 0; i < sl->sl_cur; i++) + if (strcmp(sl->sl_str[i], name) == 0) + return sl->sl_str[i]; + + return NULL; +} diff --git a/compat_stringlist.h b/compat_stringlist.h new file mode 100644 index 00000000..d3154b34 --- /dev/null +++ b/compat_stringlist.h @@ -0,0 +1,57 @@ +/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */ + +/* + * Copyright (c) 1994 Christos Zoulas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christos Zoulas. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _STRINGLIST_H +#define _STRINGLIST_H +#include +#include + +/* + * Simple string list + */ +typedef struct _stringlist { + char **sl_str; + size_t sl_max; + size_t sl_cur; +} StringList; + +__BEGIN_DECLS +StringList *sl_init(void); +int sl_add(StringList *, char *); +void sl_free(StringList *, int); +char *sl_find(StringList *, const char *); +__END_DECLS + +#endif /* _STRINGLIST_H */ diff --git a/soelim.1 b/soelim.1 new file mode 100644 index 00000000..b6ec13c1 --- /dev/null +++ b/soelim.1 @@ -0,0 +1,82 @@ +.\" Copyright (c) 2014 Baptiste Daroussin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 1, 2015 +.Dt SOELIM 1 +.Os +.Sh NAME +.Nm soelim +.Nd interpret .so directive in manpages +.Sh SYNOPSIS +.Nm +.Op Fl Crtv +.Op Fl I Ar dir +.Op Ar files ... +.Sh DESCRIPTION +.Nm +reads +.Ar files +lines by lines. +.Pp +If a line starts by: +.Dq .so anotherfile +it replace the line by processing +.Dq anotherfile . +Otherwise the line is printed to stdout. +.Bl -tag -width "-I dir" +.It Fl C +Recognise +.Em .so +when not followed by a space character. +.It Fl r +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl t +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl v +Compatibility with GNU groff's +.Xr soelim 1 +(does nothing). +.It Fl I Ar dir +This option specify directories where +.Nm +searches for files (both those on the command line and those named in +.Dq .so +directive.) +This options may be specified multiple times. The directories will be searched +in the order specified. +.El +.Pp +The files are always searched first in the current directory. +.Pp +A file specified with an absolute path will be opened directly without +performing a search. +.Sh SEE ALSO +.Xr mandoc 1 , +.Xr soelim 1 diff --git a/soelim.c b/soelim.c new file mode 100644 index 00000000..de6911f3 --- /dev/null +++ b/soelim.c @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2014 Baptiste Daroussin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#define _WITH_GETLINE +#include +#include +#include +#include +#include +#include +#include +#include + +#define C_OPTION 0x1 + +static StringList *includes; + +static void +usage(void) +{ + + fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n"); + + exit(EXIT_FAILURE); +} + +static FILE * +soelim_fopen(const char *name) +{ + FILE *f; + char path[MAXPATHLEN]; + size_t i; + + if (strcmp(name, "-") == 0) + return (stdin); + + if ((f = fopen(name, "r")) != NULL) + return (f); + + if (*name == '/') { + warn("can't open '%s'", name); + return (NULL); + } + + for (i = 0; i < includes->sl_cur; i++) { + snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i], + name); + if ((f = fopen(path, "r")) != NULL) + return (f); + } + + warn("can't open '%s'", name); + + return (f); +} + +static int +soelim_file(FILE *f, int flag) +{ + char *line = NULL; + char *walk, *cp; + size_t linecap = 0; + ssize_t linelen; + + if (f == NULL) + return (1); + + while ((linelen = getline(&line, &linecap, f)) > 0) { + if (strncmp(line, ".so", 3) != 0) { + printf("%s", line); + continue; + } + + walk = line + 3; + if (!isspace(*walk) && ((flag & C_OPTION) == 0)) { + printf("%s", line); + continue; + } + + while (isspace(*walk)) + walk++; + + cp = walk; + while (*cp != '\0' && !isspace(*cp)) + cp++; + *cp = 0; + if (cp < line + linelen) + cp++; + + if (*walk == '\0') { + printf("%s", line); + continue; + } + if (soelim_file(soelim_fopen(walk), flag) == 1) { + free(line); + return (1); + } + if (*cp != '\0') + printf("%s", cp); + } + + free(line); + fclose(f); + + return (0); +} + +int +main(int argc, char **argv) +{ + int ch, i; + int ret = 0; + int flags = 0; + + includes = sl_init(); + if (includes == NULL) + err(EXIT_FAILURE, "sl_init()"); + + while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { + switch (ch) { + case 'C': + flags |= C_OPTION; + break; + case 'r': + case 'v': + case 't': + /* stub compatibility with groff's soelim */ + break; + case 'I': + sl_add(includes, optarg); + break; + default: + sl_free(includes, 0); + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + ret = soelim_file(stdin, flags); + + for (i = 0; i < argc; i++) + ret = soelim_file(soelim_fopen(argv[i]), flags); + + sl_free(includes, 0); + + return (ret); +} -- cgit v1.2.3-56-ge451