GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \
     GUC_check_errmsg GUC_check_errdetail GUC_check_errhint \
     write_stderr yyerror parser_yyerror
+GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS) \
+    GUC_check_errmsg:1:c-format \
+    GUC_check_errdetail:1:c-format \
+    GUC_check_errhint:1:c-format \
+    write_stderr:1:c-format
 
 gettext-files: distprep
    find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@
 
                    ../../port/exec.c
 GETTEXT_TRIGGERS = write_msg:2 die_horribly:3 exit_horribly:3 simple_prompt \
                    ExecuteSqlCommand:3 ahlog:3
+GETTEXT_FLAGS  = \
+    write_msg:2:c-format \
+    die_horribly:3:c-format \
+    exit_horribly:3:c-format \
+    ahlog:3:c-format
 
                    mainloop.c print.c startup.c describe.c sql_help.h sql_help.c \
                    ../../port/exec.c
 GETTEXT_TRIGGERS = N_ psql_error simple_prompt
+GETTEXT_FLAGS    = psql_error:1:c-format
 
 AVAIL_LANGUAGES  = de es fr it ja pt_BR tr zh_CN
 GETTEXT_FILES    = connect.c error.c execute.c misc.c
 GETTEXT_TRIGGERS = ecpg_gettext
+GETTEXT_FLAGS    = ecpg_gettext:1:pass-c-format
 
 AVAIL_LANGUAGES  = de es fr it ja ko pt_BR tr zh_CN zh_TW
 GETTEXT_FILES    = descriptor.c ecpg.c pgc.c preproc.c type.c variable.c
 GETTEXT_TRIGGERS = mmerror:3
+GETTEXT_FLAGS    = mmerror:3:c-format
 
 AVAIL_LANGUAGES  = cs de es fr it ja ko pt_BR ru sv ta tr zh_CN zh_TW
 GETTEXT_FILES    = fe-auth.c fe-connect.c fe-exec.c fe-lobj.c fe-misc.c fe-protocol2.c fe-protocol3.c fe-secure.c
 GETTEXT_TRIGGERS = libpq_gettext pqInternalNotice:2
+GETTEXT_FLAGS    = libpq_gettext:1:pass-c-format pqInternalNotice:2:c-format
 
 # GETTEXT_FILES         -- list of source files that contain message strings
 # GETTEXT_TRIGGERS      -- (optional) list of functions that contain
 #                          translatable strings
+# GETTEXT_FLAGS         -- (optional) list of gettext --flag arguments to mark
+#                          function arguments that contain C format strings
+#                          (functions must be listed in TRIGGERS and FLAGS)
 #
 # That's all, the rest is done here, if --enable-nls was specified.
 #
 
 # _ is defined in c.h, so it's global
 GETTEXT_TRIGGERS += _
+GETTEXT_FLAGS    += _:1:pass-c-format
 
 
 # common settings that apply to backend and all backend modules
     errdetail errdetail_log errdetail_plural:1,2 \
     errhint \
     errcontext
+BACKEND_COMMON_GETTEXT_FLAGS = \
+    errmsg:1:c-format errmsg_plural:1:c-format errmsg_plural:2:c-format \
+    errdetail:1:c-format errdetail_log:1:c-format errdetail_plural:1:c-format errdetail_plural:2:c-format \
+    errhint:1:c-format \
+    errcontext:1:c-format
 
 
 all-po: $(MO_FILES)
 ifeq ($(word 1,$(GETTEXT_FILES)),+)
 po/$(CATALOG_NAME).pot: $(word 2, $(GETTEXT_FILES)) $(MAKEFILE_LIST)
 ifdef XGETTEXT
-   $(XGETTEXT) -D $(srcdir) -n $(addprefix -k, $(GETTEXT_TRIGGERS)) -f $<
+   $(XGETTEXT) -D $(srcdir) -n $(addprefix -k, $(GETTEXT_TRIGGERS)) $(addprefix --flag=, $(GETTEXT_FLAGS)) -f $<
 else
    @echo "You don't have 'xgettext'."; exit 1
 endif
 # Change to srcdir explicitly, don't rely on $^.  That way we get
 # consistent #: file references in the po files.
 ifdef XGETTEXT
-   $(XGETTEXT) -D $(srcdir) -n $(addprefix -k, $(GETTEXT_TRIGGERS)) $(GETTEXT_FILES)
+   $(XGETTEXT) -D $(srcdir) -n $(addprefix -k, $(GETTEXT_TRIGGERS)) $(addprefix --flag=, $(GETTEXT_FLAGS)) $(GETTEXT_FILES)
 else
    @echo "You don't have 'xgettext'."; exit 1
 endif
 
 AVAIL_LANGUAGES  = de es fr it ja pt_BR ro tr zh_CN zh_TW
 GETTEXT_FILES    = plperl.c SPI.c
 GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS)
+GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS)
 
 AVAIL_LANGUAGES  = de es fr it ja ko pt_BR ro zh_CN zh_TW
 GETTEXT_FILES    = pl_comp.c pl_exec.c pl_gram.c pl_funcs.c pl_handler.c pl_scanner.c
 GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror plpgsql_yyerror
+GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS)
 
 AVAIL_LANGUAGES  = de es fr it ja pt_BR ro tr zh_CN zh_TW
 GETTEXT_FILES    = plpython.c
 GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) PLy_elog:2 PLy_exception_set:2 PLy_exception_set_plural:2,3
+GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS) \
+    PLy_elog:2:c-format \
+    PLy_exception_set:2:c-format \
+    PLy_exception_set_plural:2:c-format \
+    PLy_exception_set_plural:3:c-format
 
 AVAIL_LANGUAGES  = de es fr it ja pt_BR ro tr zh_CN zh_TW
 GETTEXT_FILES    = pltcl.c
 GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS)
+GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS)