Allow relative path installs - Mailing list pgsql-patches

From Bruce Momjian
Subject Allow relative path installs
Date
Msg-id 200405171441.i4HEfw818421@candle.pha.pa.us
Whole thread Raw
List pgsql-patches
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
  pgman@candle.pha.pa.us               |  (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 $@$(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 $@$(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 $@$(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;

pgsql-patches by date:

Previous
From: Fabien COELHO
Date:
Subject: Re: new aggregate functions v1
Next
From: Andrew Hammond
Date:
Subject: Re: pg_ctl patch to integrate apache's rotatelogs