ecpg: move some functions into a new file ecpg/preproc/util.c.
authorTom Lane <[email protected]>
Mon, 14 Oct 2024 17:47:59 +0000 (13:47 -0400)
committerTom Lane <[email protected]>
Mon, 14 Oct 2024 17:47:59 +0000 (13:47 -0400)
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

src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/ecpg.header
src/interfaces/ecpg/preproc/meson.build
src/interfaces/ecpg/preproc/preproc_extern.h
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/util.c [new file with mode: 0644]

index c56fb92f4a47392f3ea745001c216eac010623ba..4f403da93550d8175bc54061e93a63c38d5dddce 100644 (file)
@@ -36,6 +36,7 @@ OBJS = \
        preproc.o \
        type.o \
        typename.o \
+       util.o \
        variable.o
 
 # where to find gen_keywordlist.pl and subsidiary files
index 8df6248c976dd3616c87dafd09431b5ddd651fd8..929ffa97aa077aafaf761be58c2cb06ffa3cdc19 100644 (file)
@@ -60,137 +60,8 @@ struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 
 static struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};
 
-static void vmmerror(int error_code, enum errortype type, const char *error, va_list ap) pg_attribute_printf(3, 0);
-
 static bool check_declared_list(const char *name);
 
-/*
- * Handle parsing 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");
-
-       switch (type)
-       {
-               case ET_WARNING:
-                       break;
-               case ET_ERROR:
-                       ret_value = error_code;
-                       break;
-       }
-}
-
-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 (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);
-}
-
-/*
- * string concatenation
- */
-
-static 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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static 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;
-}
 
 /*
  * "Location tracking" support.  We commandeer Bison's location tracking
index aebb88bb5892b0b7522236fa2bfd394129d1e15b..2fb1402c70c773b40b6396d9f2ce795952264e23 100644 (file)
@@ -10,6 +10,7 @@ ecpg_sources = files(
   'output.c',
   'parser.c',
   'type.c',
+  'util.c',
   'variable.c',
 )
 
index da93967462036b2190e9bbadc381c5de00cc2d6a..29329ccd89194f7549aefecceecd4416c6a44e4f 100644 (file)
@@ -82,6 +82,10 @@ extern int   base_yylex(void);
 extern void base_yyerror(const char *error);
 extern void *mm_alloc(size_t size);
 extern char *mm_strdup(const char *string);
+extern char *cat2_str(char *str1, char *str2);
+extern char *cat_str(int count,...);
+extern char *make2_str(char *str1, char *str2);
+extern char *make3_str(char *str1, char *str2, char *str3);
 extern void mmerror(int error_code, enum errortype type, const char *error,...) pg_attribute_printf(3, 4);
 extern void mmfatal(int error_code, const char *error,...) pg_attribute_printf(2, 3) pg_attribute_noreturn();
 extern void output_get_descr_header(char *desc_name);
index a842bb6a1fed7665ba092e6e28841b282f6bf4e1..5610a8dc76bffda703471746600358ad3818e389 100644 (file)
@@ -8,30 +8,6 @@
 
 static struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
 
-/* 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;
-}
-
 /* duplicate memberlist */
 struct ECPGstruct_member *
 ECPGstruct_member_dup(struct ECPGstruct_member *rm)
diff --git a/src/interfaces/ecpg/preproc/util.c b/src/interfaces/ecpg/preproc/util.c
new file mode 100644 (file)
index 0000000..cb1eca7
--- /dev/null
@@ -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;
+}