diff options
Diffstat (limited to 'gnu/usr.bin/groff/libgroff/searchpath.cc')
| -rw-r--r-- | gnu/usr.bin/groff/libgroff/searchpath.cc | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/gnu/usr.bin/groff/libgroff/searchpath.cc b/gnu/usr.bin/groff/libgroff/searchpath.cc new file mode 100644 index 000000000000..eb7a6690cd3b --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/searchpath.cc @@ -0,0 +1,117 @@ +// -*- C++ -*- +/* Copyright (C) 1989, 1990, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#include "lib.h" +#include "searchpath.h" + +search_path::search_path(const char *envvar, const char *standard) +{ + char *e = envvar ? getenv(envvar) : 0; + if (e && standard) { + dirs = new char[strlen(e) + strlen(standard) + 2]; + strcpy(dirs, e); + strcat(dirs, ":"); + strcat(dirs, standard); + } + else + dirs = strsave(e ? e : standard); + init_len = dirs ? strlen(dirs) : 0; +} + +search_path::~search_path() +{ + if (dirs) + a_delete dirs; +} + +void search_path::command_line_dir(const char *s) +{ + if (!dirs) + dirs = strsave(s); + else { + char *old = dirs; + unsigned old_len = strlen(old); + unsigned slen = strlen(s); + dirs = new char[old_len + 1 + slen + 1]; + memcpy(dirs, old, old_len - init_len); + char *p = dirs; + p += old_len - init_len; + if (init_len == 0) + *p++ = ':'; + memcpy(p, s, slen); + p += slen; + if (init_len > 0) { + *p++ = ':'; + memcpy(p, old + old_len - init_len, init_len); + p += init_len; + } + *p++ = '\0'; + a_delete old; + } +} + +FILE *search_path::open_file(const char *name, char **pathp) +{ + assert(name != 0); + if (*name == '/' || dirs == 0 || *dirs == '\0') { + FILE *fp = fopen(name, "r"); + if (fp) { + if (pathp) + *pathp = strsave(name); + return fp; + } + else + return 0; + } + unsigned namelen = strlen(name); + char *p = dirs; + for (;;) { + char *end = strchr(p, ':'); + if (!end) + end = strchr(p, '\0'); + int need_slash = end > p && end[-1] != '/'; + char *path = new char[(end - p) + need_slash + namelen + 1]; + memcpy(path, p, end - p); + if (need_slash) + path[end - p] = '/'; + strcpy(path + (end - p) + need_slash, name); +#if 0 + fprintf(stderr, "trying `%s'\n", path); +#endif + FILE *fp = fopen(path, "r"); + if (fp) { + if (pathp) + *pathp = path; + else + a_delete path; + return fp; + } + a_delete path; + if (*end == '\0') + break; + p = end + 1; + } + return 0; +} |
