Skip to content

Commit

Permalink
[C] Deprecate *_create() to avoid *_free() confusion
Browse files Browse the repository at this point in the history
The behaviour of *_free() doesn't match *_create(), so the user should
avoid using them together. But they still need *_free() to clean up
library-allocated objects, so add a _library_owned flag to each struct
as an attempt to tell them apart. This isn't perfect though, because the
user may neglect to zero the field, but they would still see a warning
once in a while so it serves its purpose.

To prevent the new deprecation warnings (intended for the user) from
showing up during the library build itself, define a new family of
*_create_internal() functions, and turn *_create() into simple wrappers.
  • Loading branch information
eafer committed Dec 26, 2024
1 parent 6d2f2c9 commit 43aa9e5
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ char* {{classname}}_{{name}}_ToString({{projectName}}_{{classVarName}}_{{enumNam
{{/isContainer}}
{{/vars}}

{{classname}}_t *{{classname}}_create(
static {{classname}}_t *{{classname}}_create_internal(
{{#vars}}
{{^isContainer}}
{{^isPrimitiveType}}
Expand Down Expand Up @@ -205,14 +205,103 @@ char* {{classname}}_{{name}}_ToString({{projectName}}_{{classVarName}}_{{enumNam
{{classname}}_local_var->{{{name}}} = {{{name}}};
{{/vars}}

{{classname}}_local_var->_library_owned = 1;
return {{classname}}_local_var;
}

__attribute__((deprecated)) {{classname}}_t *{{classname}}_create(
{{#vars}}
{{^isContainer}}
{{^isPrimitiveType}}
{{#isModel}}
{{#isEnum}}
{{projectName}}_{{classVarName}}_{{enumName}}_e {{name}}{{^-last}},{{/-last}}
{{/isEnum}}
{{^isEnum}}
{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
{{/isEnum}}
{{/isModel}}
{{^isModel}}
{{^isFreeFormObject}}
{{^isEnum}}
{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
{{/isEnum}}
{{#isEnum}}
{{projectName}}_{{dataType}}_{{enumName}}_e {{name}}{{^-last}},{{/-last}}
{{/isEnum}}
{{/isFreeFormObject}}
{{/isModel}}
{{#isUuid}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isUuid}}
{{#isEmail}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isEmail}}
{{#isFreeFormObject}}
{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
{{/isFreeFormObject}}
{{/isPrimitiveType}}
{{#isPrimitiveType}}
{{#isNumeric}}
{{datatype}} {{name}}{{^-last}},{{/-last}}
{{/isNumeric}}
{{#isBoolean}}
{{datatype}} {{name}}{{^-last}},{{/-last}}
{{/isBoolean}}
{{#isEnum}}
{{#isString}}
{{projectName}}_{{classVarName}}_{{enumName}}_e {{name}}{{^-last}},{{/-last}}
{{/isString}}
{{/isEnum}}
{{^isEnum}}
{{#isString}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isString}}
{{/isEnum}}
{{#isByteArray}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isByteArray}}
{{#isBinary}}
{{datatype}} {{name}}{{^-last}},{{/-last}}
{{/isBinary}}
{{#isDate}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isDate}}
{{#isDateTime}}
{{datatype}} *{{name}}{{^-last}},{{/-last}}
{{/isDateTime}}
{{/isPrimitiveType}}
{{/isContainer}}
{{#isContainer}}
{{#isArray}}
{{#isPrimitiveType}}
{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
{{/isPrimitiveType}}
{{^isPrimitiveType}}
{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
{{/isPrimitiveType}}
{{/isArray}}
{{#isMap}}
{{datatype}} {{name}}{{^-last}},{{/-last}}
{{/isMap}}
{{/isContainer}}
{{/vars}}
) {
return {{classname}}_create_internal (
{{#vars}}
{{name}}{{^-last}},{{/-last}}
{{/vars}}
);
}

void {{classname}}_free({{classname}}_t *{{classname}}) {
if(NULL == {{classname}}){
return ;
}
if({{classname}}->_library_owned != 1){
fprintf(stderr, "WARNING: %s() does NOT free objects allocated by the user\n", "{{classname}}_free");
return ;
}
listEntry_t *listEntry;
{{#vars}}
{{^isContainer}}
Expand Down Expand Up @@ -859,7 +948,7 @@ fail:

{{/vars}}

{{classname}}_local_var = {{classname}}_create (
{{classname}}_local_var = {{classname}}_create_internal (
{{#vars}}
{{^isContainer}}
{{^isPrimitiveType}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,10 @@ typedef struct {{classname}}_t {
{{/isContainer}}
{{/vars}}

int _library_owned; // Is the library responsible for freeing this object?
} {{classname}}_t;

{{classname}}_t *{{classname}}_create(
__attribute__((deprecated)) {{classname}}_t *{{classname}}_create(
{{#vars}}
{{^isContainer}}
{{^isPrimitiveType}}
Expand Down

0 comments on commit 43aa9e5

Please sign in to comment.