Commit | Line | Data |
---|---|---|
8c4ebc23 JH |
1 | // -*- C++ -*- |
2 | /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. | |
3 | Written by James Clark (jjc@jclark.com) | |
4 | ||
5 | This file is part of groff. | |
6 | ||
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 | |
10 | version. | |
11 | ||
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 | |
15 | for more details. | |
16 | ||
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, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | ||
21 | #include <stdio.h> | |
22 | #include <string.h> | |
23 | #include <stdlib.h> | |
24 | #include <assert.h> | |
25 | ||
26 | #include "lib.h" | |
27 | #include "searchpath.h" | |
28 | ||
29 | search_path::search_path(const char *envvar, const char *standard) | |
30 | { | |
31 | char *e = envvar ? getenv(envvar) : 0; | |
32 | if (e && standard) { | |
33 | dirs = new char[strlen(e) + strlen(standard) + 2]; | |
34 | strcpy(dirs, e); | |
35 | strcat(dirs, ":"); | |
36 | strcat(dirs, standard); | |
37 | } | |
38 | else | |
39 | dirs = strsave(e ? e : standard); | |
40 | init_len = dirs ? strlen(dirs) : 0; | |
41 | } | |
42 | ||
43 | search_path::~search_path() | |
44 | { | |
45 | if (dirs) | |
46 | a_delete dirs; | |
47 | } | |
48 | ||
49 | void search_path::command_line_dir(const char *s) | |
50 | { | |
51 | if (!dirs) | |
52 | dirs = strsave(s); | |
53 | else { | |
54 | char *old = dirs; | |
55 | unsigned old_len = strlen(old); | |
56 | unsigned slen = strlen(s); | |
57 | dirs = new char[old_len + 1 + slen + 1]; | |
58 | memcpy(dirs, old, old_len - init_len); | |
59 | char *p = dirs; | |
60 | p += old_len - init_len; | |
61 | if (init_len == 0) | |
62 | *p++ = ':'; | |
63 | memcpy(p, s, slen); | |
64 | p += slen; | |
65 | if (init_len > 0) { | |
66 | *p++ = ':'; | |
67 | memcpy(p, old + old_len - init_len, init_len); | |
68 | p += init_len; | |
69 | } | |
70 | *p++ = '\0'; | |
71 | a_delete old; | |
72 | } | |
73 | } | |
74 | ||
75 | FILE *search_path::open_file(const char *name, char **pathp) | |
76 | { | |
77 | assert(name != 0); | |
78 | if (*name == '/' || dirs == 0 || *dirs == '\0') { | |
79 | FILE *fp = fopen(name, "r"); | |
80 | if (fp) { | |
81 | if (pathp) | |
82 | *pathp = strsave(name); | |
83 | return fp; | |
84 | } | |
85 | else | |
86 | return 0; | |
87 | } | |
88 | unsigned namelen = strlen(name); | |
89 | char *p = dirs; | |
90 | for (;;) { | |
91 | char *end = strchr(p, ':'); | |
92 | if (!end) | |
93 | end = strchr(p, '\0'); | |
94 | int need_slash = end > p && end[-1] != '/'; | |
95 | char *path = new char[(end - p) + need_slash + namelen + 1]; | |
96 | memcpy(path, p, end - p); | |
97 | if (need_slash) | |
98 | path[end - p] = '/'; | |
99 | strcpy(path + (end - p) + need_slash, name); | |
100 | #if 0 | |
101 | fprintf(stderr, "trying `%s'\n", path); | |
102 | #endif | |
103 | FILE *fp = fopen(path, "r"); | |
104 | if (fp) { | |
105 | if (pathp) | |
106 | *pathp = path; | |
107 | else | |
108 | a_delete path; | |
109 | return fp; | |
110 | } | |
111 | a_delete path; | |
112 | if (*end == '\0') | |
113 | break; | |
114 | p = end + 1; | |
115 | } | |
116 | return 0; | |
117 | } |