diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2024-10-14 13:47:59 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2024-10-14 13:47:59 -0400 |
commit | f18231e817599246fc99a798c9bf57ab785db91f (patch) | |
tree | 73c9c524c00ee469f32b1e3703f757bf04321c4c /src/interfaces/ecpg/preproc/util.c | |
parent | a542d5614bdb6430094556162b9ca2f01d35f9dc (diff) | |
download | postgresql-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.c | 189 |
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; +} |