mirror of
https://github.com/postgres/postgres.git
synced 2025-05-11 05:41:32 +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 \
|
preproc.o \
|
||||||
type.o \
|
type.o \
|
||||||
typename.o \
|
typename.o \
|
||||||
|
util.o \
|
||||||
variable.o
|
variable.o
|
||||||
|
|
||||||
# where to find gen_keywordlist.pl and subsidiary files
|
# 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 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);
|
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
|
* "Location tracking" support. We commandeer Bison's location tracking
|
||||||
|
@ -10,6 +10,7 @@ ecpg_sources = files(
|
|||||||
'output.c',
|
'output.c',
|
||||||
'parser.c',
|
'parser.c',
|
||||||
'type.c',
|
'type.c',
|
||||||
|
'util.c',
|
||||||
'variable.c',
|
'variable.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ extern int base_yylex(void);
|
|||||||
extern void base_yyerror(const char *error);
|
extern void base_yyerror(const char *error);
|
||||||
extern void *mm_alloc(size_t size);
|
extern void *mm_alloc(size_t size);
|
||||||
extern char *mm_strdup(const char *string);
|
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 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 mmfatal(int error_code, const char *error,...) pg_attribute_printf(2, 3) pg_attribute_noreturn();
|
||||||
extern void output_get_descr_header(char *desc_name);
|
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};
|
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 */
|
/* duplicate memberlist */
|
||||||
struct ECPGstruct_member *
|
struct ECPGstruct_member *
|
||||||
ECPGstruct_member_dup(struct ECPGstruct_member *rm)
|
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