#!/usr/bin/perl -w use strict; use XML::Twig; sub write_c_header(@); sub write_c_impl_defaults(@); sub write_c_impl_apply(@); sub write_c_impl_free(@); sub write_c_impl_dump(@); sub get_data($); # initialize parser and read the file my $input = "./config.xml"; my $parser = XML::Twig->new(); my $tree = $parser->parsefile($input) || die "Unable to parse XML file."; # Write header file open GENHEAD, ">gen_config.h" || die "Unable to write header file"; print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\nstruct hub_config\n{\n"; foreach my $p ($tree->root->children("option")) { my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example")); write_c_header(@data); } print GENHEAD "};\n\n"; # Write c source file open GENIMPL, ">gen_config.c" || die "Unable to write source file"; print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n"; # The defaults function print GENIMPL "void config_defaults(struct hub_config* config)\n{\n"; foreach my $p ($tree->root->children("option")) { write_c_impl_defaults(get_data($p)); } print GENIMPL "}\n\n"; # apply function print GENIMPL "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n"; foreach my $p ($tree->root->children("option")) { write_c_impl_apply(get_data($p)); } print GENIMPL "\t/* Still here -- unknown directive */\n"; print GENIMPL "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n"; print GENIMPL "\t\treturn -1;\n"; print GENIMPL "}\n\n"; # free function (for strings) print GENIMPL "void free_config(struct hub_config* config)\n{\n"; foreach my $p ($tree->root->children("option")) { write_c_impl_free(get_data($p)); } print GENIMPL "}\n\n"; # dump function print GENIMPL "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n"; foreach my $p ($tree->root->children("option")) { write_c_impl_dump(get_data($p)); } print GENIMPL "}\n\n"; sub write_c_header(@) { my @output = @_; my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output; print GENHEAD "\t"; print GENHEAD "int " if ($type eq "int"); print GENHEAD "int " if ($type eq "boolean"); print GENHEAD "char*" if ($type =~ /(string|file|message)/); print GENHEAD " " . $name . ";"; my $comment = ""; if ($type eq "message") { $comment = "\"" . $default . "\""; } elsif (defined $short && length $short > 0) { $comment = $short; $comment .= " (default: " . $default . ")" if (defined $default); } if (length $comment > 0) { my $pad = ""; for (my $i = length $name; $i < 32; $i++) { $pad .= " "; } $comment = $pad . "/*<<< " . $comment . " */"; } print GENHEAD $comment . "\n"; } sub write_c_impl_defaults(@) { my @output = @_; my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output; print GENIMPL "\t"; print GENIMPL "DEFAULT_INTEGER" if ($type eq "int"); print GENIMPL "DEFAULT_BOOLEAN" if ($type eq "boolean"); if ($type =~ /(string|file|message)/) { print GENIMPL "DEFAULT_STRING "; $default = "\"" . $default . "\""; } print GENIMPL "(" . $name . ", " . $default . ");\n"; } sub write_c_impl_apply(@) { my @output = @_; my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output; print GENIMPL "\t"; print GENIMPL "GET_INT " if ($type eq "int"); print GENIMPL "GET_BOOL" if ($type eq "boolean"); print GENIMPL "GET_STR " if ($type =~ /(string|file|message)/); print GENIMPL "(" . $name . ");\n"; } sub write_c_impl_free(@) { my @output = @_; my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output; print GENIMPL "\thub_free(config->" . $name . ");\n" if ($type =~ /(string|file|message)/) } sub write_c_impl_dump(@) { my @output = @_; my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output; print GENIMPL "\t"; print GENIMPL "DUMP_INT " if ($type eq "int"); print GENIMPL "DUMP_BOOL" if ($type eq "boolean"); if ($type =~ /(string|file|message)/) { print GENIMPL "DUMP_STR"; $default = "\"" . $default . "\""; } print GENIMPL "(" . $name . ", " . $default . ");\n" } sub get_data($) { my $p = shift; my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example")); return @data; }