diff --git a/src/core/config.pl b/src/core/config.pl
index 0037ffd..bb92f74 100755
--- a/src/core/config.pl
+++ b/src/core/config.pl
@@ -1,241 +1,270 @@
#!/usr/bin/perl -w
use strict;
-use XML::Twig;
+use XML::DOM;
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 write_sql_dump(@);
sub get_data($);
+my $dump_to_sql = 0;
+
# initialize parser and read the file
my $input = "./config.xml";
-my $parser = XML::Twig->new();
+my $parser = new XML::DOM::Parser;
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"))
+# Get data
+my $nodes = $tree->getElementsByTagName("option");
+my @options = ();
+for (my $i = 0; $i < $nodes->getLength; $i++)
{
- write_c_header(get_data($p));
+ my @data = get_data($nodes->item($i));
+ push @options, \@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";
+write_c_header(@options);
+write_sql_dump(@options) if ($dump_to_sql);
-# The defaults function
-print GENIMPL "void config_defaults(struct hub_config* config)\n{\n";
-foreach my $p ($tree->root->children("option"))
+my $config_defaults = "void config_defaults(struct hub_config* config)\n{\n";
+my $config_apply = "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n";
+my $config_free = "void free_config(struct hub_config* config)\n{\n";
+my $config_dump = "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n";
+
+foreach my $option (@options)
{
- write_c_impl_defaults(get_data($p));
-}
-print GENIMPL "}\n\n";
+ my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check) = @$option;
+ my $string = ($type =~ /(string|file|message)/);
+ my $min = undef;
+ my $max = undef;
+ my $regexp = undef;
-# apply function
-print GENIMPL "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\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")
+ if (defined $check)
{
- $comment = "\"" . $default . "\"";
- }
- elsif (defined $short && length $short > 0)
- {
- $comment = $short;
- $comment .= " (default: " . $default . ")" if (defined $default);
+ $min = $check->getAttribute("min");
+ $max = $check->getAttribute("max");
+ $regexp = $check->getAttribute("regexp");
+
+ $max = undef if ($max eq "");
+ $min = undef if ($min eq "");
+ $regexp = undef if ($regexp eq "");
}
- if (length $comment > 0)
- {
- my $pad = "";
- for (my $i = length $name; $i < 32; $i++)
- {
- $pad .= " ";
- }
- $comment = $pad . "/*<<< " . $comment . " */";
- }
+ $config_defaults .= "\tconfig->$name = ";
+ $config_defaults .= "hub_strdup(\"" if ($string);
+ $config_defaults .= $default;
+ $config_defaults .= "\")" if ($string);
+ $config_defaults .= ";\n";
- print GENHEAD $comment . "\n";
-}
-
-sub write_c_impl_defaults(@)
-{
- my @output = @_;
- my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
- my $prefix = "";
- my $suffix = "";
-
- print GENIMPL "\tconfig->$name = ";
- if ($type =~ /(string|file|message)/)
- {
- $prefix = "hub_strdup(\"";
- $suffix = "\")"
- }
- print GENIMPL $prefix . $default . $suffix . ";\n";
-}
-
-sub write_c_impl_apply(@)
-{
- my @output = @_;
- my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $p) = @output;
-
- my $min;
- my $max;
- my $regexp;
-
- if (defined $p)
- {
- $min = $p->att("min");
- $max = $p->att("max");
- $regexp = $p->att("regexp");
-
- print "'check' is defined for option $name";
- print ", min=$min" if (defined $min);
- print ", max=$max" if (defined $max);
- print ", regexp=\"$regexp\"" if (defined $regexp);
- print "\n";
- }
-
- print GENIMPL "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
+ $config_apply .= "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
if ($type eq "int")
{
- if (defined $min)
- {
- print GENIMPL "\t\tmin = $min;\n"
- }
- if (defined $max)
- {
- print GENIMPL "\t\tmax = $max;\n"
- }
-
- print GENIMPL "\t\tif (!apply_integer(key, data, &config->$name, ";
-
- if (defined $min)
- {
- print GENIMPL "&min";
- }
- else
- {
- print GENIMPL "0";
- }
-
- print GENIMPL ", ";
-
- if (defined $max)
- {
- print GENIMPL "&max";
- }
- else
- {
- print GENIMPL "0";
- }
-
- print GENIMPL "))\n";
+ $config_apply .= "\t\tmin = $min;\n" if (defined $min);
+ $config_apply .= "\t\tmax = $max;\n" if (defined $max);
+ $config_apply .= "\t\tif (!apply_integer(key, data, &config->$name, ";
+ if (defined $min) { $config_apply .= "&min"; } else { $config_apply .= "0"; }
+ $config_apply .= ", ";
+ if (defined $max) { $config_apply .= "&max"; } else { $config_apply .= "0"; }
+ $config_apply .= "))\n";
}
elsif ($type eq "boolean")
{
- print GENIMPL "\t\tif (!apply_boolean(key, data, &config->$name))\n";
+ $config_apply .= "\t\tif (!apply_boolean(key, data, &config->$name))\n";
}
- elsif ($type =~ /(string|file|message)/)
+ elsif ($string)
{
- print GENIMPL "\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
+ $config_apply .="\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
}
- print GENIMPL "\t\t{\n" .
+ $config_apply .= "\t\t{\n" .
"\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n" .
"\t\t\treturn -1;\n" .
"\t\t}\n" .
"\t\treturn 0;\n" .
"\t}\n\n";
-}
-sub write_c_impl_free(@)
-{
- my @output = @_;
- my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
+ $config_free .= "\thub_free(config->" . $name . ");\n\n" if ($string);
- if ($type =~ /(string|file|message)/)
- {
- print GENIMPL "\thub_free(config->" . $name . ");\n\n"
- }
-}
-sub write_c_impl_dump(@)
-{
- my @output = @_;
- my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
- my $out;
+ my $out = "%s";
my $val = "config->$name";
my $test = "config->$name != $default";
- if ($type eq "int")
- {
- $out = "%d";
- }
- elsif ($type eq "boolean")
- {
- $out = "%s";
- $val = "config->$name ? \"yes\" : \"no\"";
- }
- elsif ($type =~ /(string|file|message)/)
+ $out = "%d" if ($type eq "int");
+ $val = "config->$name ? \"yes\" : \"no\"" if ($type eq "boolean");
+
+ if ($string)
{
$out = "\\\"%s\\\"";
$test = "strcmp(config->$name, \"$default\") != 0";
}
- print GENIMPL "\tif (!ignore_defaults || $test)\n";
- print GENIMPL "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
+ $config_dump .= "\tif (!ignore_defaults || $test)\n";
+ $config_dump .= "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
}
+$config_apply .= "\t/* Still here -- unknown directive */\n";
+$config_apply .= "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n";
+$config_apply .= "\treturn -1;\n";
+$config_apply .= "}\n\n";
+$config_defaults .= "}\n\n";
+$config_free .= "}\n\n";
+$config_dump .= "}\n\n";
+
+open GENIMPL, ">gen_config.c" || die "Unable to write source file";
+print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
+print GENIMPL $config_defaults;
+print GENIMPL $config_apply;
+print GENIMPL $config_free;
+print GENIMPL $config_dump;
+
+
sub get_data($)
{
my $p = shift;
- my $check = $p->first_child_matches("check");
- 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"), $check);
+
+ my $short = "";
+ my $example = "";
+ my $description = "";
+ my $since = "";
+
+ $short = $p->getElementsByTagName("short")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("short")->getLength());
+ $since = $p->getElementsByTagName("since")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("since")->getLength());
+ $example = $p->getElementsByTagName("example")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("example")->getLength());
+ $description = $p->getElementsByTagName("description")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("description")->getLength());
+ my $check = $p->getElementsByTagName("check")->item(0);
+
+ my @data = (
+ $p->getAttribute("type"),
+ $p->getAttribute("name"),
+ $p->getAttribute("default"),
+ $p->getAttribute("advanced"),
+ $short,
+ $description,
+ $since,
+ $example,
+ $check
+ );
return @data;
}
+# Write header file
+sub write_c_header(@)
+{
+ my @data = @_;
+
+ open GENHEAD, ">gen_config.h" || die "Unable to write header file";
+ print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
+ print GENHEAD "struct hub_config\n{\n";
+
+ foreach my $option (@data)
+ {
+ my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @$option;
+
+ my $string = ($type =~ /(string|file|message)/);
+
+ print GENHEAD "\t";
+ print GENHEAD "int " if ($type eq "int");
+ print GENHEAD "int " if ($type eq "boolean");
+ print GENHEAD "char*" if ($string);
+ print GENHEAD " " . $name . ";";
+
+ my $comment = "";
+ if ($type eq "message")
+ {
+ $comment = "\"" . $default . "\"";
+ }
+ elsif (defined $short && length $short > 0)
+ {
+ $comment = $short;
+ if (defined $default)
+ {
+ $comment .= " (default: ";
+ $comment .= "\"" if ($string);
+ $comment .= $default;
+ $comment .= "\"" if ($string);
+ $comment .= ")";
+ }
+ }
+
+ if (length $comment > 0)
+ {
+ my $pad = "";
+ for (my $i = length $name; $i < 32; $i++)
+ {
+ $pad .= " ";
+ }
+ $comment = $pad . "/*<<< " . $comment . " */";
+ }
+ print GENHEAD $comment . "\n";
+ }
+
+ print GENHEAD "};\n\n";
+}
+
+
+sub write_sql_dump(@)
+{
+ my @data = @_;
+
+ # Write SQL dump code
+ open GENSQL, ">gen_config.sql" || die "Unable to write SQL dump";
+ print GENSQL "START TRANSACTION;\n\n
+ DROP TABLE uhub_config IF EXISTS;\n\n
+ CREATE TABLE uhub_config (
+ name VARCHAR(32) UNIQUE NOT NULL,
+ defaultValue TINYTEXT NOT NULL,
+ description LONGTEXT NOT NULL,
+ type TINYTEXT NOT NULL,
+ advanced BOOLEAN,
+ example LONGTEXT,
+ since TINYTEXT
+ );\n\n";
+
+ foreach my $option (@data)
+ {
+ my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @$option;
+
+ if ($type =~ /(string|file|message)/ )
+ {
+ $default = "\\\"$default\\\"";
+ }
+
+ $desc =~ s/\"/\\\"/g;
+ $type =~ s/^int$/integer/;
+
+ my $stmt = "INSERT INTO uhub_config VALUES(";
+ $stmt .= "\"$name\", ";
+ $stmt .= "\"$default\", ";
+ $stmt .= "\"$desc\", ";
+ $stmt .= "\"$type\", ";
+
+ if (defined $example)
+ {
+ my $example_str = $example;
+ $example_str =~ s/\\/\\\\/g;
+ $example_str =~ s/\"/\\\"/g;
+ $stmt .= "\"$example_str\", ";
+ } else {
+ $stmt .= "NULL, ";
+ }
+
+ if (defined $since) {
+ $stmt .= "\"$since\", ";
+ } else {
+ $stmt .= "NULL, ";
+ }
+
+ if (defined $advanced) {
+ $stmt .= "\"$advanced\"";
+ } else {
+ $stmt .= "NULL";
+ }
+
+ $stmt .= ");\n";
+
+ print GENSQL $stmt;
+ }
+ print GENSQL "\n\nCOMMIT;\n\n";
+}
diff --git a/src/core/config.xml b/src/core/config.xml
index 40e4932..b5e949d 100644
--- a/src/core/config.xml
+++ b/src/core/config.xml
@@ -13,7 +13,7 @@
0.1.0
Server port to bind to
-
+