aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/preproc/util.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-10-14 13:47:59 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-10-14 13:47:59 -0400
commitf18231e817599246fc99a798c9bf57ab785db91f (patch)
tree73c9c524c00ee469f32b1e3703f757bf04321c4c /src/interfaces/ecpg/preproc/util.c
parenta542d5614bdb6430094556162b9ca2f01d35f9dc (diff)
downloadpostgresql-f18231e817599246fc99a798c9bf57ab785db91f.tar.gz
postgresql-f18231e817599246fc99a798c9bf57ab785db91f.zip
ecpg: move some functions into a new file ecpg/preproc/util.c.
mm_alloc and mm_strdup were in type.c, which seems a completely random choice. No doubt the original author thought two small functions didn't deserve their own file. But I'm about to add some more memory-management stuff beside them, so let's put them in a less surprising place. This seems like a better home for mmerror, mmfatal, and the cat_str/make_str family, too. Discussion: https://postgr.es/m/2011420.1713493114@sss.pgh.pa.us
Diffstat (limited to 'src/interfaces/ecpg/preproc/util.c')
-rw-r--r--src/interfaces/ecpg/preproc/util.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/preproc/util.c b/src/interfaces/ecpg/preproc/util.c
new file mode 100644
index 00000000000..cb1eca7f3cb
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/util.c
@@ -0,0 +1,189 @@
+/* src/interfaces/ecpg/preproc/util.c */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+
+#include "preproc_extern.h"
+
+static void vmmerror(int error_code, enum errortype type, const char *error, va_list ap) pg_attribute_printf(3, 0);
+
+
+/*
+ * Handle preprocessor errors and warnings
+ */
+static void
+vmmerror(int error_code, enum errortype type, const char *error, va_list ap)
+{
+ /* localize the error message string */
+ error = _(error);
+
+ fprintf(stderr, "%s:%d: ", input_filename, base_yylineno);
+
+ switch (type)
+ {
+ case ET_WARNING:
+ fprintf(stderr, _("WARNING: "));
+ break;
+ case ET_ERROR:
+ fprintf(stderr, _("ERROR: "));
+ break;
+ }
+
+ vfprintf(stderr, error, ap);
+
+ fprintf(stderr, "\n");
+
+ /* If appropriate, set error code to be inspected by ecpg.c */
+ switch (type)
+ {
+ case ET_WARNING:
+ break;
+ case ET_ERROR:
+ ret_value = error_code;
+ break;
+ }
+}
+
+/* Report an error or warning */
+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);
+}
+
+/* Report an error and abandon execution */
+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 (base_yyin)
+ fclose(base_yyin);
+ if (base_yyout)
+ fclose(base_yyout);
+
+ if (strcmp(output_filename, "-") != 0 && unlink(output_filename) != 0)
+ fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename);
+ exit(error_code);
+}
+
+/*
+ * Basic memory management support
+ */
+
+/* malloc + error check */
+void *
+mm_alloc(size_t size)
+{
+ void *ptr = malloc(size);
+
+ if (ptr == NULL)
+ mmfatal(OUT_OF_MEMORY, "out of memory");
+
+ return ptr;
+}
+
+/* strdup + error check */
+char *
+mm_strdup(const char *string)
+{
+ char *new = strdup(string);
+
+ if (new == NULL)
+ mmfatal(OUT_OF_MEMORY, "out of memory");
+
+ return new;
+}
+
+/*
+ * String concatenation
+ */
+
+/*
+ * Concatenate 2 strings, inserting a space between them unless either is empty
+ *
+ * The input strings are freed.
+ */
+char *
+cat2_str(char *str1, char *str2)
+{
+ char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + 2);
+
+ strcpy(res_str, str1);
+ if (strlen(str1) != 0 && strlen(str2) != 0)
+ strcat(res_str, " ");
+ strcat(res_str, str2);
+ free(str1);
+ free(str2);
+ return res_str;
+}
+
+/*
+ * Concatenate N strings, inserting spaces between them unless they are empty
+ *
+ * The input strings are freed.
+ */
+char *
+cat_str(int count,...)
+{
+ va_list args;
+ int i;
+ char *res_str;
+
+ va_start(args, count);
+
+ res_str = va_arg(args, char *);
+
+ /* now add all other strings */
+ for (i = 1; i < count; i++)
+ res_str = cat2_str(res_str, va_arg(args, char *));
+
+ va_end(args);
+
+ return res_str;
+}
+
+/*
+ * Concatenate 2 strings, with no space between
+ *
+ * The input strings are freed.
+ */
+char *
+make2_str(char *str1, char *str2)
+{
+ char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + 1);
+
+ strcpy(res_str, str1);
+ strcat(res_str, str2);
+ free(str1);
+ free(str2);
+ return res_str;
+}
+
+/*
+ * Concatenate 3 strings, with no space between
+ *
+ * The input strings are freed.
+ */
+char *
+make3_str(char *str1, char *str2, char *str3)
+{
+ char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
+
+ strcpy(res_str, str1);
+ strcat(res_str, str2);
+ strcat(res_str, str3);
+ free(str1);
+ free(str2);
+ free(str3);
+ return res_str;
+}