I have a project to make the functions of a C program available to Perl for
unit testing purposes. A lot of them use structs like so...
typedef struct
{
char *config_file_name;
char *input_file_name;
char *time_str;
int test_mode; /* flag set from command line or config value */
int mail_input; /* flag set from command line */
int debug; /* flag set from command line */
int save; /* flag set from command line */
GHashTable *forw_hash; /* stores email addresses for forward messages */
...and so on...
} options_struct_t
Note the additional complication of the non-standard GHashTable type (from
Gnome).
They pass them into functions to be modified, prototyped like this:
void set_option(
options_struct_t *options,
char *key,
char *val,
);
I'm having difficulty figuring out how best to map this to Perl, both
conceptually and the XS details. If I was making it Perlish I might have an
options object:
$options->set($key, $val);
but I'm hesitant to change the interface so radically, the point is to test
the C code. I'm going with a more literal translation:
my $opts = {};
set_option( $opts, foo => $foo );
set_option( $opts, bar => $bar );
The real issue is how best to translate between the struct and Perl. Using a
hash, like I do above, means I have to translate key element of the struct to
a hash key and back.
void
_hv2options(HV *hash, options_struct_t *options) {
SV ** hash_val;
if( hash_val = hv_fetchs( hash, "mail_input", 0 ) )
options->mail_input = SvIV(*hash_val);
if( hash_val = hv_fetchs( hash, "input_file_name", 0 ) )
options->input_file_name = SvPV_nolen(*hash_val);
...and so on...
}
void
_options2hv(options_struct_t *options, HV *hash) {
hv_stores(hash, "mail_input", newSViv( options->mail_input ));
hv_stores(hash, "input_file_name", newSVpv( options->input_file_name, 0 ));
...and so on...
}
As you can imagine, this rapidly gets tiresome. Also I'm a crappy C programmer.
I know there's something to make C structs act like objects, but I'm having
trouble wrapping my head around it. I have this vague feeling that there's a
way to make Perl auto-generate accessors to each struct element but I'm not
sure how.
Any help?
Complicating this problem is that h2xs will not run over this code, it gets
lost in the twisty maze of includes and drags the CPU with it down in a
drunken spiral.
--
125. Two drink limit does not mean two kinds of drinks.
-- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army
http://skippyslist.com/list/