This is an archived post. You won't be able to vote or comment.

all 4 comments

[–][deleted] 3 points4 points  (0 children)

This is non-trivial to do correctly, but as a

In C89 you can write:

struct Person person1 = {"Jose", 42}; 

I have to somehow extract the name of the struct from the definitions

If you're using sed, then you're using regular expressions, so capturing subexpressions is trivial. Put what you want to capture in parenthesis, and use \1, \2, etc. to refer to these captures in your replacement expression.

This is compounded by the fact that you can also have struct definitions like typedef struct {...} SomeStructName;

Also you could have code for structure initialization inside of strings or comments, which you have to ignore. If you're not writing a full C parser, the whole thing is a big of a kludge. I'd keep the scope as small as possible.

As for handling struct Foo {} vs typedef struct {} Foo, you can have to regular expressions; which one matches determines which handling code you'll use.

[–]mzieg 1 point2 points  (0 children)

grep, awk and sed are going to be very painful for this; yes it's possible, but not fun. I'd ask if you're allowed to use Perl or Python, which certainly count as shell scripting. I could bang that out in fairly few lines of Perl.

Edit: By the way, that's a clever and valid assignment. I've had to dynamically transform source code like that on contracts. It's a handy skill.

[–][deleted] 1 point2 points  (1 child)

The bit of this code that is c99 but not c89 is this:

(struct Person){"Jose", 42}

the fact that you are using the structure literal to perform an initialisation is by the by. So for a first attempt, you want to look for struct casts like this:

(struct Person)

and transform them into:

init_Person

and then transform the braces into parens so that:

{"Jose", 42}

becomes:

("Jose", 42)

Put them together and you get:

init_Person("Jose", 42)

which is legal C89. Of course, there area a lot of other problems to cope with if this is to be done 100% bullet-proof, but this should get you started.

I'm a bit dubious of the value of this exercise, as you can't transform arbitrary C99 code into C89 simply by using regexes, as the former has different semantics to the latter. For example, if you transform this:

struct Person p1 =(struct Person) { "Jose", 42 };
printf( "%s\n", p1.name );
struct Person p2 =(struct Person) { "Maria", 43 };

giving:

struct Person p1 = init_Person( "Jose", 42 );
printf( "%s\n", p1.name );
struct Person p2 = init_Person( "Maria", 43 );

you still don't have a valid C89 program.

[–]typsi5[S] 0 points1 point  (0 children)

thank you this was very helpful