Reputation: 169
I have input that contains structures that are defined with a typedef. I later use these to initialize variables in my main function.
For example:
typedef struct {
int numer;
int denom;
} Rational;
int main()
{
Rational half, *newf = malloc(sizeof(Rational));
half = (Rational){ 1, 2 };
*newf = (Rational){ 2, 3 };
}
Here is what I want to do: I want to convert the two initialization lines into function calls.
For example:
half = (Rational){ 1, 2 };
should turn into:
init_Rational( &half, 1, 2 );
and
*newf = (Rational){ 2, 3 };
should turn into
init_Rational( newf, 2, 3 );
The trick is to remember that Rational was defined as a struct earlier and replace the initializations with function calls. It doesn't have to be called Rational, it could be any name.
Once it recognizes that the declaration is a struct typedef, it should do the following as shown above.
Turn:
something = (someStructName){ data1, data2, data3.. };
into
init_someStructName( &something, data1, data2, data3.. );
Or for pointers...Turn:
*something = (someStructName){ data1, data2, data3.. };
into
init_someStructName( something, data1, data2, data3.. );
Can someone help me out here? Thanks!
Upvotes: 1
Views: 82
Reputation: 4426
Almost unreadable!
sed -e 's/\(\**[a-zA-Z_][a-zA-Z_0-9]*\) *= *( *\([a-zA-Z_][a-zA-Z_0-9]*\) *) *{\([^}]*\)} *;/init_\2(\&\1,\3);/'
Note: it's a single line
Note2: I have assumed that there may be only spaces as possible separators (no TAB)
Note3: The form "*x
" is left unchanged, since it's transformed into &*x
, that it's correct. I have assumed that there aren't spaces between "*" and the identifier;
Upvotes: 0
Reputation: 208475
This is a pretty tricky problem, because needing to dynamically detect struct names means you can't write the entire regular expression in advance.
Here is one potential solution, assuming your file name is foo.c:
sed -n '/^typedef struct/,/^}/{/^}/{s/.* \(.*\);/\1/p}}' foo.c | xargs -I {} sed -i -e 's/^\(\s*\)\*\(\w*\) = ('{}'){\(.*\)};/\1init_'{}'( \2,\3);/' -e 's/^\(\s*\)\(\w*\) = ('{}'){\(.*\)};/\1init_'{}'( \&\2,\3);/' foo.c
This does one pass with sed
to print out each struct name on a line by itself, and then uses xargs
to construct an additional sed
command for each struct to perform the replacements on the file in place.
If your version of sed
doesn't support the \s
or \w
shortcuts, you can use [ \t]
instead of \s
and [_a-zA-Z0-9]
instead of \w
.
Upvotes: 1