aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/preproc/ecpg.header
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-10-14 13:55:08 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-10-14 13:55:08 -0400
commit1acd0f55274fab8c936779a0f2b738f6005cc48f (patch)
treecfcd82b581fa2cfc0ce25608f0d0adaf38811159 /src/interfaces/ecpg/preproc/ecpg.header
parentf18231e817599246fc99a798c9bf57ab785db91f (diff)
downloadpostgresql-1acd0f55274fab8c936779a0f2b738f6005cc48f.tar.gz
postgresql-1acd0f55274fab8c936779a0f2b738f6005cc48f.zip
ecpg: improve preprocessor's memory management.
Invent a notion of "local" storage that will automatically be reclaimed at the end of each statement. Use this for location strings as well as other visibly short-lived data within the parser. Also, make cat_str and make_str return local storage and not free their inputs, which allows dispensing with a whole lot of retail mm_strdup calls. We do have to add some new ones in places where a local-lifetime string needs to be added to a longer-lived data structure, but on balance there are a lot less mm_strdup calls than before. In hopes of flushing out places where changes were necessary, I changed YYLTYPE from "char *" to "const char *", which forced const-ification of various function arguments that probably should've been like that all along. This still leaks somewhat more memory than v17, but that will be cleaned up in future commits. Discussion: https://postgr.es/m/2011420.1713493114@sss.pgh.pa.us
Diffstat (limited to 'src/interfaces/ecpg/preproc/ecpg.header')
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.header167
1 files changed, 84 insertions, 83 deletions
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 929ffa97aa0..d3df8eabbb7 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -39,8 +39,6 @@ char *input_filename = NULL;
static int FoundInto = 0;
static int initializer = 0;
static int pacounter = 1;
-static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the
- * size we need */
static struct this_type actual_type[STRUCT_DEPTH];
static char *actual_startline[STRUCT_DEPTH];
static int varchar_counter = 1;
@@ -95,7 +93,7 @@ yylloc_default(YYLTYPE *target, YYLTYPE *rhs, int N)
needed++;
needed += thislen;
}
- result = (char *) mm_alloc(needed + 1);
+ result = (char *) loc_alloc(needed + 1);
ptr = result;
for (int i = 1; i <= N; i++)
{
@@ -115,22 +113,19 @@ yylloc_default(YYLTYPE *target, YYLTYPE *rhs, int N)
*target = rhs[1];
}
else
- *target = EMPTY;
+ {
+ /* No need to allocate any space */
+ *target = "";
+ }
}
/* and the rest */
static char *
-make_name(void)
-{
- return mm_strdup(base_yytext);
-}
-
-static char *
-create_questionmarks(char *name, bool array)
+create_questionmarks(const char *name, bool array)
{
struct variable *p = find_variable(name);
int count;
- char *result = EMPTY;
+ char *result = "";
/*
* In case we have a struct, we have to print as many "?" as there are
@@ -158,12 +153,13 @@ create_questionmarks(char *name, bool array)
for (; count > 0; count--)
{
- sprintf(pacounter_buffer, "$%d", pacounter++);
- result = cat_str(3, result, mm_strdup(pacounter_buffer), mm_strdup(" , "));
- }
+ char buf[32];
- /* removed the trailing " ," */
+ snprintf(buf, sizeof(buf), "$%d", pacounter++);
+ result = cat_str(3, result, buf, " , ");
+ }
+ /* remove the trailing " ," */
result[strlen(result) - 3] = '\0';
return result;
}
@@ -183,8 +179,7 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
* pointer instead of the variable. Do it only for local variables, not
* for globals.
*/
-
- char *result = EMPTY;
+ char *result = "";
int insert;
for (insert = 1; insert >= 0; insert--)
@@ -206,7 +201,7 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
/* change variable name to "ECPGget_var(<counter>)" */
original_var = ptr->variable->name;
- sprintf(var_text, "%d))", ecpg_internal_var);
+ snprintf(var_text, sizeof(var_text), "%d))", ecpg_internal_var);
/* Don't emit ECPGset_var() calls for global variables */
if (ptr->variable->brace_level == 0)
@@ -227,12 +222,12 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
&& ptr->variable->type->type != ECPGt_bytea)
&& atoi(ptr->variable->type->size) > 1)
{
- newvar = new_variable(cat_str(4, mm_strdup("("),
- mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newvar = new_variable(cat_str(4, "(",
+ ecpg_type_name(ptr->variable->type->u.element->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type,
- mm_strdup("1"),
+ "1",
ptr->variable->type->u.element->counter),
ptr->variable->type->size),
0);
@@ -244,10 +239,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
|| ptr->variable->type->type == ECPGt_bytea)
&& atoi(ptr->variable->type->size) > 1)
{
- newvar = new_variable(cat_str(4, mm_strdup("("),
- mm_strdup(ecpg_type_name(ptr->variable->type->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newvar = new_variable(cat_str(4, "(",
+ ecpg_type_name(ptr->variable->type->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_simple_type(ptr->variable->type->type,
ptr->variable->type->size,
ptr->variable->type->counter),
@@ -259,11 +254,11 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
else if (ptr->variable->type->type == ECPGt_struct
|| ptr->variable->type->type == ECPGt_union)
{
- newvar = new_variable(cat_str(5, mm_strdup("(*("),
- mm_strdup(ptr->variable->type->type_name),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text),
- mm_strdup(")")),
+ newvar = new_variable(cat_str(5, "(*(",
+ ptr->variable->type->type_name,
+ " *)(ECPGget_var(",
+ var_text,
+ ")"),
ECPGmake_struct_type(ptr->variable->type->u.members,
ptr->variable->type->type,
ptr->variable->type->type_name,
@@ -276,11 +271,11 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
if (ptr->variable->type->u.element->type == ECPGt_struct
|| ptr->variable->type->u.element->type == ECPGt_union)
{
- newvar = new_variable(cat_str(5, mm_strdup("(*("),
- mm_strdup(ptr->variable->type->u.element->type_name),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text),
- mm_strdup(")")),
+ newvar = new_variable(cat_str(5, "(*(",
+ ptr->variable->type->u.element->type_name,
+ " *)(ECPGget_var(",
+ var_text,
+ ")"),
ECPGmake_struct_type(ptr->variable->type->u.element->u.members,
ptr->variable->type->u.element->type,
ptr->variable->type->u.element->type_name,
@@ -289,10 +284,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
}
else
{
- newvar = new_variable(cat_str(4, mm_strdup("("),
- mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newvar = new_variable(cat_str(4, "(",
+ ecpg_type_name(ptr->variable->type->u.element->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type,
ptr->variable->type->u.element->size,
ptr->variable->type->u.element->counter),
@@ -303,10 +298,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
}
else
{
- newvar = new_variable(cat_str(4, mm_strdup("*("),
- mm_strdup(ecpg_type_name(ptr->variable->type->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newvar = new_variable(cat_str(4, "*(",
+ ecpg_type_name(ptr->variable->type->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_simple_type(ptr->variable->type->type,
ptr->variable->type->size,
ptr->variable->type->counter),
@@ -320,10 +315,11 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
*/
if (!skip_set_var)
{
- sprintf(var_text, "%d, %s", ecpg_internal_var++, var_ptr ? "&(" : "(");
- result = cat_str(5, result, mm_strdup("ECPGset_var("),
- mm_strdup(var_text), mm_strdup(original_var),
- mm_strdup("), __LINE__);\n"));
+ snprintf(var_text, sizeof(var_text), "%d, %s",
+ ecpg_internal_var++, var_ptr ? "&(" : "(");
+ result = cat_str(5, result, "ECPGset_var(",
+ var_text, original_var,
+ "), __LINE__);\n");
}
/*
@@ -338,17 +334,17 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
{
/* change variable name to "ECPGget_var(<counter>)" */
original_var = ptr->indicator->name;
- sprintf(var_text, "%d))", ecpg_internal_var);
+ snprintf(var_text, sizeof(var_text), "%d))", ecpg_internal_var);
var_ptr = false;
if (ptr->indicator->type->type == ECPGt_struct
|| ptr->indicator->type->type == ECPGt_union)
{
- newind = new_variable(cat_str(5, mm_strdup("(*("),
- mm_strdup(ptr->indicator->type->type_name),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text),
- mm_strdup(")")),
+ newind = new_variable(cat_str(5, "(*(",
+ ptr->indicator->type->type_name,
+ " *)(ECPGget_var(",
+ var_text,
+ ")"),
ECPGmake_struct_type(ptr->indicator->type->u.members,
ptr->indicator->type->type,
ptr->indicator->type->type_name,
@@ -361,11 +357,11 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
if (ptr->indicator->type->u.element->type == ECPGt_struct
|| ptr->indicator->type->u.element->type == ECPGt_union)
{
- newind = new_variable(cat_str(5, mm_strdup("(*("),
- mm_strdup(ptr->indicator->type->u.element->type_name),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text),
- mm_strdup(")")),
+ newind = new_variable(cat_str(5, "(*(",
+ ptr->indicator->type->u.element->type_name,
+ " *)(ECPGget_var(",
+ var_text,
+ ")"),
ECPGmake_struct_type(ptr->indicator->type->u.element->u.members,
ptr->indicator->type->u.element->type,
ptr->indicator->type->u.element->type_name,
@@ -374,9 +370,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
}
else
{
- newind = new_variable(cat_str(4, mm_strdup("("),
- mm_strdup(ecpg_type_name(ptr->indicator->type->u.element->type)),
- mm_strdup(" *)(ECPGget_var("), mm_strdup(var_text)),
+ newind = new_variable(cat_str(4, "(",
+ ecpg_type_name(ptr->indicator->type->u.element->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type,
ptr->indicator->type->u.element->size,
ptr->indicator->type->u.element->counter),
@@ -387,10 +384,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
}
else if (atoi(ptr->indicator->type->size) > 1)
{
- newind = new_variable(cat_str(4, mm_strdup("("),
- mm_strdup(ecpg_type_name(ptr->indicator->type->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newind = new_variable(cat_str(4, "(",
+ ecpg_type_name(ptr->indicator->type->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_simple_type(ptr->indicator->type->type,
ptr->indicator->type->size,
ptr->variable->type->counter),
@@ -398,10 +395,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
}
else
{
- newind = new_variable(cat_str(4, mm_strdup("*("),
- mm_strdup(ecpg_type_name(ptr->indicator->type->type)),
- mm_strdup(" *)(ECPGget_var("),
- mm_strdup(var_text)),
+ newind = new_variable(cat_str(4, "*(",
+ ecpg_type_name(ptr->indicator->type->type),
+ " *)(ECPGget_var(",
+ var_text),
ECPGmake_simple_type(ptr->indicator->type->type,
ptr->indicator->type->size,
ptr->variable->type->counter),
@@ -413,10 +410,11 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
* create call to "ECPGset_var(<counter>, <pointer>. <line
* number>)"
*/
- sprintf(var_text, "%d, %s", ecpg_internal_var++, var_ptr ? "&(" : "(");
- result = cat_str(5, result, mm_strdup("ECPGset_var("),
- mm_strdup(var_text), mm_strdup(original_var),
- mm_strdup("), __LINE__);\n"));
+ snprintf(var_text, sizeof(var_text), "%d, %s",
+ ecpg_internal_var++, var_ptr ? "&(" : "(");
+ result = cat_str(5, result, "ECPGset_var(",
+ var_text, original_var,
+ "), __LINE__);\n");
}
add_variable_to_tail(&newlist, newvar, newind);
@@ -437,7 +435,7 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
(cur->function != NULL && strcmp(cur->function, current_function) == 0))
static struct cursor *
-add_additional_variables(char *name, bool insert)
+add_additional_variables(const char *name, bool insert)
{
struct cursor *ptr;
struct arguments *p;
@@ -475,8 +473,10 @@ add_additional_variables(char *name, bool insert)
}
static void
-add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum,
- char *type_dimension, char *type_index, int initializer, int array)
+add_typedef(const char *name, const char *dimension, const char *length,
+ enum ECPGttype type_enum,
+ const char *type_dimension, const char *type_index,
+ int initializer, int array)
{
/* add entry to list */
struct typedefs *ptr,
@@ -496,19 +496,20 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum,
/* re-definition is a bug */
mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", name);
}
- adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
+ adjust_array(type_enum, &dimension, &length,
+ type_dimension, type_index, array, true);
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
/* initial definition */
this->next = types;
- this->name = name;
+ this->name = mm_strdup(name);
this->brace_level = braces_open;
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
this->type->type_enum = type_enum;
this->type->type_str = mm_strdup(name);
- this->type->type_dimension = dimension; /* dimension of array */
- this->type->type_index = length; /* length of string */
+ this->type->type_dimension = mm_strdup(dimension); /* dimension of array */
+ this->type->type_index = mm_strdup(length); /* length of string */
this->type->type_sizeof = ECPGstruct_sizeof;
this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;