Rewrote the configuration file parser generator.
Converted from Perl to Python for a better and cleaner object oriented design.
This commit is contained in:
parent
22292e493e
commit
cf9be754aa
|
@ -1,289 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use XML::DOM;
|
|
||||||
|
|
||||||
sub write_c_header(@);
|
|
||||||
sub write_sql_dump(@);
|
|
||||||
sub get_data($);
|
|
||||||
|
|
||||||
my $dump_to_sql = 0;
|
|
||||||
|
|
||||||
# initialize parser and read the file
|
|
||||||
my $input = "./config.xml";
|
|
||||||
my $parser = new XML::DOM::Parser;
|
|
||||||
my $tree = $parser->parsefile($input) || die "Unable to parse XML file.";
|
|
||||||
|
|
||||||
# Get data
|
|
||||||
my $nodes = $tree->getElementsByTagName("option");
|
|
||||||
my @options = ();
|
|
||||||
for (my $i = 0; $i < $nodes->getLength; $i++)
|
|
||||||
{
|
|
||||||
my @data = get_data($nodes->item($i));
|
|
||||||
push @options, \@data;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_c_header(@options);
|
|
||||||
write_sql_dump(@options) if ($dump_to_sql);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
|
||||||
my $min = undef;
|
|
||||||
my $max = undef;
|
|
||||||
my $regexp = undef;
|
|
||||||
|
|
||||||
if (defined $check)
|
|
||||||
{
|
|
||||||
$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 "");
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_defaults .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_defaults .= "\tconfig->$name = ";
|
|
||||||
$config_defaults .= "hub_strdup(\"" if ($string);
|
|
||||||
$config_defaults .= $default;
|
|
||||||
$config_defaults .= "\")" if ($string);
|
|
||||||
$config_defaults .= ";\n";
|
|
||||||
$config_defaults .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
|
|
||||||
$config_apply .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_apply .= "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
|
|
||||||
|
|
||||||
if ($type eq "int")
|
|
||||||
{
|
|
||||||
$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")
|
|
||||||
{
|
|
||||||
$config_apply .= "\t\tif (!apply_boolean(key, data, &config->$name))\n";
|
|
||||||
}
|
|
||||||
elsif ($string)
|
|
||||||
{
|
|
||||||
$config_apply .="\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\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";
|
|
||||||
$config_apply .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
$config_apply .= "\n";
|
|
||||||
|
|
||||||
if ($string)
|
|
||||||
{
|
|
||||||
$config_free .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_free .= "\thub_free(config->" . $name . ");\n";
|
|
||||||
$config_free .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
$config_free .= "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $out = "%s";
|
|
||||||
my $val = "config->$name";
|
|
||||||
my $test = "config->$name != $default";
|
|
||||||
|
|
||||||
$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";
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_dump .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_dump .= "\tif (!ignore_defaults || $test)\n";
|
|
||||||
$config_dump .= "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n";
|
|
||||||
$config_dump .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
$config_dump .= "\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 $short = "";
|
|
||||||
my $example = "";
|
|
||||||
my $description = "";
|
|
||||||
my $since = "";
|
|
||||||
my $ifdef = "";
|
|
||||||
|
|
||||||
$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);
|
|
||||||
$ifdef = $p->getElementsByTagName("ifdef")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("ifdef")->getLength());
|
|
||||||
|
|
||||||
my @data = (
|
|
||||||
$p->getAttribute("type"),
|
|
||||||
$p->getAttribute("name"),
|
|
||||||
$p->getAttribute("default"),
|
|
||||||
$p->getAttribute("advanced"),
|
|
||||||
$short,
|
|
||||||
$description,
|
|
||||||
$since,
|
|
||||||
$example,
|
|
||||||
$check,
|
|
||||||
$ifdef
|
|
||||||
);
|
|
||||||
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, $check, $ifdef) = @$option;
|
|
||||||
|
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
|
||||||
|
|
||||||
print GENHEAD "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
|
|
||||||
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 "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
}
|
|
||||||
|
|
||||||
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, $check, $ifdef) = @$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";
|
|
||||||
}
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
uhub - A tiny ADC p2p connection hub
|
||||||
|
Copyright (C) 2007-2013, Jan Vidar Krey
|
||||||
|
"""
|
||||||
|
|
||||||
|
from xml.dom import minidom, Node
|
||||||
|
from datetime import datetime
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
class OptionParseError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Option(object):
|
||||||
|
def _get(self, node, name):
|
||||||
|
self.__dict__[name] = None
|
||||||
|
if (node.getElementsByTagName(name)):
|
||||||
|
self.__dict__[name] = node.getElementsByTagName(name)[0].firstChild.nodeValue
|
||||||
|
|
||||||
|
def _attr(self, node, name, required = False):
|
||||||
|
try:
|
||||||
|
return node.attributes[name].value
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
if (required):
|
||||||
|
raise OptionParseError("Option %s is required but not found!" % name)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __init__(self, node):
|
||||||
|
self.otype = self._attr(node, 'type', True)
|
||||||
|
|
||||||
|
# Verify that the type is known
|
||||||
|
if not self.otype in ["int", "boolean", "string", "message", "file"]:
|
||||||
|
raise OptionParseError("Option %s has unknown type" % self.name)
|
||||||
|
|
||||||
|
self.name = self._attr(node, 'name', True)
|
||||||
|
self.default = self._attr(node, 'default', True)
|
||||||
|
self.advanced = self._attr(node, 'advanced', False)
|
||||||
|
self.is_string = self.otype in ["string", "message", "file"]
|
||||||
|
|
||||||
|
self._get(node, "short");
|
||||||
|
self._get(node, "description");
|
||||||
|
self._get(node, "syntax");
|
||||||
|
self._get(node, "since");
|
||||||
|
self._get(node, "example");
|
||||||
|
|
||||||
|
check = node.getElementsByTagName("check")
|
||||||
|
if (check):
|
||||||
|
check = node.getElementsByTagName("check")[0]
|
||||||
|
self.check_min = self._attr(check, 'min', False)
|
||||||
|
self.check_max = self._attr(check, 'max', False)
|
||||||
|
self.check_regexp = self._attr(check, 'regexp', False)
|
||||||
|
else:
|
||||||
|
self.check_min = None
|
||||||
|
self.check_max = None
|
||||||
|
self.check_regexp = None
|
||||||
|
|
||||||
|
|
||||||
|
def c_type(self):
|
||||||
|
if self.otype == "boolean":
|
||||||
|
return "int"
|
||||||
|
elif self.is_string:
|
||||||
|
return "char*"
|
||||||
|
else:
|
||||||
|
return self.otype
|
||||||
|
|
||||||
|
def sql_type(self):
|
||||||
|
if self.otype == "int":
|
||||||
|
return "integer"
|
||||||
|
return self.otype
|
||||||
|
|
||||||
|
def c_comment(self):
|
||||||
|
comment = ""
|
||||||
|
if (self.otype == "message"):
|
||||||
|
comment = self.formatted_default()
|
||||||
|
elif len(self.short):
|
||||||
|
comment = "%s (default: %s)" % (self.short, self.formatted_default())
|
||||||
|
return comment
|
||||||
|
|
||||||
|
def formatted_default(self):
|
||||||
|
if self.is_string:
|
||||||
|
return "\"%s\"" % self.default
|
||||||
|
return self.default
|
||||||
|
|
||||||
|
class SourceGenerator(object):
|
||||||
|
def __init__(self, filename, cppStyle = True):
|
||||||
|
print "Generating %s..." % filename
|
||||||
|
self.f = open(filename, 'w');
|
||||||
|
|
||||||
|
def write_header(self, Comment = True):
|
||||||
|
if Comment:
|
||||||
|
s = "/*\n * uhub - A tiny ADC p2p connection hub\n"
|
||||||
|
s += " * Copyright (C) 2007-%s, Jan Vidar Krey\n *\n" % datetime.now().strftime("%Y")
|
||||||
|
s += " * THIS FILE IS AUTOGENERATED - DO NOT MODIFY\n"
|
||||||
|
s += " * Created %s, by config.py\n */\n\n" % datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
class CHeaderGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename):
|
||||||
|
super(CHeaderGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _write_declaration(self, option):
|
||||||
|
comment = ' ' * (32 - len(option.name)) + "/*<<< %s */" % option.c_comment()
|
||||||
|
ptype = option.c_type() + (5 - len(option.c_type())) * ' '
|
||||||
|
self.f.write("\t%(type)s %(name)s;%(comment)s\n" % {
|
||||||
|
"type": ptype,
|
||||||
|
"name": option.name,
|
||||||
|
"comment": comment})
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header()
|
||||||
|
self.f.write("struct hub_config\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_declaration(option)
|
||||||
|
self.f.write("};\n\n")
|
||||||
|
|
||||||
|
class CSourceGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename):
|
||||||
|
super(CSourceGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _write_default_impl(self, option):
|
||||||
|
s = "\tconfig->%s = " % option.name
|
||||||
|
if option.is_string:
|
||||||
|
s += "hub_strdup(%s);\n" % option.formatted_default()
|
||||||
|
else:
|
||||||
|
s += option.formatted_default() + ";\n"
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def _write_apply_impl(self, option):
|
||||||
|
s = "\tif (!strcmp(key, \"%s\"))\n\t{\n" % option.name
|
||||||
|
if option.otype == "int":
|
||||||
|
s_min = "0"
|
||||||
|
s_max = "0"
|
||||||
|
if (option.check_min):
|
||||||
|
s += "\t\tmin = %s;\n" % option.check_min
|
||||||
|
s_min = "&min"
|
||||||
|
if (option.check_max):
|
||||||
|
s += "\t\tmax = %s;\n" % option.check_max
|
||||||
|
s_max = "&max"
|
||||||
|
s+= "\t\tif (!apply_integer(key, data, &config->%s, %s, %s))\n" % (option.name, s_min, s_max)
|
||||||
|
elif option.otype == "boolean":
|
||||||
|
s += "\t\tif (!apply_boolean(key, data, &config->%s))\n" % option.name
|
||||||
|
elif option.is_string:
|
||||||
|
s += "\t\tif (!apply_string(key, data, &config->%s, (char*) \"\"))\n" % option.name
|
||||||
|
s += "\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"
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def _write_free_impl(self, option):
|
||||||
|
if option.is_string:
|
||||||
|
self.f.write("\thub_free(config->%s);\n\n" % option.name)
|
||||||
|
|
||||||
|
def _write_dump_impl(self, option):
|
||||||
|
s = ""
|
||||||
|
fmt = "%s"
|
||||||
|
val = "config->%s" % option.name
|
||||||
|
test = "config->%s != %s" % (option.name, option.default)
|
||||||
|
|
||||||
|
if (option.otype == "int"):
|
||||||
|
fmt = "%d"
|
||||||
|
elif (option.otype == "boolean"):
|
||||||
|
val = "config->%s ? \"yes\" : \"no\"" % option.name
|
||||||
|
elif (option.is_string):
|
||||||
|
fmt = "\\\"%s\\\"";
|
||||||
|
test = "strcmp(config->%s, %s) != 0" % (option.name, option.formatted_default())
|
||||||
|
|
||||||
|
s += "\tif (!ignore_defaults || %s)\n" % test;
|
||||||
|
s += "\t\tfprintf(stdout, \"%s = %s\\n\", %s);\n\n" % (option.name, fmt, val)
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header()
|
||||||
|
self.f.write("void config_defaults(struct hub_config* config)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_default_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
self.f.write("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")
|
||||||
|
for option in options:
|
||||||
|
self._write_apply_impl(option)
|
||||||
|
self.f.write("\t/* Still here -- unknown directive */\n\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n\treturn -1;\n}\n\n")
|
||||||
|
self.f.write("void free_config(struct hub_config* config)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_free_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
self.f.write("void dump_config(struct hub_config* config, int ignore_defaults)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_dump_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
|
||||||
|
class SqlWebsiteDocsGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename, sqlite_support = False):
|
||||||
|
self.sqlite_support = sqlite_support
|
||||||
|
super(SqlWebsiteDocsGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _sql_escape(self, s):
|
||||||
|
if self.sqlite_support:
|
||||||
|
return s.replace("\"", "\"\"")
|
||||||
|
return s.replace("\"", "\\\"")
|
||||||
|
|
||||||
|
|
||||||
|
def _write_or_null(self, s):
|
||||||
|
if (not s or len(s) == 0):
|
||||||
|
return "NULL"
|
||||||
|
return "\"%s\"" % self._sql_escape(s)
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header(False)
|
||||||
|
table = "uhub_config"
|
||||||
|
|
||||||
|
s = ""
|
||||||
|
if not self.sqlite_support:
|
||||||
|
s += "START TRANSACTION;\n\nDROP TABLE %(table)s IF EXISTS;" % { "table": table }
|
||||||
|
s += "\n\nCREATE TABLE %(table)s (\n\tname VARCHAR(32) UNIQUE NOT NULL,\n\tdefaultValue TINYTEXT NOT NULL,\n\tdescription LONGTEXT NOT NULL,\n\ttype TINYTEXT NOT NULL,\n\tadvanced BOOLEAN,\n\texample LONGTEXT,\n\tsince TINYTEXT\n);\n\n" % { "table": table }
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
for option in options:
|
||||||
|
s = "INSERT INTO %(table)s VALUES(\"%(name)s\", \"%(default)s\", \"%(description)s\", \"%(type)s\", %(example)s, %(since)s, %(advanced)s);\n" % {
|
||||||
|
"table": table,
|
||||||
|
"name": self._sql_escape(option.name),
|
||||||
|
"default": self._sql_escape(option.formatted_default()),
|
||||||
|
"description": self._sql_escape(option.description),
|
||||||
|
"type": option.sql_type(),
|
||||||
|
"example": self._write_or_null(option.example),
|
||||||
|
"since": self._write_or_null(option.since),
|
||||||
|
"advanced": self._write_or_null(option.example),
|
||||||
|
}
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
if not self.sqlite_support:
|
||||||
|
self.f.write("\n\nCOMMIT;\n\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# parser = argparse.ArgumentParser(description = "Configuration file parser and source generator")
|
||||||
|
# parser.add_argument("--in", nargs=1, type=argparse.FileType('r'), default="config.xml", help="Input file (config.xml)", required = True)
|
||||||
|
# parser.add_argument("--c-decl", nargs=1, type=argparse.FileType('w'), default="gen_config.h", help="Output file for C declarations (gen_config.h)")
|
||||||
|
# parser.add_argument("--c-impl", nargs=1, type=argparse.FileType('w'), default="gen_config.c", help="Output file for C implementation (gen_config.c)")
|
||||||
|
# parser.add_argument("--doc-sql", nargs=1, type=argparse.FileType('w'), help="Output file for SQL documentation")
|
||||||
|
# args = parser.parse_args()
|
||||||
|
|
||||||
|
xmldoc = minidom.parse("./config.xml")
|
||||||
|
opt_tags = xmldoc.getElementsByTagName('option')
|
||||||
|
options = []
|
||||||
|
for option in opt_tags:
|
||||||
|
opt = Option(option)
|
||||||
|
options.append(opt)
|
||||||
|
|
||||||
|
header = CHeaderGenerator("./gen_config.h");
|
||||||
|
header.write(options);
|
||||||
|
|
||||||
|
source = CSourceGenerator("./gen_config.c");
|
||||||
|
source.write(options);
|
||||||
|
|
||||||
|
#sql = SqlWebsiteDocsGenerator("./gen_config.sql", True);
|
||||||
|
#sql.write(options);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2013, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
|
||||||
|
* Created 2013-04-22 21:57, by config.py
|
||||||
|
*/
|
||||||
|
|
||||||
void config_defaults(struct hub_config* config)
|
void config_defaults(struct hub_config* config)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2013, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
|
||||||
|
* Created 2013-04-22 21:57, by config.py
|
||||||
|
*/
|
||||||
|
|
||||||
struct hub_config
|
struct hub_config
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue