diff options
| author | Bruce Momjian | 2004-05-17 14:35:34 +0000 |
|---|---|---|
| committer | Bruce Momjian | 2004-05-17 14:35:34 +0000 |
| commit | 3febb477e643c1cd37fc8d2d3e02685dce6d1196 (patch) | |
| tree | adc5f3696ec9001b0bda4d9c0336c50c251c2f62 /src/port | |
| parent | 85383214ea2b0085658a650b4e6b293464dcf045 (diff) | |
Reorganize code to allow path-relative installs.
Create new get_* functions to access compiled-in paths and adjust if
relative installs are to be used.
Clean up substitute_libpath_macro() code.
Diffstat (limited to 'src/port')
| -rw-r--r-- | src/port/Makefile | 9 | ||||
| -rw-r--r-- | src/port/exec.c | 19 | ||||
| -rw-r--r-- | src/port/path.c | 278 |
3 files changed, 267 insertions, 39 deletions
diff --git a/src/port/Makefile b/src/port/Makefile index 356a0b4585..fc84d57260 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -7,7 +7,7 @@ # with broken/missing library files. # IDENTIFICATION -# $PostgreSQL: pgsql/src/port/Makefile,v 1.10 2004/04/23 18:15:55 momjian Exp $ +# $PostgreSQL: pgsql/src/port/Makefile,v 1.11 2004/05/17 14:35:34 momjian Exp $ # #------------------------------------------------------------------------- @@ -15,6 +15,13 @@ subdir = src/port top_builddir = ../.. include $(top_builddir)/src/Makefile.global +override CPPFLAGS += -DPGBINDIR=\"$(bindir)\" \ + -DPGDATADIR=\"$(datadir)\" \ + -DSYSCONFDIR='"$(sysconfdir)"' \ + -DINCLUDEDIR=\"$(includedir)\" \ + -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \ + -DPKGLIBDIR=\"$(pkglibdir)\" + ifdef LIBOBJS all: libpgport.a endif diff --git a/src/port/exec.c b/src/port/exec.c index 1022082551..02defe9a8d 100644 --- a/src/port/exec.c +++ b/src/port/exec.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/exec.c,v 1.5 2004/05/14 17:04:48 momjian Exp $ + * $PostgreSQL: pgsql/src/port/exec.c,v 1.6 2004/05/17 14:35:34 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,13 @@ #include "miscadmin.h" +/* $PATH (or %PATH%) path separator */ +#ifdef WIN32 +#define PATHSEP ';' +#else +#define PATHSEP ':' +#endif + #ifndef S_IRUSR /* XXX [TRH] should be in a header */ #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE @@ -265,6 +272,16 @@ find_my_exec(const char *argv0, char *full_path) log_debug("could not find a \"%s\" to execute", argv0); return -1; + +#if 0 + /* + * Win32 has a native way to find the executable name, but the above + * method works too. + */ + if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0) + ereport(FATAL, + (errmsg("GetModuleFileName failed (%i)",(int)GetLastError()))); +#endif } diff --git a/src/port/path.c b/src/port/path.c index 5d102a90c2..f5fccca278 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/path.c,v 1.7 2004/05/12 13:38:49 momjian Exp $ + * $PostgreSQL: pgsql/src/port/path.c,v 1.8 2004/05/17 14:35:34 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -16,6 +16,24 @@ #include "c.h" #include <ctype.h> +#ifndef WIN32 +#define ISSEP(ch) ((ch) == '/') +#else +#define ISSEP(ch) ((ch) == '/' || (ch) == '\\') +#endif + +static bool relative_path(const char *path1, const char *path2); +static void trim_directory(char *path); +static void trim_trailing_separator(char *path); + +/* Move to last of consecutive separators or to null byte */ +#define MOVE_TO_SEP_END(p) \ +{ \ + while (ISSEP((p)[0]) && (ISSEP((p)[1]) || !(p)[1])) \ + (p)++; \ +} + + /* * is_absolute_path */ @@ -40,22 +58,12 @@ is_absolute_path(const char *filename) char * first_path_separator(const char *filename) { -#ifndef WIN32 - return strchr(filename, '/'); -#else - char *slash, - *bslash; - - /* How should we handle "C:file.c"? */ - slash = strchr(filename, '/'); - bslash = strchr(filename, '\\'); - if (slash == NULL) - return bslash; - else if (bslash == NULL) - return slash; - else - return (slash < bslash) ? slash : bslash; -#endif + char *p; + + for (p = (char *)filename; *p; p++) + if (ISSEP(*p)) + return p; + return NULL; } @@ -65,22 +73,12 @@ first_path_separator(const char *filename) char * last_path_separator(const char *filename) { -#ifndef WIN32 - return strrchr(filename, '/'); -#else - char *slash, - *bslash; - - /* How should we handle "C:file.c"? */ - slash = strrchr(filename, '/'); - bslash = strrchr(filename, '\\'); - if (slash == NULL) - return bslash; - else if (bslash == NULL) - return slash; - else - return (slash > bslash) ? slash : bslash; -#endif + char *p, *ret = NULL; + + for (p = (char *)filename; *p; p++) + if (ISSEP(*p)) + ret = p; + return ret; } @@ -96,17 +94,17 @@ last_path_separator(const char *filename) void canonicalize_path(char *path) { +#ifdef WIN32 char *p; for (p = path; *p; p++) { -#ifdef WIN32 if (*p == '\\') *p = '/'; -#endif } - if (p > path+1 && *--p == '/') - *p = '\0'; +#endif + + trim_trailing_separator(path); } @@ -122,3 +120,209 @@ get_progname(const char *argv0) return last_path_separator(argv0) + 1; } + +/* + * get_share_path + */ +void +get_share_path(const char *my_exec_path, char *ret_path) +{ + if (relative_path(PGBINDIR, PGDATADIR)) + { + /* Autoconf calls our /share 'datadir' */ + StrNCpy(ret_path, my_exec_path, MAXPGPATH); + trim_directory(ret_path); /* trim off binary */ + trim_directory(ret_path); /* trim off /bin */ + strcat(ret_path, "/share"); /* add /share */ + } + else + StrNCpy(ret_path, PGDATADIR, MAXPGPATH); +} + + + +/* + * get_etc_path + */ +void +get_etc_path(const char *my_exec_path, char *ret_path) +{ + if (relative_path(PGBINDIR, SYSCONFDIR)) + { + StrNCpy(ret_path, my_exec_path, MAXPGPATH); + trim_directory(ret_path); + trim_directory(ret_path); + strcat(ret_path, "/etc"); + } + else + StrNCpy(ret_path, SYSCONFDIR, MAXPGPATH); +} + + + +/* + * get_include_path + */ +void +get_include_path(const char *my_exec_path, char *ret_path) +{ + if (relative_path(PGBINDIR, INCLUDEDIR)) + { + StrNCpy(ret_path, my_exec_path, MAXPGPATH); + trim_directory(ret_path); + trim_directory(ret_path); + strcat(ret_path, "/include"); + } + else + StrNCpy(ret_path, INCLUDEDIR, MAXPGPATH); +} + + + +/* + * get_pkginclude_path + */ +void +get_pkginclude_path(const char *my_exec_path, char *ret_path) +{ + if (relative_path(PGBINDIR, PKGINCLUDEDIR)) + { + StrNCpy(ret_path, my_exec_path, MAXPGPATH); + trim_directory(ret_path); + trim_directory(ret_path); + strcat(ret_path, "/include"); + } + else + StrNCpy(ret_path, PKGINCLUDEDIR, MAXPGPATH); +} + + + +/* + * get_pkglib_path + * + * Return library path, either relative to /bin or hardcoded + */ +void +get_pkglib_path(const char *my_exec_path, char *ret_path) +{ + if (relative_path(PGBINDIR, PKGLIBDIR)) + { + StrNCpy(ret_path, my_exec_path, MAXPGPATH); + trim_directory(ret_path); + trim_directory(ret_path); + strcat(ret_path, "/lib"); + } + else + StrNCpy(ret_path, PKGLIBDIR, MAXPGPATH); +} + + + +/* + * relative_path + * + * Do the supplied paths differ only in their last component? + */ +static bool +relative_path(const char *path1, const char *path2) +{ + +#ifdef WIN32 + /* Driver letters match? */ + if (isalpha(*path1) && path1[1] == ':' && + (!isalpha(*path2) || !path2[1] == ':')) + return false; + if ((!isalpha(*path1) || !path1[1] == ':') && + (isalpha(*path2) && path2[1] == ':') + return false; + if (isalpha(*path1) && path1[1] == ':' && + isalpha(*path2) && path2[1] == ':') + { + if (toupper(*path1) != toupper(*path2)) + return false; + path1 += 2; + path2 += 2; + } +#endif + + while (1) + { + /* Move past adjacent slashes like //, and trailing ones */ + MOVE_TO_SEP_END(path1); + MOVE_TO_SEP_END(path2); + + /* One of the paths is done? */ + if (!*path1 || !*path2) + break; + + /* Win32 filesystem is case insensitive */ +#ifndef WIN32 + if (*path1 != *path2) +#else + if (toupper((unsigned char) *path1) != toupper((unsigned char)*path2)) +#endif + break; + + path1++; + path2++; + } + + /* both done, identical? */ + if (!*path1 && !*path2) + return false; + + /* advance past directory name */ + while (!ISSEP(*path1) && *path1) + path1++; + while (!ISSEP(*path2) && *path2) + path2++; + + MOVE_TO_SEP_END(path1); + MOVE_TO_SEP_END(path2); + + /* Are both strings done? */ + if (!*path1 && !*path2) + return true; + else + return false; +} + + +/* + * trim_directory + * + * Trim trailing directory from path + */ +static void +trim_directory(char *path) +{ + char *p; + + if (path[0] == '\0') + return; + + for (p = path + strlen(path) - 1; ISSEP(*p) && p > path; p--) + ; + for (; !ISSEP(*p) && p > path; p--) + ; + *p = '\0'; + return; +} + + + +/* + * trim_trailing_separator + */ +static void +trim_trailing_separator(char *path) +{ + char *p = path + strlen(path); + + /* trim off trailing slashes */ + if (p > path) + for (p--; p >= path && ISSEP(*p); p--) + *p = '\0'; +} + |
