Fri 01 Feb 2013 03:18:37 PM UTC, original submission:
When run with --expand-tabs, skel variables are passed to generate_string() in
the generated code, regardless of their type. For string variables, this is
fine. For non-string variables, this causes a compilation error for generated
C++ code, and a runtime segfault for generated C code.
For example, take the following skel file:
@array_name@[@array_index:int@]
When run like this:
$ gengen --expand-tabs < skel
The following code is generated:
void generate_gengen(ostream &stream, unsigned int indent = 0)
{
string indent_str (indent, ' ');
indent = 0;
generate_string (array_name, stream, indent + indent_str.length ());
stream << "[";
generate_string (array_index, stream, indent + indent_str.length ());
stream << "]";
stream << "\n";
stream << indent_str;
}
You can see array_name and array_index are both passed to generate_string(),
even though generate_string() takes a const string & as its first parameter,
and not an int. Passing array_index causes a compiler error.
When run like this:
gengen --expand-tabs --output-format=c < skel
The following code is generated:
void
generate_gengen(FILE stream, struct gengen_gen_struct record, unsigned int indent)
{
char *indent_str;
unsigned int i;
indent_str = (char *) malloc (indent + 1);
for (i = 0; i < indent; ++i)
indent_str[i] = ' ';
indent_str[indent] = '\0';
indent = 0;
generate_string ((record->array_name ? record->array_name : ""), stream, indent + strlen (indent_str));
fprintf (stream, "%s", "[");
generate_string ((record->array_index ? record->array_index : ""), stream, indent + strlen (indent_str));
fprintf (stream, "%s", "]");
fprintf (stream, "%s", "\n");
fprintf (stream, "%s", indent_str);
free (indent_str);
}
Again, you can see record->array_name and record->array_index both being passed
to generate_string(), even though generate_string() takes a const char * as its
first paramater, and not an int. This creates a compiler warning and segfaults
at runtime (the int is treated as a pointer).
I have attached a patch for src/skelstruct_cpp.cc and src/skelstruct_c.cpp that
works, in both cases, as follows:
Previously, the generation logic worked like this:
if expand-tabs
send the variable through generate_string()
else
just output the variable
The patch changes this to:
if variable-type is string and expand-tabs
send the variable through generate_string()
else
just output the variable
This should work OK, because non-string type variables (bools and ints) can not
contain newlines anyway, and do not need to be indented, so generate_string()
would have no effect on them.
|