mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
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
This commit is contained in:
parent
a542d5614b
commit
f18231e817
@ -36,6 +36,7 @@ OBJS = \
|
||||
preproc.o \
|
||||
type.o \
|
||||
typename.o \
|
||||
util.o \
|
||||
variable.o
|
||||
|
||||
# where to find gen_keywordlist.pl and subsidiary files
|
||||
|
@ -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
|
||||
|
@ -10,6 +10,7 @@ ecpg_sources = files(
|
||||
'output.c',
|
||||
'parser.c',
|
||||
'type.c',
|
||||
'util.c',
|
||||
'variable.c',
|
||||
)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
189
src/interfaces/ecpg/preproc/util.c
Normal file
189
src/interfaces/ecpg/preproc/util.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user