Similar to recent pg_upgrade changes
(https://commitfest.postgresql.org/action/patch_view?id=1216), here is a
patch to separate the terminating and nonterminating variants of
mmerror() in ecpg.
From 2c8cc7ea1135c9ceddb5b60c30e4363d3784cb29 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut pete...@gmx.net
Date: Tue, 12 Nov 2013 22:12:08 -0500
Subject: [PATCH] ecpg: Split off mmfatal() from mmerror()
This allows decorating mmfatal() with noreturn compiler hints, leading
to better diagnostics.
---
src/interfaces/ecpg/preproc/descriptor.c | 4 +--
src/interfaces/ecpg/preproc/ecpg.header | 47 +---
src/interfaces/ecpg/preproc/ecpg.trailer | 2 +-
src/interfaces/ecpg/preproc/extern.h | 6 ++--
src/interfaces/ecpg/preproc/nls.mk | 4 +--
src/interfaces/ecpg/preproc/pgc.l| 42 ++--
src/interfaces/ecpg/preproc/type.c | 14 +-
src/interfaces/ecpg/preproc/type.h | 2 +-
src/interfaces/ecpg/preproc/variable.c | 36
9 files changed, 85 insertions(+), 72 deletions(-)
diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c
index 115cb17..053a7af 100644
--- a/src/interfaces/ecpg/preproc/descriptor.c
+++ b/src/interfaces/ecpg/preproc/descriptor.c
@@ -274,7 +274,7 @@ output_set_descr(char *desc_name, char *index)
case ECPGd_di_precision:
case ECPGd_precision:
case ECPGd_scale:
-mmerror(PARSE_ERROR, ET_FATAL, descriptor item \%s\ is not implemented,
+mmfatal(PARSE_ERROR, descriptor item \%s\ is not implemented,
descriptor_item_name(results-value));
break;
@@ -284,7 +284,7 @@ output_set_descr(char *desc_name, char *index)
case ECPGd_octet:
case ECPGd_ret_length:
case ECPGd_ret_octet:
-mmerror(PARSE_ERROR, ET_FATAL, descriptor item \%s\ cannot be set,
+mmfatal(PARSE_ERROR, descriptor item \%s\ cannot be set,
descriptor_item_name(results-value));
break;
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 88d9cf5..71b11f4 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -64,11 +64,9 @@ struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};
/*
* Handle parsing errors and warnings
*/
-void
-mmerror(int error_code, enum errortype type, const char *error, ...)
+static void __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)))
+vmmerror(int error_code, enum errortype type, const char *error, va_list ap)
{
- va_list ap;
-
/* internationalize the error message string */
error = _(error);
@@ -80,14 +78,11 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
fprintf(stderr, _(WARNING: ));
break;
case ET_ERROR:
- case ET_FATAL:
fprintf(stderr, _(ERROR: ));
break;
}
- va_start(ap, error);
vfprintf(stderr, error, ap);
- va_end(ap);
fprintf(stderr, \n);
@@ -98,18 +93,38 @@ mmerror(int error_code, enum errortype type, const char *error, ...)
case ET_ERROR:
ret_value = error_code;
break;
- case ET_FATAL:
- if (yyin)
-fclose(yyin);
- if (yyout)
-fclose(yyout);
-
- if (strcmp(output_filename, -) != 0 unlink(output_filename) != 0)
-fprintf(stderr, _(could not remove output file \%s\\n), output_filename);
- exit(error_code);
}
}
+void
+mmerror(int error_code, enum errortype type, const char *error, ...)
+{
+ va_list ap;
+
+ va_start(ap, error);
+ vmmerror(error_code, type, error, ap);
+ va_end(ap);
+}
+
+void
+mmfatal(int error_code, const char *error, ...)
+{
+ va_list ap;
+
+ va_start(ap, error);
+ vmmerror(error_code, ET_ERROR, error, ap);
+ va_end(ap);
+
+ if (yyin)
+ fclose(yyin);
+ if (yyout)
+ fclose(yyout);
+
+ if (strcmp(output_filename, -) != 0 unlink(output_filename) != 0)
+ fprintf(stderr, _(could not remove output file \%s\\n), output_filename);
+ exit(error_code);
+}
+
/*
* string concatenation
*/
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 58155ab..342b7bc 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -1687,7 +1687,7 @@ cvariable: CVARIABLE
{
case '[':
if (brace)
-mmerror(PARSE_ERROR, ET_FATAL, multidimensional arrays for simple data types are not supported);
+mmfatal(PARSE_ERROR, multidimensional arrays for simple data types are not supported);
brace_open++;
break;
case ']':
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index ccf5548..3bbb6a4 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -73,10 +73,8 @@ extern int base_yylex(void);
extern void base_yyerror(const char *);
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
extern char *mm_strdup(const char *);
-extern void
-mmerror(int, enum