From 6016d649968b96b3ee9b0d586da83a3120ec023f Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 9 Oct 2008 17:24:05 +0000 Subject: [PATCH] Improve translatability of error messages for external modules by tweaking the ereport macro. Included in this commit are enough files for starting plpgsql, plpython, plperl and pltcl translations. --- src/backend/utils/error/elog.c | 8 +++++--- src/backend/utils/init/miscinit.c | 14 ++++++++++++++ src/include/miscadmin.h | 1 + src/include/utils/elog.h | 19 ++++++++++++++++--- src/pl/plperl/nls.mk | 5 +++++ src/pl/plperl/plperl.c | 8 +++++++- src/pl/plpgsql/src/nls.mk | 8 ++++++++ src/pl/plpgsql/src/pl_handler.c | 2 ++ src/pl/plpgsql/src/plpgsql.h | 4 ++++ src/pl/plpython/nls.mk | 5 +++++ src/pl/plpython/plpython.c | 6 ++++++ src/pl/tcl/nls.mk | 5 +++++ src/pl/tcl/pltcl.c | 6 ++++++ 13 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/pl/plperl/nls.mk create mode 100644 src/pl/plpgsql/src/nls.mk create mode 100644 src/pl/plpython/nls.mk create mode 100644 src/pl/tcl/nls.mk diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 863ed7208c..3a1ef3fe8e 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -160,7 +160,7 @@ static void write_csvlog(ErrorData *edata); */ bool errstart(int elevel, const char *filename, int lineno, - const char *funcname) + const char *funcname, const char *domain) { ErrorData *edata; bool output_to_server; @@ -290,6 +290,8 @@ errstart(int elevel, const char *filename, int lineno, edata->filename = filename; edata->lineno = lineno; edata->funcname = funcname; + /* the default text domain is the backend's */ + edata->domain = domain ? domain : "postgres"; /* Select default errcode based on elevel */ if (elevel >= ERROR) edata->sqlerrcode = ERRCODE_INTERNAL_ERROR; @@ -611,7 +613,7 @@ errcode_for_socket_access(void) char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ - fmt = _(fmt); \ + fmt = dgettext(edata->domain, fmt); \ /* Expand %m in format string */ \ fmtbuf = expand_fmt_string(fmt, edata); \ initStringInfo(&buf); \ @@ -982,7 +984,7 @@ elog_finish(int elevel, const char *fmt,...) */ errordata_stack_depth--; errno = edata->saved_errno; - if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname)) + if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname, NULL)) return; /* nothing to do */ /* diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index a14d05d95b..596c288850 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -1212,3 +1212,17 @@ process_local_preload_libraries(void) "local_preload_libraries", true); } + +void +set_text_domain(const char *domain) +{ +#ifdef ENABLE_NLS + if (my_exec_path[0] != '\0') + { + char locale_path[MAXPGPATH]; + + get_locale_path(my_exec_path, locale_path); + bindtextdomain(domain, locale_path); + } +#endif +} diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index b73815b7c8..ffbff22c6e 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -329,6 +329,7 @@ extern void RecordSharedMemoryInLockFile(unsigned long id1, extern void ValidatePgVersion(const char *path); extern void process_shared_preload_libraries(void); extern void process_local_preload_libraries(void); +extern void set_text_domain(const char *domain); /* in access/transam/xlog.c */ extern bool BackupInProgress(void); diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 6a74fca214..ed21d4f40c 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -92,14 +92,26 @@ * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is * NOTICE or below. + * + * ereport_domain() allows a message domain to be specified, for modules that + * wish to use a different message catalog from the backend's. To avoid having + * one copy of the default text domain per .o file, we define it as NULL here + * and have errstart insert the default text domain. Modules can either use + * ereport_domain() directly, or preferrably they can override the TEXTDOMAIN + * macro. *---------- */ -#define ereport(elevel, rest) \ - (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO) ? \ +#define ereport_domain(elevel, domain, rest) \ + (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \ (errfinish rest) : (void) 0) +#define ereport(level, rest) \ + ereport_domain(level, TEXTDOMAIN, rest) + +#define TEXTDOMAIN NULL + extern bool errstart(int elevel, const char *filename, int lineno, - const char *funcname); + const char *funcname, const char *domain); extern void errfinish(int dummy,...); extern int errcode(int sqlerrcode); @@ -269,6 +281,7 @@ typedef struct ErrorData const char *filename; /* __FILE__ of ereport() call */ int lineno; /* __LINE__ of ereport() call */ const char *funcname; /* __func__ of ereport() call */ + const char *domain; /* message domain, NULL if default */ int sqlerrcode; /* encoded ERRSTATE */ char *message; /* primary error message */ char *detail; /* detail error message */ diff --git a/src/pl/plperl/nls.mk b/src/pl/plperl/nls.mk new file mode 100644 index 0000000000..82f652f709 --- /dev/null +++ b/src/pl/plperl/nls.mk @@ -0,0 +1,5 @@ +# $PostgreSQL$ +CATALOG_NAME := plperl +AVAIL_LANGUAGES := +GETTEXT_FILES := plperl.c SPI.xs +GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr croak Perl_croak diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 234579f46d..43044aa7c1 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -30,6 +30,10 @@ #include "utils/typcache.h" #include "utils/hsearch.h" +/* define our text domain for translations */ +#undef TEXTDOMAIN +#define TEXTDOMAIN "plperl" + /* perl stuff */ #include "plperl.h" @@ -186,8 +190,10 @@ _PG_init(void) if (inited) return; + set_text_domain(TEXTDOMAIN); + DefineCustomBoolVariable("plperl.use_strict", - "If true, will compile trusted and untrusted perl code in strict mode", + gettext_noop("If true, will compile trusted and untrusted perl code in strict mode"), NULL, &plperl_use_strict, PGC_USERSET, diff --git a/src/pl/plpgsql/src/nls.mk b/src/pl/plpgsql/src/nls.mk new file mode 100644 index 0000000000..f97a1ce424 --- /dev/null +++ b/src/pl/plpgsql/src/nls.mk @@ -0,0 +1,8 @@ +# $PostgreSQL$ +CATALOG_NAME := plpgsql +AVAIL_LANGUAGES := +GETTEXT_FILES := pl_comp.c pl_exec.c pl_gram.c pl_funcs.c pl_handler.c pl_scan.c +GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror + +.PHONY: gettext-files +gettext-files: distprep diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c index 51c1214c32..23dfb8e393 100644 --- a/src/pl/plpgsql/src/pl_handler.c +++ b/src/pl/plpgsql/src/pl_handler.c @@ -42,6 +42,8 @@ _PG_init(void) if (inited) return; + set_text_domain(TEXTDOMAIN); + plpgsql_HashTableInit(); RegisterXactCallback(plpgsql_xact_cb, NULL); RegisterSubXactCallback(plpgsql_subxact_cb, NULL); diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index a526039d7f..7a40495694 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -28,6 +28,10 @@ * Definitions **********************************************************************/ +/* define our text domain for translations */ +#undef TEXTDOMAIN +#define TEXTDOMAIN "plpgsql" + /* ---------- * Compiler's namestack item types * ---------- diff --git a/src/pl/plpython/nls.mk b/src/pl/plpython/nls.mk new file mode 100644 index 0000000000..c9505ecf76 --- /dev/null +++ b/src/pl/plpython/nls.mk @@ -0,0 +1,5 @@ +# $PostgreSQL$ +CATALOG_NAME := plpython +AVAIL_LANGUAGES := +GETTEXT_FILES := plpython.c +GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 1f12d5c14b..8e0a5985e2 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -63,6 +63,10 @@ typedef int Py_ssize_t; #include "utils/syscache.h" #include "utils/typcache.h" +/* define our text domain for translations */ +#undef TEXTDOMAIN +#define TEXTDOMAIN "plpython" + #include #include @@ -2745,6 +2749,8 @@ _PG_init(void) if (inited) return; + set_text_domain(TEXTDOMAIN); + Py_Initialize(); PLy_init_interp(); PLy_init_plpy(); diff --git a/src/pl/tcl/nls.mk b/src/pl/tcl/nls.mk new file mode 100644 index 0000000000..72baa7fb28 --- /dev/null +++ b/src/pl/tcl/nls.mk @@ -0,0 +1,5 @@ +# $PostgreSQL$ +CATALOG_NAME := pltcl +AVAIL_LANGUAGES := +GETTEXT_FILES := pltcl.c +GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 39419445da..4b468e9a9f 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -41,6 +41,10 @@ #define Tcl_GetStringResult(interp) ((interp)->result) #endif +/* define our text domain for translations */ +#undef TEXTDOMAIN +#define TEXTDOMAIN "pltcl" + #if defined(UNICODE_CONVERSION) && HAVE_TCL_VERSION(8,1) #include "mb/pg_wchar.h" @@ -263,6 +267,8 @@ _PG_init(void) if (pltcl_pm_init_done) return; + set_text_domain(TEXTDOMAIN); + #ifdef WIN32 /* Required on win32 to prevent error loading init.tcl */ Tcl_FindExecutable(""); -- 2.39.5