4 /* Provide relocation for macro and font files.
5 Copyright (C) 2005 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Library General Public License as published
9 by the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
22 // Made after relocation code in kpathsea and gettext.
35 # define WIN32_LEAN_AND_MEAN
39 #define INSTALLPATHLEN (sizeof(INSTALLPATH) - 1)
44 extern "C" const char *program_name
;
46 // The prefix (parent directory) corresponding to the binary.
47 char *curr_prefix
= 0;
48 size_t curr_prefix_len
= 0;
50 // Return the directory part of a filename, or `.' if no path separators.
51 char *xdirname(char *s
)
53 static const char dot
[] = ".";
56 // DIR_SEPS[] are possible directory separator characters, see nonposix.h.
57 // We want the rightmost separator of all possible ones.
58 // Example: d:/foo\\bar.
59 char *p
= strrchr(s
, DIR_SEPS
[0]);
60 const char *sep
= &DIR_SEPS
[1];
62 char *p1
= strrchr(s
, *sep
);
63 if (p1
&& (!p
|| p1
> p
))
74 // Return the full path of NAME along the path PATHP.
75 // Adapted from search_path::open_file in searchpath.cpp.
76 char *searchpath(const char *name
, const char *pathp
)
82 fprintf(stderr
, "searchpath: pathp: `%s'\n", pathp
);
83 fprintf(stderr
, "searchpath: trying `%s'\n", name
);
85 // Try first NAME as such; success if NAME is an absolute filename,
86 // or if NAME is found in the current directory.
87 if (!access (name
, F_OK
)) {
88 path
= new char[path_name_max()];
90 path
= _fullpath(path
, name
, path_name_max());
92 path
= realpath(name
, path
);
95 fprintf(stderr
, "searchpath: found `%s'\n", path
);
99 // Secondly, try the current directory.
100 // Now search along PATHP.
101 size_t namelen
= strlen(name
);
102 char *p
= (char *)pathp
;
104 char *end
= strchr(p
, PATH_SEP_CHAR
);
106 end
= strchr(p
, '\0');
107 int need_slash
= end
> p
&& strchr(DIR_SEPS
, end
[-1]) == 0;
108 path
= new char[end
- p
+ need_slash
+ namelen
+ 1];
109 memcpy(path
, p
, end
- p
);
112 strcpy(path
+ (end
- p
) + need_slash
, name
);
114 fprintf(stderr
, "searchpath: trying `%s'\n", path
);
116 if (!access(path
, F_OK
)) {
118 fprintf(stderr
, "searchpath: found `%s'\n", name
);
130 // Search NAME along PATHP with the elements of PATHEXT in turn added.
131 char *searchpathext(const char *name
, const char *pathext
, const char *pathp
)
134 char *tmpathext
= strsave(pathext
); // strtok modifies this string,
136 char *ext
= strtok(tmpathext
, PATH_SEP
);
138 char *namex
= new char[strlen(name
) + strlen(ext
) + 1];
141 found
= searchpath(namex
, pathp
);
145 ext
= strtok(0, PATH_SEP
);
151 // Convert an MS path to a POSIX path.
152 char *msw2posixpath(char *path
)
163 // Compute the current prefix.
164 void set_current_prefix()
167 curr_prefix
= new char[path_name_max()];
168 // Obtain the full path of the current binary;
169 // using GetModuleFileName on MS-Windows,
170 // and searching along PATH on other systems.
172 int len
= GetModuleFileName(0, curr_prefix
, path_name_max());
174 len
= GetShortPathName(curr_prefix
, curr_prefix
, path_name_max());
176 fprintf(stderr
, "curr_prefix: %s\n", curr_prefix
);
179 curr_prefix
= searchpath(program_name
, getenv("PATH"));
180 if (!curr_prefix
&& !strchr(program_name
, '.')) { // try with extensions
181 pathextstr
= strsave(getenv("PATHEXT"));
183 pathextstr
= strsave(PATH_EXT
);
184 curr_prefix
= searchpathext(program_name
, pathextstr
, getenv("PATH"));
190 msw2posixpath(curr_prefix
);
192 fprintf(stderr
, "curr_prefix: %s\n", curr_prefix
);
194 curr_prefix
= xdirname(curr_prefix
); // directory of executable
195 curr_prefix
= xdirname(curr_prefix
); // parent directory of executable
196 curr_prefix_len
= strlen(curr_prefix
);
198 fprintf(stderr
, "curr_prefix: %s\n", curr_prefix
);
199 fprintf(stderr
, "curr_prefix_len: %d\n", curr_prefix_len
);
203 // Strip the installation prefix and replace it
204 // with the current installation prefix; return the relocated path.
205 char *relocatep(const char *path
)
208 fprintf(stderr
, "relocatep: path = %s\n", path
);
209 fprintf(stderr
, "relocatep: INSTALLPATH = %s\n", INSTALLPATH
);
210 fprintf(stderr
, "relocatep: INSTALLPATHLEN = %d\n", INSTALLPATHLEN
);
213 set_current_prefix();
214 if (strncmp(INSTALLPATH
, path
, INSTALLPATHLEN
))
215 return strsave(path
);
216 char *relative_path
= (char *)path
+ INSTALLPATHLEN
;
217 size_t relative_path_len
= strlen(relative_path
);
218 char *relocated_path
= new char[curr_prefix_len
+ relative_path_len
+ 1];
219 strcpy(relocated_path
, curr_prefix
);
220 strcat(relocated_path
, relative_path
);
222 fprintf(stderr
, "relocated_path: %s\n", relocated_path
);
224 return relocated_path
;
227 // Return the original pathname if it exists;
228 // otherwise return the relocated path.
229 char *relocate(const char *path
)
232 if (access(path
, F_OK
))
237 fprintf (stderr
, "relocate: %s\n", p
);