Thread: Relocatable locale

Relocatable locale

From
Bruce Momjian
Date:
Magnus found out that LOCALEDIR wasn't being handled in a relocatable
manner.

This patch fixes that.  It also adjusts the get_*_path functions to
limit values to MAXPGPATH.

I have two questions.  First, setlocale() seemed to be inconsistently
set inside and outside of ENABLE_NLS.  I assume the proper location is
inside.   Second, libpq has a locale setting for error messages, but a
libpq program could be in any directory, so I see no way to make that
relocatable.  Instead, I just use the hardcoded path.  I could make it
relocatable, but that seems to error-prone, plus I would have to look up
the exec path and stuff, and it seemed too complicated.

--
  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/main/main.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/main/main.c,v
retrieving revision 1.81
diff -c -c -r1.81 main.c
*** src/backend/main/main.c    24 May 2004 02:47:44 -0000    1.81
--- src/backend/main/main.c    25 May 2004 00:54:53 -0000
***************
*** 150,155 ****
--- 150,157 ----
       * startup error messages to be localized.
       */

+     set_pglocale(argv[0], "postgres");
+
  #ifdef WIN32
      /*
       * Windows uses codepages rather than the environment, so we work around
***************
*** 184,194 ****
      setlocale(LC_MONETARY, "C");
      setlocale(LC_NUMERIC, "C");
      setlocale(LC_TIME, "C");
-
- #ifdef ENABLE_NLS
-     bindtextdomain("postgres", LOCALEDIR);
-     textdomain("postgres");
- #endif

      /*
       * Skip permission checks if we're just trying to do --help or
--- 186,191 ----
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.32
diff -c -c -r1.32 initdb.c
*** src/bin/initdb/initdb.c    18 May 2004 03:36:36 -0000    1.32
--- src/bin/initdb/initdb.c    25 May 2004 00:54:56 -0000
***************
*** 167,173 ****
  static bool chklocale(const char *locale);
  static void setlocales(void);
  static void usage(const char *progname);
! static void init_nls(void);


  /*
--- 167,173 ----
  static bool chklocale(const char *locale);
  static void setlocales(void);
  static void usage(const char *progname);
! static void init_nls(const char *argv0);


  /*
***************
*** 1754,1766 ****
   * Initialized NLS if enabled.
   */
  static void
! init_nls(void)
  {
! #ifdef ENABLE_NLS
!         setlocale(LC_ALL, "");
!         bindtextdomain("initdb", LOCALEDIR);
!         textdomain("initdb");
! #endif
  }


--- 1754,1762 ----
   * Initialized NLS if enabled.
   */
  static void
! init_nls(const char *argv0)
  {
!     set_pglocale(argv0, "initdb");
  }


***************
*** 1801,1807 ****
                                   * environment */
      char       *subdirs[] =
      {"global", "pg_xlog", "pg_clog", "base", "base/1"};
!     init_nls();

      progname = get_progname(argv[0]);

--- 1797,1803 ----
                                   * environment */
      char       *subdirs[] =
      {"global", "pg_xlog", "pg_clog", "base", "base/1"};
!     init_nls(argv[0]);

      progname = get_progname(argv[0]);

Index: src/bin/pg_controldata/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_controldata/Makefile,v
retrieving revision 1.7
diff -c -c -r1.7 Makefile
*** src/bin/pg_controldata/Makefile    30 Apr 2004 20:01:39 -0000    1.7
--- src/bin/pg_controldata/Makefile    25 May 2004 00:54:56 -0000
***************
*** 14,20 ****

  override CPPFLAGS += -DFRONTEND

! OBJS= pg_controldata.o pg_crc.o

  all: submake-libpgport pg_controldata

--- 14,20 ----

  override CPPFLAGS += -DFRONTEND

! OBJS= pg_controldata.o pg_crc.o exec.o

  all: submake-libpgport pg_controldata

***************
*** 24,29 ****
--- 24,32 ----
  pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c
      rm -f $@ && $(LN_S) $< .

+ exec.c: % : $(top_srcdir)/src/port/%
+     rm -f $@ && $(LN_S) $< .
+
  install: all installdirs
      $(INSTALL_PROGRAM) pg_controldata$(X) $(DESTDIR)$(bindir)/pg_controldata$(X)

***************
*** 34,37 ****
      rm -f $(DESTDIR)$(bindir)/pg_controldata$(X)

  clean distclean maintainer-clean:
!     rm -f pg_controldata$(X) pg_controldata.o pg_crc.o pg_crc.c
--- 37,40 ----
      rm -f $(DESTDIR)$(bindir)/pg_controldata$(X)

  clean distclean maintainer-clean:
!     rm -f pg_controldata$(X) pg_controldata.o pg_crc.o pg_crc.c exec.c
Index: src/bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.15
diff -c -c -r1.15 pg_controldata.c
*** src/bin/pg_controldata/pg_controldata.c    12 May 2004 13:38:43 -0000    1.15
--- src/bin/pg_controldata/pg_controldata.c    25 May 2004 00:54:57 -0000
***************
*** 77,87 ****
      char       *strftime_fmt = "%c";
      const char *progname;

!     setlocale(LC_ALL, "");
! #ifdef ENABLE_NLS
!     bindtextdomain("pg_controldata", LOCALEDIR);
!     textdomain("pg_controldata");
! #endif

      progname = get_progname(argv[0]);

--- 77,83 ----
      char       *strftime_fmt = "%c";
      const char *progname;

!     set_pglocale(argv[0], "pg_controldata");

      progname = get_progname(argv[0]);

Index: src/bin/pg_dump/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/Makefile,v
retrieving revision 1.51
diff -c -c -r1.51 Makefile
*** src/bin/pg_dump/Makefile    24 May 2004 01:01:37 -0000    1.51
--- src/bin/pg_dump/Makefile    25 May 2004 00:54:57 -0000
***************
*** 17,24 ****

  OBJS=    pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
      pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
!     dumputils.o
! PG_DUMPALL_OBJS = exec.o

  EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o

--- 17,23 ----

  OBJS=    pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
      pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
!     dumputils.o exec.o

  EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o

***************
*** 31,38 ****
  pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
      $(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

! pg_dumpall: pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(libpq_builddir)/libpq.a
!     $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

  # We need our own build of exec.c so it gets made with -DFRONTEND
  exec.c: % : $(top_srcdir)/src/port/%
--- 30,37 ----
  pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
      $(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

! pg_dumpall: pg_dumpall.o dumputils.o exec.o $(libpq_builddir)/libpq.a
!     $(CC) $(CFLAGS) pg_dumpall.o dumputils.o exec.o $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

  # We need our own build of exec.c so it gets made with -DFRONTEND
  exec.c: % : $(top_srcdir)/src/port/%
***************
*** 55,58 ****
      rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))

  clean distclean maintainer-clean:
!     rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) $(PG_DUMPALL_OBJS) pg_dump.o common.o pg_dump_sort.o
pg_restore.opg_dumpall.o exec.c 
--- 54,57 ----
      rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))

  clean distclean maintainer-clean:
!     rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o
pg_dumpall.oexec.c 
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.370
diff -c -c -r1.370 pg_dump.c
*** src/bin/pg_dump/pg_dump.c    24 Mar 2004 03:06:08 -0000    1.370
--- src/bin/pg_dump/pg_dump.c    25 May 2004 00:55:02 -0000
***************
*** 242,252 ****
      };
      int            optindex;

! #ifdef ENABLE_NLS
!     setlocale(LC_ALL, "");
!     bindtextdomain("pg_dump", LOCALEDIR);
!     textdomain("pg_dump");
! #endif

      g_verbose = false;

--- 242,248 ----
      };
      int            optindex;

!     set_pglocale(argv[0], "pg_dump");

      g_verbose = false;

Index: src/bin/pg_dump/pg_dumpall.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dumpall.c,v
retrieving revision 1.34
diff -c -c -r1.34 pg_dumpall.c
*** src/bin/pg_dump/pg_dumpall.c    19 May 2004 21:21:26 -0000    1.34
--- src/bin/pg_dump/pg_dumpall.c    25 May 2004 00:55:03 -0000
***************
*** 101,111 ****

      int            optindex;

! #ifdef ENABLE_NLS
!     setlocale(LC_ALL, "");
!     bindtextdomain("pg_dump", LOCALEDIR);
!     textdomain("pg_dump");
! #endif

      progname = get_progname(argv[0]);

--- 101,107 ----

      int            optindex;

!     set_pglocale(argv[0], "pg_dump");

      progname = get_progname(argv[0]);

Index: src/bin/pg_dump/pg_restore.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_restore.c,v
retrieving revision 1.56
diff -c -c -r1.56 pg_restore.c
*** src/bin/pg_dump/pg_restore.c    22 Apr 2004 02:39:10 -0000    1.56
--- src/bin/pg_dump/pg_restore.c    25 May 2004 00:55:03 -0000
***************
*** 121,131 ****
          {NULL, 0, NULL, 0}
      };

! #ifdef ENABLE_NLS
!     setlocale(LC_ALL, "");
!     bindtextdomain("pg_dump", LOCALEDIR);
!     textdomain("pg_dump");
! #endif

      opts = NewRestoreOptions();

--- 121,127 ----
          {NULL, 0, NULL, 0}
      };

!     set_pglocale(argv[0], "pg_dump");

      opts = NewRestoreOptions();

Index: src/bin/pg_resetxlog/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_resetxlog/Makefile,v
retrieving revision 1.9
diff -c -c -r1.9 Makefile
*** src/bin/pg_resetxlog/Makefile    24 May 2004 01:01:37 -0000    1.9
--- src/bin/pg_resetxlog/Makefile    25 May 2004 00:55:03 -0000
***************
*** 14,20 ****

  override CPPFLAGS += -DFRONTEND

! OBJS= pg_resetxlog.o pg_crc.o dirmod.o

  all: submake-libpgport pg_resetxlog

--- 14,20 ----

  override CPPFLAGS += -DFRONTEND

! OBJS= pg_resetxlog.o pg_crc.o dirmod.o exec.o

  all: submake-libpgport pg_resetxlog

***************
*** 27,32 ****
--- 27,35 ----
  pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c
      rm -f $@ && $(LN_S) $< .

+ exec.c: % : $(top_srcdir)/src/port/%
+     rm -f $@ && $(LN_S) $< .
+
  install: all installdirs
      $(INSTALL_PROGRAM) pg_resetxlog$(X) $(DESTDIR)$(bindir)/pg_resetxlog$(X)

***************
*** 37,40 ****
      rm -f $(DESTDIR)$(bindir)/pg_resetxlog$(X)

  clean distclean maintainer-clean:
!     rm -f pg_resetxlog$(X) pg_crc.c dirmod.c $(OBJS)
--- 40,43 ----
      rm -f $(DESTDIR)$(bindir)/pg_resetxlog$(X)

  clean distclean maintainer-clean:
!     rm -f pg_resetxlog$(X) pg_crc.c dirmod.c exec.c $(OBJS)
Index: src/bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.18
diff -c -c -r1.18 pg_resetxlog.c
*** src/bin/pg_resetxlog/pg_resetxlog.c    12 May 2004 13:38:44 -0000    1.18
--- src/bin/pg_resetxlog/pg_resetxlog.c    25 May 2004 00:55:03 -0000
***************
*** 102,112 ****
      int            fd;
      char        path[MAXPGPATH];

!     setlocale(LC_ALL, "");
! #ifdef ENABLE_NLS
!     bindtextdomain("pg_resetxlog", LOCALEDIR);
!     textdomain("pg_resetxlog");
! #endif

      progname = get_progname(argv[0]);

--- 102,108 ----
      int            fd;
      char        path[MAXPGPATH];

!     set_pglocale(argv[0], "pg_resetxlog");

      progname = get_progname(argv[0]);

Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.93
diff -c -c -r1.93 startup.c
*** src/bin/psql/startup.c    17 May 2004 14:35:33 -0000    1.93
--- src/bin/psql/startup.c    25 May 2004 00:55:04 -0000
***************
*** 102,112 ****
      char       *password = NULL;
      bool        need_pass;

!     setlocale(LC_ALL, "");
! #ifdef ENABLE_NLS
!     bindtextdomain("psql", LOCALEDIR);
!     textdomain("psql");
! #endif

      pset.progname = get_progname(argv[0]);

--- 102,108 ----
      char       *password = NULL;
      bool        need_pass;

!     set_pglocale(argv[0], "psql");

      pset.progname = get_progname(argv[0]);

Index: src/bin/scripts/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/Makefile,v
retrieving revision 1.26
diff -c -c -r1.26 Makefile
*** src/bin/scripts/Makefile    26 Apr 2004 17:40:48 -0000    1.26
--- src/bin/scripts/Makefile    25 May 2004 00:55:04 -0000
***************
*** 15,35 ****

  PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vacuumdb

! override CPPFLAGS := -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir) $(CPPFLAGS)

  all: submake-libpq submake-backend $(PROGRAMS)

  %: %.o
      $(CC) $(CFLAGS) $^ $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

! createdb: createdb.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! createlang: createlang.o common.o print.o mbprint.o
! createuser: createuser.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! dropdb: dropdb.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! droplang: droplang.o common.o print.o mbprint.o
! dropuser: dropuser.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! clusterdb: clusterdb.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! vacuumdb: vacuumdb.o common.o

  dumputils.c: % : $(top_srcdir)/src/bin/pg_dump/%
      rm -f $@ && $(LN_S) $< .
--- 15,38 ----

  PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vacuumdb

! override CPPFLAGS := -DFRONTEND -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir)
$(CPPFLAGS)

  all: submake-libpq submake-backend $(PROGRAMS)

  %: %.o
      $(CC) $(CFLAGS) $^ $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)

! createdb: createdb.o common.o exec.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! createlang: createlang.o common.o exec.o print.o mbprint.o
! createuser: createuser.o common.o exec.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! dropdb: dropdb.o common.o exec.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! droplang: droplang.o common.o exec.o print.o mbprint.o
! dropuser: dropuser.o common.o exec.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! clusterdb: clusterdb.o common.o exec.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
! vacuumdb: vacuumdb.o common.o exec.o
!
! exec.c: % : $(top_srcdir)/src/port/%
!     rm -f $@ && $(LN_S) $< .

  dumputils.c: % : $(top_srcdir)/src/bin/pg_dump/%
      rm -f $@ && $(LN_S) $< .
***************
*** 60,63 ****


  clean distclean maintainer-clean:
!     rm -f $(addsuffix $(X), $(PROGRAMS)) $(addsuffix .o, $(PROGRAMS)) common.o dumputils.o print.o mbprint.o
dumputils.cprint.c mbprint.c 
--- 63,66 ----


  clean distclean maintainer-clean:
!     rm -f $(addsuffix $(X), $(PROGRAMS)) $(addsuffix .o, $(PROGRAMS)) common.o dumputils.o print.o mbprint.o
dumputils.cexec.c print.c mbprint.c 
Index: src/bin/scripts/clusterdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/clusterdb.c,v
retrieving revision 1.6
diff -c -c -r1.6 clusterdb.c
*** src/bin/scripts/clusterdb.c    12 May 2004 13:38:46 -0000    1.6
--- src/bin/scripts/clusterdb.c    25 May 2004 00:55:04 -0000
***************
*** 58,64 ****
      char       *table = NULL;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "clusterdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqd:at:", long_options, &optindex)) != -1)
--- 58,64 ----
      char       *table = NULL;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "clusterdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqd:at:", long_options, &optindex)) != -1)
Index: src/bin/scripts/common.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/common.c,v
retrieving revision 1.7
diff -c -c -r1.7 common.c
*** src/bin/scripts/common.c    19 Apr 2004 17:42:59 -0000    1.7
--- src/bin/scripts/common.c    25 May 2004 00:55:04 -0000
***************
*** 51,63 ****
   * Initialized NLS if enabled.
   */
  void
! init_nls(void)
  {
! #ifdef ENABLE_NLS
!     setlocale(LC_ALL, "");
!     bindtextdomain("pgscripts", LOCALEDIR);
!     textdomain("pgscripts");
! #endif
  }


--- 51,59 ----
   * Initialized NLS if enabled.
   */
  void
! init_nls(const char *argv0)
  {
!     set_pglocale(argv0, "pgscripts");
  }


Index: src/bin/scripts/common.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/common.h,v
retrieving revision 1.6
diff -c -c -r1.6 common.h
*** src/bin/scripts/common.h    8 Aug 2003 04:52:21 -0000    1.6
--- src/bin/scripts/common.h    25 May 2004 00:55:04 -0000
***************
*** 11,17 ****
  const char *get_user_name(const char *progname);

  #define _(x) gettext((x))
! void        init_nls(void);

  typedef void (*help_handler) (const char *);

--- 11,17 ----
  const char *get_user_name(const char *progname);

  #define _(x) gettext((x))
! void        init_nls(const char *argv0);

  typedef void (*help_handler) (const char *);

Index: src/bin/scripts/createdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createdb.c,v
retrieving revision 1.8
diff -c -c -r1.8 createdb.c
*** src/bin/scripts/createdb.c    12 May 2004 13:38:47 -0000    1.8
--- src/bin/scripts/createdb.c    25 May 2004 00:55:04 -0000
***************
*** 60,66 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "createdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:WeqO:D:T:E:", long_options, &optindex)) != -1)
--- 60,66 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "createdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:WeqO:D:T:E:", long_options, &optindex)) != -1)
Index: src/bin/scripts/createlang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createlang.c,v
retrieving revision 1.9
diff -c -c -r1.9 createlang.c
*** src/bin/scripts/createlang.c    12 May 2004 13:38:47 -0000    1.9
--- src/bin/scripts/createlang.c    25 May 2004 00:55:04 -0000
***************
*** 61,67 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "createlang", help);

      while ((c = getopt_long(argc, argv, "lh:p:U:Wd:L:e", long_options, &optindex)) != -1)
--- 61,67 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "createlang", help);

      while ((c = getopt_long(argc, argv, "lh:p:U:Wd:L:e", long_options, &optindex)) != -1)
Index: src/bin/scripts/createuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createuser.c,v
retrieving revision 1.10
diff -c -c -r1.10 createuser.c
*** src/bin/scripts/createuser.c    12 May 2004 13:38:48 -0000    1.10
--- src/bin/scripts/createuser.c    25 May 2004 00:55:04 -0000
***************
*** 63,69 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "createuser", help);

      while ((c = getopt_long(argc, argv, "h:p:U:WeqaAdDi:PEN", long_options, &optindex)) != -1)
--- 63,69 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "createuser", help);

      while ((c = getopt_long(argc, argv, "h:p:U:WeqaAdDi:PEN", long_options, &optindex)) != -1)
Index: src/bin/scripts/dropdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropdb.c,v
retrieving revision 1.9
diff -c -c -r1.9 dropdb.c
*** src/bin/scripts/dropdb.c    12 May 2004 13:38:48 -0000    1.9
--- src/bin/scripts/dropdb.c    25 May 2004 00:55:04 -0000
***************
*** 51,57 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "dropdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
--- 51,57 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "dropdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
Index: src/bin/scripts/droplang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/droplang.c,v
retrieving revision 1.8
diff -c -c -r1.8 droplang.c
*** src/bin/scripts/droplang.c    12 May 2004 13:38:48 -0000    1.8
--- src/bin/scripts/droplang.c    25 May 2004 00:55:04 -0000
***************
*** 61,67 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "droplang", help);

      while ((c = getopt_long(argc, argv, "lh:p:U:Wd:e", long_options, &optindex)) != -1)
--- 61,67 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "droplang", help);

      while ((c = getopt_long(argc, argv, "lh:p:U:Wd:e", long_options, &optindex)) != -1)
Index: src/bin/scripts/dropuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropuser.c,v
retrieving revision 1.8
diff -c -c -r1.8 dropuser.c
*** src/bin/scripts/dropuser.c    12 May 2004 13:38:48 -0000    1.8
--- src/bin/scripts/dropuser.c    25 May 2004 00:55:04 -0000
***************
*** 51,57 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "dropuser", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
--- 51,57 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "dropuser", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
Index: src/bin/scripts/vacuumdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/vacuumdb.c,v
retrieving revision 1.6
diff -c -c -r1.6 vacuumdb.c
*** src/bin/scripts/vacuumdb.c    12 May 2004 13:38:48 -0000    1.6
--- src/bin/scripts/vacuumdb.c    25 May 2004 00:55:05 -0000
***************
*** 66,72 ****
      bool        verbose = false;

      progname = get_progname(argv[0]);
!     init_nls();
      handle_help_version_opts(argc, argv, "vacuumdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqd:zat:fv", long_options, &optindex)) != -1)
--- 66,72 ----
      bool        verbose = false;

      progname = get_progname(argv[0]);
!     init_nls(argv[0]);
      handle_help_version_opts(argc, argv, "vacuumdb", help);

      while ((c = getopt_long(argc, argv, "h:p:U:Weqd:zat:fv", long_options, &optindex)) != -1)
Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.37
diff -c -c -r1.37 port.h
*** src/include/port.h    21 May 2004 16:06:22 -0000    1.37
--- src/include/port.h    25 May 2004 00:55:05 -0000
***************
*** 31,36 ****
--- 31,38 ----
  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);
+ extern void get_locale_path(const char *my_exec_path, char *ret_path);
+ extern void set_pglocale(const char *argv0, const char *app);

  /*
   *    is_absolute_path
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.105
diff -c -c -r1.105 fe-misc.c
*** src/interfaces/libpq/fe-misc.c    15 Mar 2004 10:41:26 -0000    1.105
--- src/interfaces/libpq/fe-misc.c    25 May 2004 00:55:06 -0000
***************
*** 1131,1136 ****
--- 1131,1137 ----
      if (!already_bound)
      {
          already_bound = 1;
+         /* No relocatable lookup here because the binary could be anywhere */
          bindtextdomain("libpq", LOCALEDIR);
      }

Index: src/port/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/Makefile,v
retrieving revision 1.13
diff -c -c -r1.13 Makefile
*** src/port/Makefile    22 May 2004 02:15:08 -0000    1.13
--- src/port/Makefile    25 May 2004 00:55:06 -0000
***************
*** 37,42 ****
--- 37,43 ----
      echo "#define INCLUDEDIR \"$(includedir)\"" >>$@
      echo "#define PKGINCLUDEDIR \"$(pkgincludedir)\"" >>$@
      echo "#define PKGLIBDIR \"$(pkglibdir)\"" >>$@
+     echo "#define LOCALEDIR \"$(localedir)\"" >>$@

  clean distclean maintainer-clean:
      rm -f libpgport.a $(LIBOBJS) pg_config_paths.h
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.11
diff -c -c -r1.11 path.c
*** src/port/path.c    21 May 2004 20:56:50 -0000    1.11
--- src/port/path.c    25 May 2004 00:55:06 -0000
***************
*** 113,124 ****
  void
  get_share_path(const char *my_exec_path, char *ret_path)
  {
      if (relative_path(PGBINDIR, PGSHAREDIR))
      {
!         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, PGSHAREDIR, MAXPGPATH);
--- 113,126 ----
  void
  get_share_path(const char *my_exec_path, char *ret_path)
  {
+     char path[MAXPGPATH];
+
      if (relative_path(PGBINDIR, PGSHAREDIR))
      {
!         StrNCpy(path, my_exec_path, MAXPGPATH);
!         trim_directory(path);    /* trim off binary */
!         trim_directory(path);    /* trim off /bin */
!         snprintf(ret_path, MAXPGPATH, "%s/share", path);
      }
      else
          StrNCpy(ret_path, PGSHAREDIR, MAXPGPATH);
***************
*** 132,143 ****
  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);
--- 134,147 ----
  void
  get_etc_path(const char *my_exec_path, char *ret_path)
  {
+     char path[MAXPGPATH];
+
      if (relative_path(PGBINDIR, SYSCONFDIR))
      {
!         StrNCpy(path, my_exec_path, MAXPGPATH);
!         trim_directory(path);
!         trim_directory(path);
!         snprintf(ret_path, MAXPGPATH, "%s/etc", path);
      }
      else
          StrNCpy(ret_path, SYSCONFDIR, MAXPGPATH);
***************
*** 151,162 ****
  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);
--- 155,168 ----
  void
  get_include_path(const char *my_exec_path, char *ret_path)
  {
+     char path[MAXPGPATH];
+
      if (relative_path(PGBINDIR, INCLUDEDIR))
      {
!         StrNCpy(path, my_exec_path, MAXPGPATH);
!         trim_directory(path);
!         trim_directory(path);
!         snprintf(ret_path, MAXPGPATH, "%s/include", path);
      }
      else
          StrNCpy(ret_path, INCLUDEDIR, MAXPGPATH);
***************
*** 170,181 ****
  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);
--- 176,189 ----
  void
  get_pkginclude_path(const char *my_exec_path, char *ret_path)
  {
+     char path[MAXPGPATH];
+
      if (relative_path(PGBINDIR, PKGINCLUDEDIR))
      {
!         StrNCpy(path, my_exec_path, MAXPGPATH);
!         trim_directory(path);
!         trim_directory(path);
!         snprintf(ret_path, MAXPGPATH, "%s/include", path);
      }
      else
          StrNCpy(ret_path, PKGINCLUDEDIR, MAXPGPATH);
***************
*** 191,205 ****
  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);
  }


--- 199,264 ----
  void
  get_pkglib_path(const char *my_exec_path, char *ret_path)
  {
+     char path[MAXPGPATH];
+
      if (relative_path(PGBINDIR, PKGLIBDIR))
      {
!         StrNCpy(path, my_exec_path, MAXPGPATH);
!         trim_directory(path);
!         trim_directory(path);
!         snprintf(ret_path, MAXPGPATH, "%s/lib", path);
      }
      else
          StrNCpy(ret_path, PKGLIBDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+  *    get_locale_path
+  *
+  *    Return locale path, either relative to /bin or hardcoded
+  */
+ void
+ get_locale_path(const char *my_exec_path, char *ret_path)
+ {
+     char path[MAXPGPATH];
+
+     if (relative_path(PGBINDIR, LOCALEDIR))
+     {
+         StrNCpy(path, my_exec_path, MAXPGPATH);
+         trim_directory(path);
+         trim_directory(path);
+         snprintf(ret_path, MAXPGPATH, "%s/share/locale", path);
+     }
+     else
+         StrNCpy(ret_path, LOCALEDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+  *    set_pglocale
+  *
+  *    Set application-specific locale
+  *
+  *    This function takes an argv[0] rather than a full path.
+  */
+ void
+ set_pglocale(const char *argv0, const char *app)
+ {
+ #ifdef ENABLE_NLS
+     char path[MAXPGPATH];
+     char my_exec_path[MAXPGPATH];
+
+     setlocale(LC_ALL, "");
+     if (find_my_exec(argv0, my_exec_path) < 0)
+         return;
+
+     get_locale_path(argv0, path);
+     bindtextdomain(app, path);
+     textdomain(app);
+ #endif
  }



Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I have two questions.  First, setlocale() seemed to be inconsistently
> set inside and outside of ENABLE_NLS.  I assume the proper location is
> inside.

Please do *not* go adding setlocale calls that were not there before.
You *will* break things.

> !         setlocale(LC_ALL, "");
            ^^^^^^^^^^^^^^^^^^^^^

Putting this call in the backend is a very serious mistake.  It might be
okay in clients, but not in the backend.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I have two questions.  First, setlocale() seemed to be inconsistently
> > set inside and outside of ENABLE_NLS.  I assume the proper location is
> > inside.
>
> Please do *not* go adding setlocale calls that were not there before.
> You *will* break things.
>
> > !         setlocale(LC_ALL, "");
>             ^^^^^^^^^^^^^^^^^^^^^
>
> Putting this call in the backend is a very serious mistake.  It might be
> okay in clients, but not in the backend.

OK, patch applied.  Turns out it was only added for the backend
("postgres").

--
  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/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.12
diff -c -c -r1.12 path.c
*** src/port/path.c    25 May 2004 01:00:30 -0000    1.12
--- src/port/path.c    25 May 2004 01:40:36 -0000
***************
*** 251,257 ****
      char path[MAXPGPATH];
      char my_exec_path[MAXPGPATH];

!     setlocale(LC_ALL, "");
      if (find_my_exec(argv0, my_exec_path) < 0)
          return;

--- 251,260 ----
      char path[MAXPGPATH];
      char my_exec_path[MAXPGPATH];

!     /* don't set LC_ALL in the backend */
!     if (strcmp(app, "postgres") != 0)
!         setlocale(LC_ALL, "");
!
      if (find_my_exec(argv0, my_exec_path) < 0)
          return;


Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> OK, patch applied.  Turns out it was only added for the backend
> ("postgres").

Hm?  Isn't that code going to be executed in postmaster, bootstrap,
checkpoint processes, etc etc?

I don't really believe that path.c has any business doing this at
all, in any program.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > OK, patch applied.  Turns out it was only added for the backend
> > ("postgres").
>
> Hm?  Isn't that code going to be executed in postmaster, bootstrap,
> checkpoint processes, etc etc?
>
> I don't really believe that path.c has any business doing this at
> all, in any program.

Well, all our client apps used to do it in their own code.  Now they
call set_pglocale to do it centrally and relocabably.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Tom Lane wrote:
>> I don't really believe that path.c has any business doing this at
>> all, in any program.

> Well, all our client apps used to do it in their own code.  Now they
> call set_pglocale to do it centrally and relocabably.

I don't care if the clients do it.  I don't want main.c doing it.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Tom Lane wrote:
> >> I don't really believe that path.c has any business doing this at
> >> all, in any program.
>
> > Well, all our client apps used to do it in their own code.  Now they
> > call set_pglocale to do it centrally and relocabably.
>
> I don't care if the clients do it.  I don't want main.c doing it.

Well, as coded now, it will behave the same.

The old code has in main.c:

-       bindtextdomain("postgres", LOCALEDIR);
-       textdomain("postgres");

and now it has a call to set_pgsetlocale which does:

    if (find_my_exec(argv0, my_exec_path) < 0)
        return;

    get_locale_path(argv0, path);
    bindtextdomain(app, path);
    textdomain(app);

--
  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: main.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/main/main.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -c -r1.81 -r1.82
*** main.c    24 May 2004 02:47:44 -0000    1.81
--- main.c    25 May 2004 01:00:20 -0000    1.82
***************
*** 150,155 ****
--- 150,157 ----
       * startup error messages to be localized.
       */

+     set_pglocale(argv[0], "postgres");
+
  #ifdef WIN32
      /*
       * Windows uses codepages rather than the environment, so we work around
***************
*** 184,194 ****
      setlocale(LC_MONETARY, "C");
      setlocale(LC_NUMERIC, "C");
      setlocale(LC_TIME, "C");
-
- #ifdef ENABLE_NLS
-     bindtextdomain("postgres", LOCALEDIR);
-     textdomain("postgres");
- #endif

      /*
       * Skip permission checks if we're just trying to do --help or
--- 186,191 ----

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Well, as coded now, it will behave the same.

No it won't: as you have it, the postmaster and everything else that
goes through main.c will execute a setlocale call, which was not there
before for very good reasons.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Well, as coded now, it will behave the same.
>
> No it won't: as you have it, the postmaster and everything else that
> goes through main.c will execute a setlocale call, which was not there
> before for very good reasons.

I don't understand. I moved it up little in the file, but those calls
were happening in that file before, just a little lower.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I don't understand. I moved it up little in the file, but those calls
> were happening in that file before, just a little lower.

No, *that* call wasn't happening at all.  The calls that were there
were setting certain limited, safe LC categories.  You added a call
that sets *all* LC categories, including ones we do not want changed.
See the discussion in src/backend/utils/adt/pg_locale.c.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I don't understand. I moved it up little in the file, but those calls
> > were happening in that file before, just a little lower.
>
> No, *that* call wasn't happening at all.  The calls that were there
> were setting certain limited, safe LC categories.  You added a call
> that sets *all* LC categories, including ones we do not want changed.
> See the discussion in src/backend/utils/adt/pg_locale.c.

But I added code to path.c to skip that if the app is "postgres".  Why
doesn't that work?

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> But I added code to path.c to skip that if the app is "postgres".  Why
> doesn't that work?

That will work fine ... for a standalone backend.  Not so fine for
postmaster or bootstrap or other cases that go through main.c.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > But I added code to path.c to skip that if the app is "postgres".  Why
> > doesn't that work?
>
> That will work fine ... for a standalone backend.  Not so fine for
> postmaster or bootstrap or other cases that go through main.c.

But they all use the app name of "postgres".  They always did.

That is not 'progname' but a hardcoded appname that is used in the
main.c call.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> But they all use the app name of "postgres".  They always did.

Oh!  Sorry, I'm barking up the wrong tree then.  I was thinking you were
looking at the exec_path.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > But they all use the app name of "postgres".  They always did.
>
> Oh!  Sorry, I'm barking up the wrong tree then.  I was thinking you were
> looking at the exec_path.

Nope, hard-coded, as they all are.  I could pull from argv[0], but that
doesn't work in too many cases.  The main.c call is:

    set_pglocale(argv[0], "postgres");

and is the same no matter what is coming through main.c.

--
  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

Re: Relocatable locale

From
Peter Eisentraut
Date:
Bruce Momjian wrote:
> I have two questions.  First, setlocale() seemed to be inconsistently
> set inside and outside of ENABLE_NLS.  I assume the proper location
> is inside.

No, in case of doubt it's outside.

>  Second, libpq has a locale setting for error messages,
> but a libpq program could be in any directory, so I see no way to
> make that relocatable.  Instead, I just use the hardcoded path.  I
> could make it relocatable, but that seems to error-prone, plus I
> would have to look up the exec path and stuff, and it seemed too
> complicated.

Hmm, so this says that a relocatable install isn't in fact possible?



Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Bruce Momjian wrote:
> > I have two questions.  First, setlocale() seemed to be inconsistently
> > set inside and outside of ENABLE_NLS.  I assume the proper location
> > is inside.
>
> No, in case of doubt it's outside.


OK, moved.  New code is:

    void
    set_pglocale(const char *argv0, const char *app)
    {
    #ifdef ENABLE_NLS
        char path[MAXPGPATH];
        char my_exec_path[MAXPGPATH];
    #endif

        /* don't set LC_ALL in the backend */
        if (strcmp(app, "postgres") != 0)
            setlocale(LC_ALL, "");

    #ifdef ENABLE_NLS
        if (find_my_exec(argv0, my_exec_path) < 0)
            return;

        get_locale_path(my_exec_path, path);
        bindtextdomain(app, path);
        textdomain(app);
    #endif
    }

>
> >  Second, libpq has a locale setting for error messages,
> > but a libpq program could be in any directory, so I see no way to
> > make that relocatable.  Instead, I just use the hardcoded path.  I
> > could make it relocatable, but that seems to error-prone, plus I
> > would have to look up the exec path and stuff, and it seemed too
> > complicated.
>
> Hmm, so this says that a relocatable install isn't in fact possible?

Yep.  I don't see how you can have a library know where to look for its
localized messages.  The only thing I can think of is an environment
variable to override the hard-coded default.  How is that?

--
  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

Re: Relocatable locale

From
Andrew Dunstan
Date:
Bruce Momjian wrote:

> Yep. I don't see how you can have a library know where to look for its
>
>localized messages.  The only thing I can think of is an environment
>variable to override the hard-coded default.  How is that?
>
>
>

I'm confused. Can you explain the problem more clearly, please? Do we
need to distinguish known apps with a known (relative) message location,
from unknown libpq clients?

cheers

andrew


Re: Relocatable locale

From
Peter Eisentraut
Date:
Andrew Dunstan wrote:
> I'm confused. Can you explain the problem more clearly, please? Do we
> need to distinguish known apps with a known (relative) message
> location, from unknown libpq clients?

The problem boils down to the fact that libpq needs to find its data
files (in this case locale data, but it could be anything), but it
doesn't know its own location, so it can't use a relative path
reference as has been proposed.


Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Andrew Dunstan wrote:
> > I'm confused. Can you explain the problem more clearly, please? Do we
> > need to distinguish known apps with a known (relative) message
> > location, from unknown libpq clients?
>
> The problem boils down to the fact that libpq needs to find its data
> files (in this case locale data, but it could be anything), but it
> doesn't know its own location, so it can't use a relative path
> reference as has been proposed.

I am wondering if we should use environment variables, and have our apps
use putenv() to set it to the proper relative path.

--
  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

Re: Relocatable locale

From
Andrew Dunstan
Date:

Bruce Momjian wrote:

>Peter Eisentraut wrote:
>
>
>>Andrew Dunstan wrote:
>>
>>
>>>I'm confused. Can you explain the problem more clearly, please? Do we
>>>need to distinguish known apps with a known (relative) message
>>>location, from unknown libpq clients?
>>>
>>>
>>The problem boils down to the fact that libpq needs to find its data
>>files (in this case locale data, but it could be anything), but it
>>doesn't know its own location, so it can't use a relative path
>>reference as has been proposed.
>>
>>
>
>I am wondering if we should use environment variables, and have our apps
>use putenv() to set it to the proper relative path.
>
>

It seems a bit roundabout, but might make sense. Maybe they shouldn't
override any value already present in the environment, just set it if
there is nothing there? Then the library could use the environment if
set, or fall back on a hardcoded path.

cheers

andrew


Re: Relocatable locale

From
Bruce Momjian
Date:
Andrew Dunstan wrote:
>
>
> Bruce Momjian wrote:
>
> >Peter Eisentraut wrote:
> >
> >
> >>Andrew Dunstan wrote:
> >>
> >>
> >>>I'm confused. Can you explain the problem more clearly, please? Do we
> >>>need to distinguish known apps with a known (relative) message
> >>>location, from unknown libpq clients?
> >>>
> >>>
> >>The problem boils down to the fact that libpq needs to find its data
> >>files (in this case locale data, but it could be anything), but it
> >>doesn't know its own location, so it can't use a relative path
> >>reference as has been proposed.
> >>
> >>
> >
> >I am wondering if we should use environment variables, and have our apps
> >use putenv() to set it to the proper relative path.
> >
> >
>
> It seems a bit roundabout, but might make sense. Maybe they shouldn't
> override any value already present in the environment, just set it if
> there is nothing there? Then the library could use the environment if
> set, or fall back on a hardcoded path.

Yes, that is what I was thinking.  Call it PGLOCALEDIR.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Peter Eisentraut wrote:
>> The problem boils down to the fact that libpq needs to find its data
>> files (in this case locale data, but it could be anything), but it
>> doesn't know its own location, so it can't use a relative path
>> reference as has been proposed.

> I am wondering if we should use environment variables, and have our apps
> use putenv() to set it to the proper relative path.

*Our* apps are not the problem.  The problem comes when libpq is
embedded in somebody else's app --- which is not going to be that
cooperative, and would have no good way to know what path to supply
if it did want to be cooperative.

I can't say I care for the environment variable idea either; though
there may not be any better alternative.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Peter Eisentraut wrote:
> >> The problem boils down to the fact that libpq needs to find its data
> >> files (in this case locale data, but it could be anything), but it
> >> doesn't know its own location, so it can't use a relative path
> >> reference as has been proposed.
>
> > I am wondering if we should use environment variables, and have our apps
> > use putenv() to set it to the proper relative path.
>
> *Our* apps are not the problem.  The problem comes when libpq is

Well, right now our apps don't work, so it is a problem.  Of course the
bigger problem is other apps.  How do libs find related files?  I can't
think if a common API for that.

> I can't say I care for the environment variable idea either; though
> there may not be any better alternative.

I think the best we can do is putenv() for our apps, and document the
variable for other apps.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I think the best we can do is putenv() for our apps, and document the
> variable for other apps.

Document what?  How will another app find libpq's locale file?
AFAICS *it can't*.  Documenting a useless variable is not a solution.

            regards, tom lane

Re: Relocatable locale

From
"Andrew Dunstan"
Date:
Tom Lane said:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
>> I think the best we can do is putenv() for our apps, and document the
>> variable for other apps.
>
> Document what?  How will another app find libpq's locale file?
> AFAICS *it can't*.  Documenting a useless variable is not a solution.
>

You wouldn't expect the environment var to be set by an app in those
cases - it would be set by a sysadmin or an installer on a system-wide
basis when pg is installed in other than the hardcoded location. At least,
that's the way I understood Bruce's suggestion.

cheers

andrew



Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I think the best we can do is putenv() for our apps, and document the
> > variable for other apps.
>
> Document what?  How will another app find libpq's locale file?
> AFAICS *it can't*.  Documenting a useless variable is not a solution.

I figured our apps could use putenv to set the locale directory, and
users of other apps could set the environment variable before running
the app.

--
  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

Re: Relocatable locale

From
Bruce Momjian
Date:
Andrew Dunstan wrote:
> Tom Lane said:
> > Bruce Momjian <pgman@candle.pha.pa.us> writes:
> >> I think the best we can do is putenv() for our apps, and document the
> >> variable for other apps.
> >
> > Document what?  How will another app find libpq's locale file?
> > AFAICS *it can't*.  Documenting a useless variable is not a solution.
> >
>
> You wouldn't expect the environment var to be set by an app in those
> cases - it would be set by a sysadmin or an installer on a system-wide
> basis when pg is installed in other than the hardcoded location. At least,
> that's the way I understood Bruce's suggestion.

Right.

--
  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

Re: Relocatable locale

From
Peter Eisentraut
Date:
Bruce Momjian wrote:
> I am wondering if we should use environment variables, and have our
> apps use putenv() to set it to the proper relative path.

The problem isn't our applications, it's someone else's applications.
Are you saying that from now on, setting certain environment variables
is part of the required startup for libpq programs?  Remember that on
Windows in generall all installations are relocated away from the
default location.


Re: Relocatable locale

From
Peter Eisentraut
Date:
Andrew Dunstan wrote:
> You wouldn't expect the environment var to be set by an app in those
> cases - it would be set by a sysadmin or an installer on a
> system-wide basis when pg is installed in other than the hardcoded
> location. At least, that's the way I understood Bruce's suggestion.

Strange.  I don't suppose that PostgreSQL is the first package using
gettext on Windows.  How does everyone else handle this?


Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Bruce Momjian wrote:
> > I am wondering if we should use environment variables, and have our
> > apps use putenv() to set it to the proper relative path.
>
> The problem isn't our applications, it's someone else's applications.
> Are you saying that from now on, setting certain environment variables
> is part of the required startup for libpq programs?  Remember that on
> Windows in generall all installations are relocated away from the
> default location.

Well, if they want locale-specific error messages from libpq in their
applications, the have to supply those locale files somehow.  They could
supply them in the same directory as their binaries and use putenv()
and find_my_exec().

Sure, it is a hack, but what other option do we have?  Do we somehow
move the locale files into the library?

--
  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

Re: Relocatable locale

From
"Magnus Hagander"
Date:
> > You wouldn't expect the environment var to be set by an app
> in those
> > cases - it would be set by a sysadmin or an installer on a
> system-wide
> > basis when pg is installed in other than the hardcoded location. At
> > least, that's the way I understood Bruce's suggestion.
>
> Strange.  I don't suppose that PostgreSQL is the first
> package using gettext on Windows.  How does everyone else handle this?

I don't beleive this is a windows-specific issue. It's a general issue
for all relocateable installs.

As for how to do it - on Windows you *can* get the path of the DLL that
is executing your code, using GetModuleFileName(). Hardly
cross-platform, but can be done.

(The "windows standard" way of doing it is using String Tables as
resources inside the DLL.But that's now what gettext uses, so it's not
relevant unless we'd want to replace gettext (which we don't))

//Magnus

Re: Relocatable locale

From
Peter Eisentraut
Date:
Am Donnerstag, 27. Mai 2004 13:05 schrieb Magnus Hagander:
> I don't beleive this is a windows-specific issue. It's a general issue
> for all relocateable installs.

Except that no one except Windows uses relocatable installs.

> As for how to do it - on Windows you *can* get the path of the DLL that
> is executing your code, using GetModuleFileName(). Hardly
> cross-platform, but can be done.

That sounds pretty reasonable to me.

Re: Relocatable locale

From
Peter Eisentraut
Date:
Am Donnerstag, 27. Mai 2004 07:31 schrieb Bruce Momjian:
> Sure, it is a hack, but what other option do we have?  Do we somehow
> move the locale files into the library?

On Windows we use the feature that DLLs can locate themselves (described by
Magnus Hagander), and on Unix we forget about pretending to offer relocatable
installations.

Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Am Donnerstag, 27. Mai 2004 13:05 schrieb Magnus Hagander:
> > I don't beleive this is a windows-specific issue. It's a general issue
> > for all relocateable installs.
>
> Except that no one except Windows uses relocatable installs.

I don't think that is completely true.  Packagers have been requesting
relocatable installs for a while, I think.

> > As for how to do it - on Windows you *can* get the path of the DLL that
> > is executing your code, using GetModuleFileName(). Hardly
> > cross-platform, but can be done.
>
> That sounds pretty reasonable to me.

True, and we already have our own find_my_exec() which works for Unix too.

--
  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

Re: Relocatable locale

From
Peter Eisentraut
Date:
Am Donnerstag, 27. Mai 2004 14:41 schrieb Bruce Momjian:
> > > As for how to do it - on Windows you *can* get the path of the DLL that
> > > is executing your code, using GetModuleFileName(). Hardly
> > > cross-platform, but can be done.
> >
> > That sounds pretty reasonable to me.
>
> True, and we already have our own find_my_exec() which works for Unix too.

What does that have to do with this case?  We're trying to find the library
here.

Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Am Donnerstag, 27. Mai 2004 14:41 schrieb Bruce Momjian:
> > > > As for how to do it - on Windows you *can* get the path of the DLL that
> > > > is executing your code, using GetModuleFileName(). Hardly
> > > > cross-platform, but can be done.
> > >
> > > That sounds pretty reasonable to me.
> >
> > True, and we already have our own find_my_exec() which works for Unix too.
>
> What does that have to do with this case?  We're trying to find the library
> here.

Oh, I see that GetModuleFileName() finds the location of your library,
not of the binary.  Nice.  So, for Win32, we use that function call to
find the locale directory?

We do have a comment in port/exec.c:

    if (GetModuleFileName(NULL, retpath, MAXPGPATH) == 0)

and I thought that did only binaries, not the library that uses them.  I
assume if the library is a DLL, it returns the DLL location, and if it
is in the binary, it returns the binary location.

I will make a Win32-specific patch.  Do we want an evironment variable
for Unix?  Seems folks do.  I will work on that too.

--
  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

Re: Relocatable locale

From
Peter Eisentraut
Date:
Am Donnerstag, 27. Mai 2004 15:03 schrieb Bruce Momjian:
> I will make a Win32-specific patch.  Do we want an evironment variable
> for Unix?  Seems folks do.  I will work on that too.

The gettext library already has an environment variable for that (NLSPATH I
think).  I don't know if we need a PostgreSQL-specific one.

Re: Relocatable locale

From
"Magnus Hagander"
Date:
> > > > > As for how to do it - on Windows you *can* get the
> path of the
> > > > > DLL that is executing your code, using GetModuleFileName().
> > > > > Hardly cross-platform, but can be done.
> > > >
> > > > That sounds pretty reasonable to me.
> > >
> > > True, and we already have our own find_my_exec() which
> works for Unix too.
> >
> > What does that have to do with this case?  We're trying to find the
> > library here.
>
> Oh, I see that GetModuleFileName() finds the location of your
> library, not of the binary.  Nice.  So, for Win32, we use
> that function call to find the locale directory?
>
> We do have a comment in port/exec.c:
>
>     if (GetModuleFileName(NULL, retpath, MAXPGPATH) == 0)
>
> and I thought that did only binaries, not the library that
> uses them.  I assume if the library is a DLL, it returns the
> DLL location, and if it is in the binary, it returns the
> binary location.

Nope, not quite.
With the parameter NULL, it will return for the current *process*.
You will need to use GetModuleHandle() (I think that should work) to get
the handle of the DLL. See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc
/base/getmodulehandle.asp

For static libaries, you need a different solution. Base that off the
EXE?

//Magnus


Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Am Donnerstag, 27. Mai 2004 15:03 schrieb Bruce Momjian:
> > I will make a Win32-specific patch.  Do we want an evironment variable
> > for Unix?  Seems folks do.  I will work on that too.
>
> The gettext library already has an environment variable for that (NLSPATH I
> think).  I don't know if we need a PostgreSQL-specific one.

Oh, OK. Should we just read that variable, and document it?

--
  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

Re: Relocatable locale

From
Bruce Momjian
Date:
Magnus Hagander wrote:
> > > > > > As for how to do it - on Windows you *can* get the
> > path of the
> > > > > > DLL that is executing your code, using GetModuleFileName().
> > > > > > Hardly cross-platform, but can be done.
> > > > >
> > > > > That sounds pretty reasonable to me.
> > > >
> > > > True, and we already have our own find_my_exec() which
> > works for Unix too.
> > >
> > > What does that have to do with this case?  We're trying to find the
> > > library here.
> >
> > Oh, I see that GetModuleFileName() finds the location of your
> > library, not of the binary.  Nice.  So, for Win32, we use
> > that function call to find the locale directory?
> >
> > We do have a comment in port/exec.c:
> >
> >     if (GetModuleFileName(NULL, retpath, MAXPGPATH) == 0)
> >
> > and I thought that did only binaries, not the library that
> > uses them.  I assume if the library is a DLL, it returns the
> > DLL location, and if it is in the binary, it returns the
> > binary location.
>
> Nope, not quite.
> With the parameter NULL, it will return for the current *process*.
> You will need to use GetModuleHandle() (I think that should work) to get
> the handle of the DLL. See
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc
> /base/getmodulehandle.asp
>
> For static libaries, you need a different solution. Base that off the
> EXE?

Oh, static libs basically kills our idea.  Maybe we just need to use the
environment variable solution for Win32 too.

The EXE solution would work for our client apps, and I am going to add a
putenv("NLSPATH") in those, but for 3rd-party apps that use libpq, they
could be anywhere in relation to the pgsql install.  In fact, there
might be no libpq install at all because they only use pgsql clients.

--
  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

Re: Relocatable locale

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I will make a Win32-specific patch.  Do we want an evironment variable
> for Unix?

No, we do not.  This entire thread has consisted of everyone but you
objecting loudly to that idea.

            regards, tom lane

Re: Relocatable locale

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I will make a Win32-specific patch.  Do we want an evironment variable
> > for Unix?
>
> No, we do not.  This entire thread has consisted of everyone but you
> objecting loudly to that idea.

They didn't sound very loud to me.

Why not have it so Unix folks can control it?

Also, how do we get our native apps to know the location of the locale
directory?  The only other solution I can think of is a libpq function
call to set it, but of course that can't be changed once the binary is
created.  Our apps could use the function call (based on the bin
location), and other apps would have to decide how they would make this
functionality visible, but it wouldn't be consistent.

--
  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

Re: Relocatable locale

From
Bruce Momjian
Date:
With no one coming up with a better idea, this applied patch adds PGETC
(for pg_service.conf) and PGLOCALE (for locale dir) environment variable
processing to libpq.

The patch also adds code to our client apps so we set the environment
variable directly based on our binary location, unless it is already
set. This will allow our applications to emit proper locale messages
that are generated in libpq.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> Andrew Dunstan wrote:
> >
> >
> > Bruce Momjian wrote:
> >
> > >Peter Eisentraut wrote:
> > >
> > >
> > >>Andrew Dunstan wrote:
> > >>
> > >>
> > >>>I'm confused. Can you explain the problem more clearly, please? Do we
> > >>>need to distinguish known apps with a known (relative) message
> > >>>location, from unknown libpq clients?
> > >>>
> > >>>
> > >>The problem boils down to the fact that libpq needs to find its data
> > >>files (in this case locale data, but it could be anything), but it
> > >>doesn't know its own location, so it can't use a relative path
> > >>reference as has been proposed.
> > >>
> > >>
> > >
> > >I am wondering if we should use environment variables, and have our apps
> > >use putenv() to set it to the proper relative path.
> > >
> > >
> >
> > It seems a bit roundabout, but might make sense. Maybe they shouldn't
> > override any value already present in the environment, just set it if
> > there is nothing there? Then the library could use the environment if
> > set, or fall back on a hardcoded path.
>
> Yes, that is what I was thinking.  Call it PGLOCALEDIR.
>
> --
>   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
>
> ---------------------------(end of broadcast)---------------------------
> TIP 8: explain analyze is your friend
>

--
  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: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/libpq.sgml,v
retrieving revision 1.155
diff -c -c -r1.155 libpq.sgml
*** doc/src/sgml/libpq.sgml    14 May 2004 18:04:02 -0000    1.155
--- doc/src/sgml/libpq.sgml    2 Jun 2004 23:59:33 -0000
***************
*** 3582,3587 ****
--- 3582,3605 ----
  (Equivalent to <literal>SET geqo TO ...</literal>.)
  </para>
  </listitem>
+ <listitem>
+ <para>
+ <indexterm>
+  <primary><envar>PGETC</envar></primary>
+ </indexterm>
+ <envar>PGETC</envar>
+ sets the directory containing the <filename>pg_service.conf</> file.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <indexterm>
+  <primary><envar>PGLOCALE</envar></primary>
+ </indexterm>
+ <envar>PGLOCALE</envar>
+ sets the directory containing the <literal>locale</> files.
+ </para>
+ </listitem>
  </itemizedlist>

  Refer to the <acronym>SQL</acronym> command <command>SET</command>
Index: src/backend/main/main.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/main/main.c,v
retrieving revision 1.85
diff -c -c -r1.85 main.c
*** src/backend/main/main.c    29 May 2004 22:48:19 -0000    1.85
--- src/backend/main/main.c    2 Jun 2004 23:59:41 -0000
***************
*** 152,158 ****
       * allow startup error messages to be localized.
       */

!     set_pglocale(argv[0], "postgres");

  #ifdef WIN32

--- 152,158 ----
       * allow startup error messages to be localized.
       */

!     set_pglocale_pgservice(argv[0], "postgres");

  #ifdef WIN32

Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.34
diff -c -c -r1.34 initdb.c
*** src/bin/initdb/initdb.c    1 Jun 2004 02:53:59 -0000    1.34
--- src/bin/initdb/initdb.c    2 Jun 2004 23:59:53 -0000
***************
*** 1788,1794 ****
      {"global", "pg_xlog", "pg_clog", "base", "base/1"};

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "initdb");

      if (argc > 1)
      {
--- 1788,1794 ----
      {"global", "pg_xlog", "pg_clog", "base", "base/1"};

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "initdb");

      if (argc > 1)
      {
Index: src/bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.16
diff -c -c -r1.16 pg_controldata.c
*** src/bin/pg_controldata/pg_controldata.c    25 May 2004 01:00:23 -0000    1.16
--- src/bin/pg_controldata/pg_controldata.c    2 Jun 2004 23:59:53 -0000
***************
*** 77,83 ****
      char       *strftime_fmt = "%c";
      const char *progname;

!     set_pglocale(argv[0], "pg_controldata");

      progname = get_progname(argv[0]);

--- 77,83 ----
      char       *strftime_fmt = "%c";
      const char *progname;

!     set_pglocale_pgservice(argv[0], "pg_controldata");

      progname = get_progname(argv[0]);

Index: src/bin/pg_ctl/pg_ctl.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_ctl/pg_ctl.c,v
retrieving revision 1.5
diff -c -c -r1.5 pg_ctl.c
*** src/bin/pg_ctl/pg_ctl.c    1 Jun 2004 22:03:18 -0000    1.5
--- src/bin/pg_ctl/pg_ctl.c    2 Jun 2004 23:59:54 -0000
***************
*** 824,830 ****
  #endif

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pg_ctl");

      /*
       * save argv[0] so do_start() can look for the postmaster if
--- 824,830 ----
  #endif

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pg_ctl");

      /*
       * save argv[0] so do_start() can look for the postmaster if
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.372
diff -c -c -r1.372 pg_dump.c
*** src/bin/pg_dump/pg_dump.c    26 May 2004 18:24:22 -0000    1.372
--- src/bin/pg_dump/pg_dump.c    3 Jun 2004 00:00:00 -0000
***************
*** 242,248 ****
      };
      int            optindex;

!     set_pglocale(argv[0], "pg_dump");

      g_verbose = false;

--- 242,248 ----
      };
      int            optindex;

!     set_pglocale_pgservice(argv[0], "pg_dump");

      g_verbose = false;

Index: src/bin/pg_dump/pg_dumpall.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dumpall.c,v
retrieving revision 1.35
diff -c -c -r1.35 pg_dumpall.c
*** src/bin/pg_dump/pg_dumpall.c    25 May 2004 01:00:24 -0000    1.35
--- src/bin/pg_dump/pg_dumpall.c    3 Jun 2004 00:00:00 -0000
***************
*** 101,107 ****

      int            optindex;

!     set_pglocale(argv[0], "pg_dump");

      progname = get_progname(argv[0]);

--- 101,107 ----

      int            optindex;

!     set_pglocale_pgservice(argv[0], "pg_dump");

      progname = get_progname(argv[0]);

Index: src/bin/pg_dump/pg_restore.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_restore.c,v
retrieving revision 1.57
diff -c -c -r1.57 pg_restore.c
*** src/bin/pg_dump/pg_restore.c    25 May 2004 01:00:24 -0000    1.57
--- src/bin/pg_dump/pg_restore.c    3 Jun 2004 00:00:01 -0000
***************
*** 121,127 ****
          {NULL, 0, NULL, 0}
      };

!     set_pglocale(argv[0], "pg_dump");

      opts = NewRestoreOptions();

--- 121,127 ----
          {NULL, 0, NULL, 0}
      };

!     set_pglocale_pgservice(argv[0], "pg_dump");

      opts = NewRestoreOptions();

Index: src/bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.19
diff -c -c -r1.19 pg_resetxlog.c
*** src/bin/pg_resetxlog/pg_resetxlog.c    25 May 2004 01:00:25 -0000    1.19
--- src/bin/pg_resetxlog/pg_resetxlog.c    3 Jun 2004 00:00:02 -0000
***************
*** 102,108 ****
      int            fd;
      char        path[MAXPGPATH];

!     set_pglocale(argv[0], "pg_resetxlog");

      progname = get_progname(argv[0]);

--- 102,108 ----
      int            fd;
      char        path[MAXPGPATH];

!     set_pglocale_pgservice(argv[0], "pg_resetxlog");

      progname = get_progname(argv[0]);

Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.94
diff -c -c -r1.94 startup.c
*** src/bin/psql/startup.c    25 May 2004 01:00:26 -0000    1.94
--- src/bin/psql/startup.c    3 Jun 2004 00:00:02 -0000
***************
*** 102,108 ****
      char       *password = NULL;
      bool        need_pass;

!     set_pglocale(argv[0], "psql");

      pset.progname = get_progname(argv[0]);

--- 102,108 ----
      char       *password = NULL;
      bool        need_pass;

!     set_pglocale_pgservice(argv[0], "psql");

      pset.progname = get_progname(argv[0]);

Index: src/bin/scripts/clusterdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/clusterdb.c,v
retrieving revision 1.8
diff -c -c -r1.8 clusterdb.c
*** src/bin/scripts/clusterdb.c    1 Jun 2004 02:54:09 -0000    1.8
--- src/bin/scripts/clusterdb.c    3 Jun 2004 00:00:02 -0000
***************
*** 58,64 ****
      char       *table = NULL;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "clusterdb", help);

--- 58,64 ----
      char       *table = NULL;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "clusterdb", help);

Index: src/bin/scripts/createdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createdb.c,v
retrieving revision 1.10
diff -c -c -r1.10 createdb.c
*** src/bin/scripts/createdb.c    1 Jun 2004 02:54:09 -0000    1.10
--- src/bin/scripts/createdb.c    3 Jun 2004 00:00:03 -0000
***************
*** 60,66 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createdb", help);

--- 60,66 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createdb", help);

Index: src/bin/scripts/createlang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createlang.c,v
retrieving revision 1.11
diff -c -c -r1.11 createlang.c
*** src/bin/scripts/createlang.c    1 Jun 2004 02:54:09 -0000    1.11
--- src/bin/scripts/createlang.c    3 Jun 2004 00:00:05 -0000
***************
*** 61,67 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createlang", help);

--- 61,67 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createlang", help);

Index: src/bin/scripts/createuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createuser.c,v
retrieving revision 1.12
diff -c -c -r1.12 createuser.c
*** src/bin/scripts/createuser.c    1 Jun 2004 02:54:09 -0000    1.12
--- src/bin/scripts/createuser.c    3 Jun 2004 00:00:05 -0000
***************
*** 63,69 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createuser", help);

--- 63,69 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "createuser", help);

Index: src/bin/scripts/dropdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropdb.c,v
retrieving revision 1.11
diff -c -c -r1.11 dropdb.c
*** src/bin/scripts/dropdb.c    1 Jun 2004 02:54:09 -0000    1.11
--- src/bin/scripts/dropdb.c    3 Jun 2004 00:00:05 -0000
***************
*** 51,57 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "dropdb", help);

--- 51,57 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "dropdb", help);

Index: src/bin/scripts/droplang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/droplang.c,v
retrieving revision 1.10
diff -c -c -r1.10 droplang.c
*** src/bin/scripts/droplang.c    1 Jun 2004 02:54:09 -0000    1.10
--- src/bin/scripts/droplang.c    3 Jun 2004 00:00:05 -0000
***************
*** 61,67 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "droplang", help);

--- 61,67 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "droplang", help);

Index: src/bin/scripts/dropuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropuser.c,v
retrieving revision 1.10
diff -c -c -r1.10 dropuser.c
*** src/bin/scripts/dropuser.c    1 Jun 2004 02:54:09 -0000    1.10
--- src/bin/scripts/dropuser.c    3 Jun 2004 00:00:05 -0000
***************
*** 51,57 ****
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "dropuser", help);

--- 51,57 ----
      PGresult   *result;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "dropuser", help);

Index: src/bin/scripts/vacuumdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/vacuumdb.c,v
retrieving revision 1.8
diff -c -c -r1.8 vacuumdb.c
*** src/bin/scripts/vacuumdb.c    1 Jun 2004 02:54:09 -0000    1.8
--- src/bin/scripts/vacuumdb.c    3 Jun 2004 00:00:05 -0000
***************
*** 66,72 ****
      bool        verbose = false;

      progname = get_progname(argv[0]);
!     set_pglocale(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "vacuumdb", help);

--- 66,72 ----
      bool        verbose = false;

      progname = get_progname(argv[0]);
!     set_pglocale_pgservice(argv[0], "pgscripts");

      handle_help_version_opts(argc, argv, "vacuumdb", help);

Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.39
diff -c -c -r1.39 port.h
*** src/include/port.h    27 May 2004 14:39:32 -0000    1.39
--- src/include/port.h    3 Jun 2004 00:00:06 -0000
***************
*** 32,38 ****
  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);
  extern void get_locale_path(const char *my_exec_path, char *ret_path);
! extern void set_pglocale(const char *argv0, const char *app);

  /*
   *    is_absolute_path
--- 32,38 ----
  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);
  extern void get_locale_path(const char *my_exec_path, char *ret_path);
! extern void set_pglocale_pgservice(const char *argv0, const char *app);

  /*
   *    is_absolute_path
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.271
diff -c -c -r1.271 fe-connect.c
*** src/interfaces/libpq/fe-connect.c    26 May 2004 18:35:51 -0000    1.271
--- src/interfaces/libpq/fe-connect.c    3 Jun 2004 00:00:13 -0000
***************
*** 2363,2379 ****



- #ifndef SYSCONFDIR
- #error "You must compile this file with SYSCONFDIR defined."
- #endif
-
  #define MAXBUFSIZE 256

  static int
  parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
  {
      char       *service = conninfo_getval(options, "service");
!     char       *serviceFile = SYSCONFDIR "/pg_service.conf";
      bool        group_found = false;
      int            linenr = 0,
                  i;
--- 2363,2375 ----



  #define MAXBUFSIZE 256

  static int
  parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
  {
      char       *service = conninfo_getval(options, "service");
!     char        serviceFile[MAXPGPATH];
      bool        group_found = false;
      int            linenr = 0,
                  i;
***************
*** 2385,2390 ****
--- 2381,2393 ----
       */
      if (service == NULL)
          service = getenv("PGSERVICE");
+
+     /*
+      *    This could be used by any application so we can't use the binary
+      *    location to find our config files.
+      */
+     snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
+              getenv("PGETC") ? getenv("PGETC") : SYSCONFDIR);

      if (service != NULL)
      {
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.106
diff -c -c -r1.106 fe-misc.c
*** src/interfaces/libpq/fe-misc.c    25 May 2004 01:00:29 -0000    1.106
--- src/interfaces/libpq/fe-misc.c    3 Jun 2004 00:00:13 -0000
***************
*** 1132,1138 ****
      {
          already_bound = 1;
          /* No relocatable lookup here because the binary could be anywhere */
!         bindtextdomain("libpq", LOCALEDIR);
      }

      return dgettext("libpq", msgid);
--- 1132,1138 ----
      {
          already_bound = 1;
          /* No relocatable lookup here because the binary could be anywhere */
!         bindtextdomain("libpq", getenv("PGLOCALE") ? getenv("PGLOCALE") : LOCALEDIR);
      }

      return dgettext("libpq", msgid);
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.16
diff -c -c -r1.16 path.c
*** src/port/path.c    26 May 2004 19:00:31 -0000    1.16
--- src/port/path.c    3 Jun 2004 00:00:13 -0000
***************
*** 222,253 ****


  /*
!  *    set_pglocale
   *
!  *    Set application-specific locale
   *
   *    This function takes an argv[0] rather than a full path.
   */
  void
! set_pglocale(const char *argv0, const char *app)
  {
- #ifdef ENABLE_NLS
      char path[MAXPGPATH];
      char my_exec_path[MAXPGPATH];
! #endif

      /* don't set LC_ALL in the backend */
      if (strcmp(app, "postgres") != 0)
          setlocale(LC_ALL, "");

- #ifdef ENABLE_NLS
      if (find_my_exec(argv0, my_exec_path) < 0)
          return;

      get_locale_path(my_exec_path, path);
      bindtextdomain(app, path);
      textdomain(app);
  #endif
  }


--- 222,268 ----


  /*
!  *    set_pglocale_pgservice
   *
!  *    Set application-specific locale and service directory
   *
   *    This function takes an argv[0] rather than a full path.
   */
  void
! set_pglocale_pgservice(const char *argv0, const char *app)
  {
      char path[MAXPGPATH];
      char my_exec_path[MAXPGPATH];
!     char env_path[MAXPGPATH + strlen("PGLOCALE=")]; /* longer than PGETC */

      /* don't set LC_ALL in the backend */
      if (strcmp(app, "postgres") != 0)
          setlocale(LC_ALL, "");

      if (find_my_exec(argv0, my_exec_path) < 0)
          return;

+ #ifdef ENABLE_NLS
      get_locale_path(my_exec_path, path);
      bindtextdomain(app, path);
      textdomain(app);
+
+     if (!getenv("PGLOCALE"))
+     {
+         /* set for libpq to use */
+         sprintf(env_path, "PGLOCALE=%s", path);
+         putenv(env_path);
+     }
  #endif
+
+     if (!getenv("PGETC"))
+     {
+         get_etc_path(my_exec_path, path);
+
+         /* set for libpq to use */
+         sprintf(env_path, "PGETC=%s", path);
+         putenv(env_path);
+     }
  }



Re: Relocatable locale

From
Peter Eisentraut
Date:
Bruce Momjian wrote:
> With no one coming up with a better idea, this applied patch adds
> PGETC (for pg_service.conf) and PGLOCALE (for locale dir) environment
> variable processing to libpq.

Considering that in other places these locations are referred to as
"sysconfdir" and "localdir", it would make sense to name the variables
"PGSYSCONFDIR" and "PGLOCALEDIR", so we stick to one set of terms.


Re: Relocatable locale

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Bruce Momjian wrote:
> > With no one coming up with a better idea, this applied patch adds
> > PGETC (for pg_service.conf) and PGLOCALE (for locale dir) environment
> > variable processing to libpq.
>
> Considering that in other places these locations are referred to as
> "sysconfdir" and "localdir", it would make sense to name the variables
> "PGSYSCONFDIR" and "PGLOCALEDIR", so we stick to one set of terms.

OK, change made.

--
  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