I have reorganized the code to allow path-relative installs.  A relative
path is used if only the last directory of a path is different from the
hardcoded binary directory.  For example, /a/b/c is relative to /a/b/d,
but /a/b/c is not relative to /a/f/g.

If the install used relative paths, then the system will use the current
binary directory, strip the /bin part, and add /lib or /share as
appropriate.

I also created new get_* functions to access compiled-in paths and
adjusted if relative installs are to be used.

I cleaned up substitute_libpath_macro() code.

I will do some doc updates now for the install file.

Patch attached and applied.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.387
diff -c -c -r1.387 postmaster.c
*** src/backend/postmaster/postmaster.c 14 May 2004 17:04:44 -0000      1.387
--- src/backend/postmaster/postmaster.c 17 May 2004 14:25:35 -0000
***************
*** 697,702 ****
--- 697,704 ----
                ereport(FATAL,
                                (errmsg("%s: could not locate my own executable path",
                                                progname)));
+       if (strlen(pkglib_path) == 0)
+               get_pkglib_path(my_exec_path, pkglib_path);
  
  #ifdef EXEC_BACKEND
        if (find_other_exec(argv[0], "postgres", PG_VERSIONSTR, postgres_exec_path) < 
0)
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.406
diff -c -c -r1.406 postgres.c
*** src/backend/tcop/postgres.c 14 May 2004 17:04:45 -0000      1.406
--- src/backend/tcop/postgres.c 17 May 2004 14:25:38 -0000
***************
*** 2652,2657 ****
--- 2652,2660 ----
                        ereport(FATAL,
                                        (errmsg("%s: could not locate postgres 
executable",
                                                        argv[0])));
+               if (strlen(pkglib_path) == 0)
+                       get_pkglib_path(my_exec_path, pkglib_path);
+                       
                /*
                 * Validate we have been given a reasonable-looking DataDir (if
                 * under postmaster, assume postmaster did this already).
Index: src/backend/utils/fmgr/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/fmgr/Makefile,v
retrieving revision 1.15
diff -c -c -r1.15 Makefile
*** src/backend/utils/fmgr/Makefile     23 Dec 2003 21:56:20 -0000      1.15
--- src/backend/utils/fmgr/Makefile     17 May 2004 14:25:38 -0000
***************
*** 14,20 ****
  
  OBJS = dfmgr.o fmgr.o funcapi.o
  
! override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
  
  
  all: SUBSYS.o
--- 14,20 ----
  
  OBJS = dfmgr.o fmgr.o funcapi.o
  
! override CPPFLAGS += -DDLSUFFIX=\"$(DLSUFFIX)\"
  
  
  all: SUBSYS.o
Index: src/backend/utils/fmgr/dfmgr.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/fmgr/dfmgr.c,v
retrieving revision 1.71
diff -c -c -r1.71 dfmgr.c
*** src/backend/utils/fmgr/dfmgr.c      9 Mar 2004 05:06:45 -0000       1.71
--- src/backend/utils/fmgr/dfmgr.c      17 May 2004 14:25:39 -0000
***************
*** 270,281 ****
  #error "DLSUFFIX must be defined to compile this file."
  #endif
  
- /* Example format: "/usr/local/pgsql/lib" */
- #ifndef PKGLIBDIR
- #error "PKGLIBDIR needs to be defined to compile this file."
- #endif
- 
- 
  /*
   * If name contains a slash, check if the file exists, if so return
   * the name.  Else (no slash) try to expand using search path (see
--- 270,275 ----
***************
*** 341,402 ****
  static char *
  substitute_libpath_macro(const char *name)
  {
!       size_t          macroname_len;
!       char       *replacement = NULL;
! #ifdef WIN32
!       char            basename[MAXPGPATH];
! #endif
! 
        AssertArg(name != NULL);
  
        if (name[0] != '$')
                return pstrdup(name);
  
! #ifndef WIN32
!       macroname_len = strcspn(name + 1, "/") + 1;
! #else
!       macroname_len = strcspn(name + 1, "/\\") + 1;
! #endif
! 
!       if (strncmp(name, "$libdir", macroname_len) == 0)
! #ifndef WIN32
!               replacement = PKGLIBDIR;
! #else
!       {
!               char *p;
!               if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0)
!                       ereport(FATAL,
!                                       (errmsg("GetModuleFileName failed 
(%i)",(int)GetLastError())));
! 
!               canonicalize_path(basename);
!               if ((p = last_path_separator(basename)) == NULL)
!                       ereport(FATAL,
!                                       (errmsg("unexpected failure in determining 
PKGLIBDIR (%s)",basename)));
!               else
!                       *p = '\0';
! 
!               strcat(basename,"/../lib");
!               replacement = basename;
!       }
! #endif
!       else
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_NAME),
                                 errmsg("invalid macro name in dynamic library 
path")));
  
!       if (name[macroname_len] == '\0')
!               return pstrdup(replacement);
!       else
!       {
!               char       *new;
  
!               new = palloc(strlen(replacement) + (strlen(name) - macroname_len) + 1);
  
!               strcpy(new, replacement);
!               strcat(new, name + macroname_len);
! 
!               return new;
!       }
  }
  
  
--- 335,363 ----
  static char *
  substitute_libpath_macro(const char *name)
  {
!       const char *sep_ptr;
!       char       *ret;
!       
        AssertArg(name != NULL);
  
        if (name[0] != '$')
                return pstrdup(name);
  
!       if ((sep_ptr = first_path_separator(name)) == NULL)
!               sep_ptr = name + strlen(name);
!               
!       if (strlen("$libdir") != sep_ptr - name ||
!               strncmp(name, "$libdir", strlen("$libdir")) != 0)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_NAME),
                                 errmsg("invalid macro name in dynamic library 
path")));
  
!       ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1);
  
!       strcpy(ret, pkglib_path);
!       strcat(ret, sep_ptr);
  
!       return ret;
  }
  
  
Index: src/backend/utils/init/globals.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/init/globals.c,v
retrieving revision 1.85
diff -c -c -r1.85 globals.c
*** src/backend/utils/init/globals.c    13 May 2004 22:45:03 -0000      1.85
--- src/backend/utils/init/globals.c    17 May 2004 14:25:39 -0000
***************
*** 46,51 ****
--- 46,52 ----
  char          OutputFileName[MAXPGPATH];
  
  char          my_exec_path[MAXPGPATH];        /* full path to postgres executable */
+ char          pkglib_path[MAXPGPATH]; /* full path to lib directory */
  
  BackendId     MyBackendId;
  
Index: src/bin/initdb/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/Makefile,v
retrieving revision 1.37
diff -c -c -r1.37 Makefile
*** src/bin/initdb/Makefile     11 May 2004 21:57:14 -0000      1.37
--- src/bin/initdb/Makefile     17 May 2004 14:25:40 -0000
***************
*** 13,19 ****
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! override CPPFLAGS := -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) 
$(CPPFLAGS)
  
  OBJS= initdb.o \
        $(filter exec.o, $(LIBOBJS))
--- 13,19 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
  
  OBJS= initdb.o \
        $(filter exec.o, $(LIBOBJS))
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.30
diff -c -c -r1.30 initdb.c
*** src/bin/initdb/initdb.c     17 May 2004 13:17:29 -0000      1.30
--- src/bin/initdb/initdb.c     17 May 2004 14:25:41 -0000
***************
*** 69,79 ****
  
  /*
   * these values are passed in by makefile defines
-  *
-  * Note that "datadir" is not the directory we're going to initialize,
-  * it's merely how Autoconf names PREFIX/share.
   */
! char     *datadir = PGDATADIR;
  
  /* values to be obtained from arguments */
  char     *pg_data = "";
--- 69,76 ----
  
  /*
   * these values are passed in by makefile defines
   */
! char          *share_path = NULL;
  
  /* values to be obtained from arguments */
  char     *pg_data = "";
***************
*** 129,135 ****
  
  
  /* path to 'initdb' binary directory */
! char     bindir[MAXPGPATH];
  char     backend_exec[MAXPGPATH];
  
  static void *xmalloc(size_t size);
--- 126,132 ----
  
  
  /* path to 'initdb' binary directory */
! char     bin_path[MAXPGPATH];
  char     backend_exec[MAXPGPATH];
  
  static void *xmalloc(size_t size);
***************
*** 730,737 ****
  static void
  set_input(char **dest, char *filename)
  {
!       *dest = xmalloc(strlen(datadir) + strlen(filename) + 2);
!       sprintf(*dest, "%s/%s", datadir, filename);
  }
  
  /*
--- 727,734 ----
  static void
  set_input(char **dest, char *filename)
  {
!       *dest = xmalloc(strlen(share_path) + strlen(filename) + 2);
!       sprintf(*dest, "%s/%s", share_path, filename);
  }
  
  /*
***************
*** 1849,1855 ****
                                printf(_("Running in noclean mode.  Mistakes will not 
be cleaned up.\n"));
                                break;
                        case 'L':
!                               datadir = xstrdup(optarg);
                                break;
                        case 1:
                                locale = xstrdup(optarg);
--- 1846,1852 ----
                                printf(_("Running in noclean mode.  Mistakes will not 
be cleaned up.\n"));
                                break;
                        case 'L':
!                               share_path = xstrdup(optarg);
                                break;
                        case 1:
                                locale = xstrdup(optarg);
***************
*** 1951,1959 ****
        }
  
        /* store binary directory */
!       strcpy(bindir, backend_exec);
!       *last_path_separator(bindir) = '\0';
!       
        if ((short_version = get_short_version()) == NULL)
        {
                fprintf(stderr, _("%s: could not determine valid short version 
string\n"), progname);
--- 1948,1962 ----
        }
  
        /* store binary directory */
!       strcpy(bin_path, backend_exec);
!       *last_path_separator(bin_path) = '\0';
! 
!       if (!share_path)
!       {
!               share_path = xmalloc(MAXPGPATH);
!               get_share_path(backend_exec, share_path);
!       }
! 
        if ((short_version = get_short_version()) == NULL)
        {
                fprintf(stderr, _("%s: could not determine valid short version 
string\n"), progname);
***************
*** 1983,1995 ****
        {
                fprintf(stderr,
                                "VERSION=%s\n"
!                               "PGDATA=%s\ndatadir=%s\nPGPATH=%s\n"
                                "ENCODING=%s\nENCODINGID=%s\n"
                                "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
                                "POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
                                "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
                                PG_VERSION,
!                               pg_data, datadir, bindir,
                                encoding, encodingid,
                                username, bki_file,
                                desc_file, conf_file,
--- 1986,1998 ----
        {
                fprintf(stderr,
                                "VERSION=%s\n"
!                               "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
                                "ENCODING=%s\nENCODINGID=%s\n"
                                "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
                                "POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
                                "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
                                PG_VERSION,
!                               pg_data, share_path, bin_path,
                                encoding, encodingid,
                                username, bki_file,
                                desc_file, conf_file,
***************
*** 2182,2189 ****
                   "    %s%s%s/postmaster -D %s%s%s\n"
                   "or\n"
                   "    %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
!                QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
!               QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
  
        return 0;
  }
--- 2185,2192 ----
                   "    %s%s%s/postmaster -D %s%s%s\n"
                   "or\n"
                   "    %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
!                QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
!               QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
  
        return 0;
  }
Index: src/bin/psql/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/Makefile,v
retrieving revision 1.43
diff -c -c -r1.43 Makefile
*** src/bin/psql/Makefile       26 Apr 2004 17:40:48 -0000      1.43
--- src/bin/psql/Makefile       17 May 2004 14:25:41 -0000
***************
*** 15,25 ****
  
  REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
  
! override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND 
-DSYSCONFDIR='"$(sysconfdir)"'
  
  OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
        startup.o prompt.o variables.o large_obj.o print.o describe.o \
!       psqlscan.o tab-complete.o mbprint.o
  
  FLEXFLAGS = -Cfe
  
--- 15,26 ----
  
  REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
  
! override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND
  
  OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
        startup.o prompt.o variables.o large_obj.o print.o describe.o \
!       psqlscan.o tab-complete.o mbprint.o \
!       $(filter exec.o, $(LIBOBJS))
  
  FLEXFLAGS = -Cfe
  
***************
*** 29,34 ****
--- 30,38 ----
  psql: $(OBJS) $(libpq_builddir)/libpq.a
        $(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o [EMAIL PROTECTED](X)
  
+ exec.c: % : $(top_srcdir)/src/port/%
+       rm -f $@ && $(LN_S) $< .
+ 
  help.o: $(srcdir)/sql_help.h
  
  ifdef PERL
***************
*** 60,66 ****
  
  # psqlscan.c is in the distribution tarball, so is not cleaned here
  clean distclean:
!       rm -f psql$(X) $(OBJS)
  
  maintainer-clean: distclean
        rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
--- 64,70 ----
  
  # psqlscan.c is in the distribution tarball, so is not cleaned here
  clean distclean:
!       rm -f psql$(X) $(OBJS) exec.c
  
  maintainer-clean: distclean
        rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.92
diff -c -c -r1.92 startup.c
*** src/bin/psql/startup.c      2 May 2004 04:25:45 -0000       1.92
--- src/bin/psql/startup.c      17 May 2004 14:25:41 -0000
***************
*** 74,80 ****
  
  static void parse_psql_options(int argc, char *argv[],
                                   struct adhoc_opts * options);
! static void process_psqlrc(void);
  static void process_psqlrc_file(char *filename);
  static void showVersion(void);
  
--- 74,80 ----
  
  static void parse_psql_options(int argc, char *argv[],
                                   struct adhoc_opts * options);
! static void process_psqlrc(char *argv0);
  static void process_psqlrc_file(char *filename);
  static void showVersion(void);
  
***************
*** 239,245 ****
        if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
        {
                if (!options.no_psqlrc)
!                       process_psqlrc();
  
                successResult = process_file(options.action_string);
        }
--- 239,245 ----
        if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
        {
                if (!options.no_psqlrc)
!                       process_psqlrc(argv[0]);
  
                successResult = process_file(options.action_string);
        }
***************
*** 305,311 ****
                SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
  
                if (!options.no_psqlrc)
!                       process_psqlrc();
                if (!pset.notty)
                        initializeInput(options.no_readline ? 0 : 1);
                if (options.action_string)              /* -f - was used */
--- 305,311 ----
                SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
  
                if (!options.no_psqlrc)
!                       process_psqlrc(argv[0]);
                if (!pset.notty)
                        initializeInput(options.no_readline ? 0 : 1);
                if (options.action_string)              /* -f - was used */
***************
*** 567,588 ****
  
  }
  
- #ifndef SYSCONFDIR
- #error "You must compile this file with SYSCONFDIR defined."
- #endif
- 
  
  /*
   * Load .psqlrc file, if found.
   */
  static void
! process_psqlrc(void)
  {
-       char       *globalFile = SYSCONFDIR "/" SYSPSQLRC;
        char       *home;
        char       *psqlrc;
  
!       process_psqlrc_file(globalFile);
  
        if ((home = getenv("HOME")) != NULL)
        {
--- 567,590 ----
  
  }
  
  
  /*
   * Load .psqlrc file, if found.
   */
  static void
! process_psqlrc(char *argv0)
  {
        char       *home;
        char       *psqlrc;
+       char       global_file[MAXPGPATH];
+       char       my_exec_path[MAXPGPATH];
+       char       etc_path[MAXPGPATH];
+ 
+       find_my_exec(argv0, my_exec_path);
+       get_etc_path(my_exec_path, etc_path);
  
!       snprintf(global_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
!       process_psqlrc_file(global_file);
  
        if ((home = getenv("HOME")) != NULL)
        {
Index: src/include/miscadmin.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/miscadmin.h,v
retrieving revision 1.158
diff -c -c -r1.158 miscadmin.h
*** src/include/miscadmin.h     13 May 2004 22:45:04 -0000      1.158
--- src/include/miscadmin.h     17 May 2004 14:25:42 -0000
***************
*** 143,148 ****
--- 143,149 ----
  
  extern char OutputFileName[];
  extern char my_exec_path[];
+ extern char pkglib_path[];
  
  /*
   * done in storage/backendid.h for now.
Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.31
diff -c -c -r1.31 port.h
*** src/include/port.h  14 May 2004 17:04:47 -0000      1.31
--- src/include/port.h  17 May 2004 14:25:42 -0000
***************
*** 26,37 ****
  extern char *last_path_separator(const char *filename);
  extern void canonicalize_path(char *path);
  extern const char *get_progname(const char *argv0);
  
  /* Portable way to find binaries */
  extern int find_my_exec(const char *argv0, char *full_path);
  extern int find_other_exec(const char *argv0, char const *target,
                                                   const char *versionstr, char 
*retpath);
- 
  #if defined(__CYGWIN__) || defined(WIN32)
  #define EXE ".exe"
  #define DEVNULL "nul"
--- 26,42 ----
  extern char *last_path_separator(const char *filename);
  extern void canonicalize_path(char *path);
  extern const char *get_progname(const char *argv0);
+ extern void get_share_path(const char *my_exec_path, char *ret_path);
+ extern void get_etc_path(const char *my_exec_path, char *ret_path);
+ extern void get_include_path(const char *my_exec_path, char *ret_path);
+ extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
+ extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
+ 
  
  /* Portable way to find binaries */
  extern int find_my_exec(const char *argv0, char *full_path);
  extern int find_other_exec(const char *argv0, char const *target,
                                                   const char *versionstr, char 
*retpath);
  #if defined(__CYGWIN__) || defined(WIN32)
  #define EXE ".exe"
  #define DEVNULL "nul"
***************
*** 179,191 ****
                                char *buffer, size_t buflen,
                                struct hostent **result,
                                int *herrno);
- 
- /* $PATH (or %PATH%) path separator */
- #ifdef WIN32
- #define PATHSEP ';'
- #else
- #define PATHSEP ':'
- #endif
  
  /* FIXME: [win32] Placeholder win32 replacements, to allow continued development */
  #ifdef WIN32
--- 184,189 ----
Index: src/interfaces/ecpg/preproc/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/preproc/Makefile,v
retrieving revision 1.103
diff -c -c -r1.103 Makefile
*** src/interfaces/ecpg/preproc/Makefile        30 Apr 2004 04:14:06 -0000      1.103
--- src/interfaces/ecpg/preproc/Makefile        17 May 2004 14:25:43 -0000
***************
*** 11,18 ****
  override CPPFLAGS := -I$(srcdir)/../include -I$(srcdir) $(CPPFLAGS) \
        -DMAJOR_VERSION=$(MAJOR_VERSION) \
        -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
-       -DINCLUDEDIR=\"$(includedir)\" \
-       -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
        -DFRONTEND
  
  ifeq ($(GCC), yes)
--- 11,16 ----
***************
*** 20,34 ****
  endif
  override CFLAGS += $(PTHREAD_CFLAGS)
  
! OBJS=preproc.o type.o ecpg.o ecpg_keywords.o output.o\
!     keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o
! 
  
  all: submake-libpgport ecpg
  
  ecpg: $(OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o [EMAIL PROTECTED](X)
  
  # pgc is compiled as part of preproc
  preproc.o: $(srcdir)/pgc.c
  
--- 18,35 ----
  endif
  override CFLAGS += $(PTHREAD_CFLAGS)
  
! OBJS= preproc.o type.o ecpg.o ecpg_keywords.o output.o\
!       keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
!       $(filter exec.o, $(LIBOBJS))
  
  all: submake-libpgport ecpg
  
  ecpg: $(OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o [EMAIL PROTECTED](X)
  
+ exec.c: % : $(top_srcdir)/src/port/%
+       rm -f $@ && $(LN_S) $< .
+ 
  # pgc is compiled as part of preproc
  preproc.o: $(srcdir)/pgc.c
  
***************
*** 65,71 ****
        rm -f $(DESTDIR)$(bindir)/ecpg$(X)
  
  clean distclean:
!       rm -f *.o ecpg$(X)
  # garbage from partial builds
        @rm -f y.tab.c y.tab.h
  # garbage from development
--- 66,72 ----
        rm -f $(DESTDIR)$(bindir)/ecpg$(X)
  
  clean distclean:
!       rm -f *.o ecpg$(X) exec.c
  # garbage from partial builds
        @rm -f y.tab.c y.tab.h
  # garbage from development
Index: src/interfaces/ecpg/preproc/ecpg.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/preproc/ecpg.c,v
retrieving revision 1.86
diff -c -c -r1.86 ecpg.c
*** src/interfaces/ecpg/preproc/ecpg.c  12 May 2004 13:38:48 -0000      1.86
--- src/interfaces/ecpg/preproc/ecpg.c  17 May 2004 14:25:43 -0000
***************
*** 120,126 ****
                                out_option = 0;
        struct _include_path *ip;
        const char *progname;
! 
        progname = get_progname(argv[0]);
  
        if (argc > 1)
--- 120,128 ----
                                out_option = 0;
        struct _include_path *ip;
        const char *progname;
!       char       my_exec_path[MAXPGPATH];
!       char       include_path[MAXPGPATH];
!       
        progname = get_progname(argv[0]);
  
        if (argc > 1)
***************
*** 138,143 ****
--- 140,147 ----
                }
        }
  
+       find_my_exec(argv[0], my_exec_path);
+ 
        while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:h")) != -1)
        {
                switch (c)
***************
*** 175,186 ****
                        case 'C':
                                if (strncmp(optarg, "INFORMIX", strlen("INFORMIX")) == 
0)
                                {
                                        compat = (strcmp(optarg, "INFORMIX") == 0) ? 
ECPG_COMPAT_INFORMIX : ECPG_COMPAT_INFORMIX_SE;
                                        /* system_includes = true; */
                                        add_preprocessor_define("dec_t=decimal");
                                        add_preprocessor_define("intrvl_t=interval");
                                        add_preprocessor_define("dtime_t=timestamp");
!                                       add_include_path(PKGINCLUDEDIR 
"/informix/esql");
                                }
                                else
                                {
--- 179,196 ----
                        case 'C':
                                if (strncmp(optarg, "INFORMIX", strlen("INFORMIX")) == 
0)
                                {
+                                       char       pkginclude_path[MAXPGPATH];
+                                       char       informix_path[MAXPGPATH];
+                               
                                        compat = (strcmp(optarg, "INFORMIX") == 0) ? 
ECPG_COMPAT_INFORMIX : ECPG_COMPAT_INFORMIX_SE;
                                        /* system_includes = true; */
                                        add_preprocessor_define("dec_t=decimal");
                                        add_preprocessor_define("intrvl_t=interval");
                                        add_preprocessor_define("dtime_t=timestamp");
! 
!                                       get_pkginclude_path(my_exec_path, 
pkginclude_path);
!                                       snprintf(informix_path, MAXPGPATH, 
"%s/informix/esql", pkginclude_path);
!                                       add_include_path(informix_path);
                                }
                                else
                                {
***************
*** 216,222 ****
  
        add_include_path(".");
        add_include_path("/usr/local/include");
!       add_include_path(INCLUDEDIR);
        add_include_path("/usr/include");
  
        if (verbose)
--- 226,233 ----
  
        add_include_path(".");
        add_include_path("/usr/local/include");
!       get_include_path(my_exec_path, include_path);
!       add_include_path(include_path);
        add_include_path("/usr/include");
  
        if (verbose)
Index: src/interfaces/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/Makefile,v
retrieving revision 1.105
diff -c -c -r1.105 Makefile
*** src/interfaces/libpq/Makefile       10 May 2004 23:09:04 -0000      1.105
--- src/interfaces/libpq/Makefile       17 May 2004 14:25:43 -0000
***************
*** 19,25 ****
  SO_MINOR_VERSION= 2
  
  override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(PTHREAD_CFLAGS) -DFRONTEND 
-DSYSCONFDIR='"$(sysconfdir)"'
! override CFLAGS += $(PTHREAD_CFLAGS)
  
  OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
        fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
--- 19,31 ----
  SO_MINOR_VERSION= 2
  
  override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(PTHREAD_CFLAGS) -DFRONTEND 
-DSYSCONFDIR='"$(sysconfdir)"'
! override CFLAGS += $(PTHREAD_CFLAGS) \
!                    -DPGBINDIR=\"$(bindir)\" \
!                    -DPGDATADIR=\"$(datadir)\" \
!                    -DSYSCONFDIR='"$(sysconfdir)"' \
!                    -DINCLUDEDIR=\"$(includedir)\" \
!                    -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
!                    -DPKGLIBDIR=\"$(pkglibdir)\"
  
  OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
        fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
Index: src/port/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/Makefile,v
retrieving revision 1.10
diff -c -c -r1.10 Makefile
*** src/port/Makefile   23 Apr 2004 18:15:55 -0000      1.10
--- src/port/Makefile   17 May 2004 14:25:45 -0000
***************
*** 15,20 ****
--- 15,27 ----
  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
Index: src/port/exec.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/exec.c,v
retrieving revision 1.5
diff -c -c -r1.5 exec.c
*** src/port/exec.c     14 May 2004 17:04:48 -0000      1.5
--- src/port/exec.c     17 May 2004 14:25:45 -0000
***************
*** 25,30 ****
--- 25,37 ----
  
  #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,270 ****
--- 272,287 ----
  
        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
  }
  
  
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.7
diff -c -c -r1.7 path.c
*** src/port/path.c     12 May 2004 13:38:49 -0000      1.7
--- src/port/path.c     17 May 2004 14:25:45 -0000
***************
*** 16,21 ****
--- 16,39 ----
  #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,61 ****
  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
  }
  
  
--- 58,69 ----
  char *
  first_path_separator(const char *filename)
  {
!       char       *p;
  
!       for (p = (char *)filename; *p; p++)
!               if (ISSEP(*p))
!                       return p;
!       return NULL;
  }
  
  
***************
*** 65,86 ****
  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
  }
  
  
--- 73,84 ----
  char *
  last_path_separator(const char *filename)
  {
!       char       *p, *ret = NULL;
  
!       for (p = (char *)filename; *p; p++)
!               if (ISSEP(*p))
!                       ret = p;
!       return ret;
  }
  
  
***************
*** 96,112 ****
  void
  canonicalize_path(char *path)
  {
        char       *p;
  
        for (p = path; *p; p++)
        {
- #ifdef WIN32
                if (*p == '\\')
                        *p = '/';
- #endif
        }
!       if (p > path+1 && *--p == '/')
!               *p = '\0';
  }
  
  
--- 94,110 ----
  void
  canonicalize_path(char *path)
  {
+ #ifdef WIN32
        char       *p;
  
        for (p = path; *p; p++)
        {
                if (*p == '\\')
                        *p = '/';
        }
! #endif
! 
!       trim_trailing_separator(path);
  }
  
  
***************
*** 120,124 ****
--- 118,328 ----
                return argv0;
        else
                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';
  }
  
Index: src/timezone/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/timezone/Makefile,v
retrieving revision 1.7
diff -c -c -r1.7 Makefile
*** src/timezone/Makefile       30 Apr 2004 20:23:28 -0000      1.7
--- src/timezone/Makefile       17 May 2004 14:25:45 -0000
***************
*** 12,19 ****
  top_builddir = ../..
  include $(top_builddir)/src/Makefile.global
  
- override CPPFLAGS += -DPGDATADIR=\"$(datadir)\"
- 
  OBJS= asctime.o difftime.o localtime.o pgtz.o
  ZICOBJS= zic.o ialloc.o scheck.o localtime.o asctime.o pgtz.o
  
--- 12,17 ----
Index: src/timezone/pgtz.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/timezone/pgtz.c,v
retrieving revision 1.7
diff -c -c -r1.7 pgtz.c
*** src/timezone/pgtz.c 2 May 2004 03:12:12 -0000       1.7
--- src/timezone/pgtz.c 17 May 2004 14:25:45 -0000
***************
*** 25,46 ****
        if (done_tzdir)
                return tzdir;
  
! #ifndef WIN32
!       StrNCpy(tzdir, PGDATADIR, MAXPGPATH);
! #else
!       if (GetModuleFileName(NULL, tzdir, MAXPGPATH) == 0)
!               return NULL;
! #endif
! 
!       canonicalize_path(tzdir);
! #ifdef WIN32
!       /* trim off binary name, then go up a directory */
!       if ((p = last_path_separator(tzdir)) == NULL)
!               return NULL;
!       else
!               *p = '\0';
!       strcat(tzdir, "/../share");
! #endif
        strcat(tzdir, "/timezone");
  
        done_tzdir = 1;
--- 25,31 ----
        if (done_tzdir)
                return tzdir;
  
!       get_share_dir(my_exec_path, tzdir);
        strcat(tzdir, "/timezone");
  
        done_tzdir = 1;
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to