/
niceSOFT
/
groff
Обзор
Документация
Войти
/
niceSOFT
/
groff
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/libs/libgroff/relocate.cpp
257 строк
7 KB
G. Branden Robinson
[libgroff]: Drop unnecessary function call.
01 апр 2026, 05:56
01 апр 2026, 05:56
0f6f550
Код
Авторство
О чём код?
/* Provide relocation for macro and font files. Copyright 2005 Free Software Foundation, Inc. Made by Werner Lemberg after relocation code in kpathsea and gettext. This file is part of groff, the GNU roff typesetting system. This file is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This file 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <assert.h> #include <errno.h> #include <stdlib.h> #include "lib.h" #include "defs.h" #include "posix.h" #include "nonposix.h" #include "relocate.h" #if defined _WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> #endif #define INSTALLPATHLEN (sizeof(INSTALLPATH) - 1) #ifndef DEBUG # define DEBUG 0 #endif extern "C" const char *program_name; // The prefix (parent directory) corresponding to the binary. char *curr_prefix = 0; size_t curr_prefix_len = 0; // Return the directory part of a filename, or '.' if no path separators. char *xdirname(char *s) { static const char dot[] = "."; if (!s) return 0; // DIR_SEPS[] are possible directory separator characters, see nonposix.h. // We want the rightmost separator of all possible ones. // Example: d:/foo\\bar. char *p = strrchr(s, DIR_SEPS[0]); const char *sep = &DIR_SEPS[1]; while (*sep) { char *p1 = strrchr(s, *sep); if (p1 && (!p || p1 > p)) p = p1; sep++; } if (p) *p = '\0'; else s = (char *)dot; return s; } // Return the full path of NAME along the path PATHP. // Adapted from search_path::open_file in searchpath.cpp. char *searchpath(const char *name, const char *pathp) { char *path; if (!name || !*name) return 0; #if DEBUG fprintf(stderr, "searchpath: pathp: '%s'\n", pathp); fprintf(stderr, "searchpath: trying '%s'\n", name); #endif // Try first NAME as such; success if NAME is an absolute filename, // or if NAME is found in the current directory. if (!access (name, F_OK)) { path = new char[path_name_max()]; #ifdef _WIN32 path = _fullpath(path, name, path_name_max()); #else path = realpath(name, path); #endif #if DEBUG fprintf(stderr, "searchpath: found '%s'\n", path); #endif return path; } // Secondly, try the current directory. // Now search along PATHP. size_t namelen = strlen(name); char *p = (char *)pathp; for (;;) { char *end = strchr(p, PATH_SEP_CHAR); if (!end) end = strchr(p, '\0'); int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0; 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 DEBUG fprintf(stderr, "searchpath: trying '%s'\n", path); #endif if (!access(path, F_OK)) { #if DEBUG fprintf(stderr, "searchpath: found '%s'\n", name); #endif return path; } delete[] path; if (*end == '\0') break; p = end + 1; } return 0; } #ifdef _WIN32 // Search NAME along PATHP with the elements of PATHEXT in turn added. static char *searchpathext(const char *name, const char *pathext, const char *pathp) { char *found = 0; char *tmpathext = strsave(pathext); // strtok modifies this string, // so make a copy char *ext = strtok(tmpathext, PATH_SEP); while (ext) { char *namex = new char[strlen(name) + strlen(ext) + 1]; strcpy(namex, name); strcat(namex, ext); found = searchpath(namex, pathp); delete[] namex; if (found) break; ext = strtok(0, PATH_SEP); } delete[] tmpathext; return found; } // XXX: This function is nearly identical to // `normalize_file_name_for_lf_request()` in "libgroff/lf.cpp". // // Convert an MS path to a POSIX path. static char *msw2posixpath(char *path) { char *s = path; while (*s) { if (*s == '\\') *s = '/'; s++; } return path; } #endif // Compute the current prefix. void set_current_prefix() { // Obtain the full path of the current binary; // using GetModuleFileName on MS-Windows, // and searching along PATH on other systems. #ifdef _WIN32 char *pathextstr; curr_prefix = new char[path_name_max()]; int len = GetModuleFileName(0, curr_prefix, path_name_max()); if (len) len = GetShortPathName(curr_prefix, curr_prefix, path_name_max()); # if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); # endif /* DEBUG */ if (!curr_prefix && !strchr(program_name, '.')) { // try with extensions pathextstr = strsave(getenv("PATHEXT")); if (0 /* nullptr */ == pathextstr) pathextstr = strsave(PATH_EXT); curr_prefix = searchpathext(program_name, pathextstr, getenv("PATH")); delete[] pathextstr; } msw2posixpath(curr_prefix); #else /* !_WIN32 */ curr_prefix = searchpath(program_name, getenv("PATH")); if (!curr_prefix) return; #endif /* !_WIN32 */ #if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); #endif curr_prefix = xdirname(curr_prefix); // directory of executable curr_prefix = xdirname(curr_prefix); // parent directory of executable curr_prefix_len = strlen(curr_prefix); #if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); fprintf(stderr, "curr_prefix_len: %d\n", curr_prefix_len); #endif } // Strip the installation prefix and replace it // with the current installation prefix; return the relocated path. char *relocatep(const char *path) { #if DEBUG fprintf(stderr, "relocatep: path = %s\n", path); fprintf(stderr, "relocatep: INSTALLPATH = %s\n", INSTALLPATH); fprintf(stderr, "relocatep: INSTALLPATHLEN = %d\n", INSTALLPATHLEN); #endif if (!curr_prefix) set_current_prefix(); if (strncmp(INSTALLPATH, path, INSTALLPATHLEN)) return strsave(path); char *relative_path = (char *)path + INSTALLPATHLEN; size_t relative_path_len = strlen(relative_path); char *relocated_path = (char *)malloc(curr_prefix_len + relative_path_len + 1); assert(0 != curr_prefix); strcpy(relocated_path, curr_prefix); strcat(relocated_path, relative_path); #if DEBUG fprintf(stderr, "relocated_path: %s\n", relocated_path); #endif /* DEBUG */ return relocated_path; } // Return the original pathname if it exists; // otherwise return the relocated path. char *relocate(const char *path) { char *p; if (access(path, F_OK)) p = relocatep(path); else p = strsave(path); #if DEBUG fprintf (stderr, "relocate: %s\n", p); #endif return p; } // Local Variables: // fill-column: 72 // mode: C++ // End: // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: