2 /* Provide relocation for macro and font files.
3 Copyright (C) 2005-2014 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published
7 by the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 // Made after relocation code in kpathsea and gettext.
31 # define WIN32_LEAN_AND_MEAN
35 #define INSTALLPATHLEN (sizeof(INSTALLPATH) - 1)
40 extern "C" const char *program_name;
42 // The prefix (parent directory) corresponding to the binary.
43 char *curr_prefix = 0;
44 size_t curr_prefix_len = 0;
46 // Return the directory part of a filename, or `.' if no path separators.
47 char *xdirname(char *s)
49 static const char dot[] = ".";
52 // DIR_SEPS[] are possible directory separator characters, see nonposix.h.
53 // We want the rightmost separator of all possible ones.
54 // Example: d:/foo\\bar.
55 char *p = strrchr(s, DIR_SEPS[0]);
56 const char *sep = &DIR_SEPS[1];
58 char *p1 = strrchr(s, *sep);
59 if (p1 && (!p || p1 > p))
70 // Return the full path of NAME along the path PATHP.
71 // Adapted from search_path::open_file in searchpath.cpp.
72 char *searchpath(const char *name, const char *pathp)
78 fprintf(stderr, "searchpath: pathp: `%s'\n", pathp);
79 fprintf(stderr, "searchpath: trying `%s'\n", name);
81 // Try first NAME as such; success if NAME is an absolute filename,
82 // or if NAME is found in the current directory.
83 if (!access (name, F_OK)) {
84 path = new char[path_name_max()];
86 path = _fullpath(path, name, path_name_max());
88 path = realpath(name, path);
91 fprintf(stderr, "searchpath: found `%s'\n", path);
95 // Secondly, try the current directory.
96 // Now search along PATHP.
97 size_t namelen = strlen(name);
98 char *p = (char *)pathp;
100 char *end = strchr(p, PATH_SEP_CHAR);
102 end = strchr(p, '\0');
103 int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0;
104 path = new char[end - p + need_slash + namelen + 1];
105 memcpy(path, p, end - p);
108 strcpy(path + (end - p) + need_slash, name);
110 fprintf(stderr, "searchpath: trying `%s'\n", path);
112 if (!access(path, F_OK)) {
114 fprintf(stderr, "searchpath: found `%s'\n", name);
126 // Search NAME along PATHP with the elements of PATHEXT in turn added.
127 char *searchpathext(const char *name, const char *pathext, const char *pathp)
130 char *tmpathext = strsave(pathext); // strtok modifies this string,
132 char *ext = strtok(tmpathext, PATH_SEP);
134 char *namex = new char[strlen(name) + strlen(ext) + 1];
137 found = searchpath(namex, pathp);
141 ext = strtok(0, PATH_SEP);
147 // Convert an MS path to a POSIX path.
148 char *msw2posixpath(char *path)
159 // Compute the current prefix.
160 void set_current_prefix()
163 curr_prefix = new char[path_name_max()];
164 // Obtain the full path of the current binary;
165 // using GetModuleFileName on MS-Windows,
166 // and searching along PATH on other systems.
168 int len = GetModuleFileName(0, curr_prefix, path_name_max());
170 len = GetShortPathName(curr_prefix, curr_prefix, path_name_max());
172 fprintf(stderr, "curr_prefix: %s\n", curr_prefix);
175 curr_prefix = searchpath(program_name, getenv("PATH"));
176 if (!curr_prefix && !strchr(program_name, '.')) { // try with extensions
177 pathextstr = strsave(getenv("PATHEXT"));
179 pathextstr = strsave(PATH_EXT);
180 curr_prefix = searchpathext(program_name, pathextstr, getenv("PATH"));
186 msw2posixpath(curr_prefix);
188 fprintf(stderr, "curr_prefix: %s\n", curr_prefix);
190 curr_prefix = xdirname(curr_prefix); // directory of executable
191 curr_prefix = xdirname(curr_prefix); // parent directory of executable
192 curr_prefix_len = strlen(curr_prefix);
194 fprintf(stderr, "curr_prefix: %s\n", curr_prefix);
195 fprintf(stderr, "curr_prefix_len: %d\n", curr_prefix_len);
199 // Strip the installation prefix and replace it
200 // with the current installation prefix; return the relocated path.
201 char *relocatep(const char *path)
204 fprintf(stderr, "relocatep: path = %s\n", path);
205 fprintf(stderr, "relocatep: INSTALLPATH = %s\n", INSTALLPATH);
206 fprintf(stderr, "relocatep: INSTALLPATHLEN = %d\n", INSTALLPATHLEN);
209 set_current_prefix();
210 if (strncmp(INSTALLPATH, path, INSTALLPATHLEN))
211 return strsave(path);
212 char *relative_path = (char *)path + INSTALLPATHLEN;
213 size_t relative_path_len = strlen(relative_path);
214 char *relocated_path = new char[curr_prefix_len + relative_path_len + 1];
215 strcpy(relocated_path, curr_prefix);
216 strcat(relocated_path, relative_path);
218 fprintf(stderr, "relocated_path: %s\n", relocated_path);
220 return relocated_path;
223 // Return the original pathname if it exists;
224 // otherwise return the relocated path.
225 char *relocate(const char *path)
228 if (access(path, F_OK))
233 fprintf (stderr, "relocate: %s\n", p);