[BACK]Return to soelim.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/soelim.c, Revision 1.2

1.2     ! schwarze    1: /*     $Id$    */
        !             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:  */
                     27:
                     28: #include <sys/param.h>
1.2     ! schwarze   29: #include <sys/types.h>
1.1       schwarze   30:
1.2     ! schwarze   31: #include <ctype.h>
        !            32: #include <err.h>
1.1       schwarze   33: #include <stdio.h>
                     34: #include <stdlib.h>
                     35: #include <string.h>
1.2     ! schwarze   36: #if HAVE_STRINGLIST
1.1       schwarze   37: #include <stringlist.h>
1.2     ! schwarze   38: #else
        !            39: #include "compat_stringlist.h"
        !            40: #endif
        !            41: #include <unistd.h>
1.1       schwarze   42:
                     43: #define C_OPTION 0x1
                     44:
                     45: static StringList *includes;
                     46:
                     47: static void
                     48: usage(void)
                     49: {
                     50:
                     51:        fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n");
                     52:
                     53:        exit(EXIT_FAILURE);
                     54: }
                     55:
                     56: static FILE *
                     57: soelim_fopen(const char *name)
                     58: {
                     59:        FILE *f;
                     60:        char path[MAXPATHLEN];
                     61:        size_t i;
                     62:
                     63:        if (strcmp(name, "-") == 0)
                     64:                return (stdin);
                     65:
                     66:        if ((f = fopen(name, "r")) != NULL)
                     67:                return (f);
                     68:
                     69:        if (*name == '/') {
                     70:                warn("can't open '%s'", name);
                     71:                return (NULL);
                     72:        }
                     73:
                     74:        for (i = 0; i < includes->sl_cur; i++) {
                     75:                snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i],
                     76:                    name);
                     77:                if ((f = fopen(path, "r")) != NULL)
                     78:                        return (f);
                     79:        }
                     80:
                     81:        warn("can't open '%s'", name);
                     82:
                     83:        return (f);
                     84: }
                     85:
                     86: static int
                     87: soelim_file(FILE *f, int flag)
                     88: {
                     89:        char *line = NULL;
                     90:        char *walk, *cp;
                     91:        size_t linecap = 0;
                     92:        ssize_t linelen;
                     93:
                     94:        if (f == NULL)
                     95:                return (1);
                     96:
                     97:        while ((linelen = getline(&line, &linecap, f)) > 0) {
                     98:                if (strncmp(line, ".so", 3) != 0) {
                     99:                        printf("%s", line);
                    100:                        continue;
                    101:                }
                    102:
                    103:                walk = line + 3;
                    104:                if (!isspace(*walk) && ((flag & C_OPTION) == 0)) {
                    105:                        printf("%s", line);
                    106:                        continue;
                    107:                }
                    108:
                    109:                while (isspace(*walk))
                    110:                        walk++;
                    111:
                    112:                cp = walk;
                    113:                while (*cp != '\0' && !isspace(*cp))
                    114:                        cp++;
                    115:                *cp = 0;
                    116:                if (cp < line + linelen)
                    117:                        cp++;
                    118:
                    119:                if (*walk == '\0') {
                    120:                        printf("%s", line);
                    121:                        continue;
                    122:                }
                    123:                if (soelim_file(soelim_fopen(walk), flag) == 1) {
                    124:                        free(line);
                    125:                        return (1);
                    126:                }
                    127:                if (*cp != '\0')
                    128:                        printf("%s", cp);
                    129:        }
                    130:
                    131:        free(line);
                    132:        fclose(f);
                    133:
                    134:        return (0);
                    135: }
                    136:
                    137: int
                    138: main(int argc, char **argv)
                    139: {
                    140:        int ch, i;
                    141:        int ret = 0;
                    142:        int flags = 0;
                    143:
                    144:        includes = sl_init();
                    145:        if (includes == NULL)
                    146:                err(EXIT_FAILURE, "sl_init()");
                    147:
                    148:        while ((ch = getopt(argc, argv, "CrtvI:")) != -1) {
                    149:                switch (ch) {
                    150:                case 'C':
                    151:                        flags |= C_OPTION;
                    152:                        break;
                    153:                case 'r':
                    154:                case 'v':
                    155:                case 't':
                    156:                        /* stub compatibility with groff's soelim */
                    157:                        break;
                    158:                case 'I':
                    159:                        sl_add(includes, optarg);
                    160:                        break;
                    161:                default:
                    162:                        sl_free(includes, 0);
                    163:                        usage();
                    164:                }
                    165:        }
                    166:
                    167:        argc -= optind;
                    168:        argv += optind;
                    169:
                    170:        if (argc == 0)
                    171:                ret = soelim_file(stdin, flags);
                    172:
                    173:        for (i = 0; i < argc; i++)
                    174:                ret = soelim_file(soelim_fopen(argv[i]), flags);
                    175:
                    176:        sl_free(includes, 0);
                    177:
                    178:        return (ret);
                    179: }

CVSweb