|
|
55a0e2 |
#!/usr/bin/perl
|
|
|
55a0e2 |
|
|
|
55a0e2 |
# converts the <rules>.xml file to the old format <rules>.lst file
|
|
|
55a0e2 |
#
|
|
|
55a0e2 |
# Usage:
|
|
|
55a0e2 |
#
|
|
|
55a0e2 |
# perl xml2lst.pl < filename.xml > filename.lst
|
|
|
55a0e2 |
#
|
|
|
55a0e2 |
# author Ivan Pascal
|
|
|
55a0e2 |
# modified by Vitezslav Crhonek
|
|
|
55a0e2 |
|
|
|
55a0e2 |
$doc = new_document( 0, '');
|
|
|
55a0e2 |
parse('', $doc);
|
|
|
55a0e2 |
|
|
|
55a0e2 |
($reg) = node_by_name($doc, '/xkbConfigRegistry');
|
|
|
55a0e2 |
@models = node_by_name($reg, 'modelList/model/configItem');
|
|
|
55a0e2 |
@layouts = node_by_name($reg, 'layoutList/layout/configItem');
|
|
|
55a0e2 |
@options = node_by_name($reg, 'optionList/group/configItem');
|
|
|
55a0e2 |
|
|
|
55a0e2 |
for $i (@layouts) {
|
|
|
55a0e2 |
($name) = node_by_name($i, 'name');
|
|
|
55a0e2 |
@variants = node_by_name($i, '../variantList/variant/configItem');
|
|
|
55a0e2 |
for $v (@variants) {
|
|
|
55a0e2 |
($variant) = node_by_name($v, 'name');
|
|
|
55a0e2 |
printf("%s %s\n", text_child($name), text_child($variant));
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub with_attribute {
|
|
|
55a0e2 |
local ($nodelist, $attrexpr) = @_;
|
|
|
55a0e2 |
local ($attr, $value) = split (/=/, $attrexpr);
|
|
|
55a0e2 |
local ($node, $attrvalue);
|
|
|
55a0e2 |
if (defined $value && $value ne '') {
|
|
|
55a0e2 |
$value =~ s/"//g;
|
|
|
55a0e2 |
foreach $node (@{$nodelist}) {
|
|
|
55a0e2 |
$attrvalue = node_attribute($node, $attr);
|
|
|
55a0e2 |
if (defined $attrvalue && $attrvalue eq $value) {
|
|
|
55a0e2 |
return $node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
foreach $node (@{$nodelist}) {
|
|
|
55a0e2 |
if (! defined node_attribute($node, $attr)) {
|
|
|
55a0e2 |
return $node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
undef;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
# Subroutines
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub parse {
|
|
|
55a0e2 |
local $intag = 0;
|
|
|
55a0e2 |
my (@node_stack, $parent);
|
|
|
55a0e2 |
$parent = @_[1];
|
|
|
55a0e2 |
local ($tag, $text);
|
|
|
55a0e2 |
|
|
|
55a0e2 |
while (<>) {
|
|
|
55a0e2 |
chomp;
|
|
|
55a0e2 |
@str = split /([<>])/;
|
|
|
55a0e2 |
shift @str if ($str[0] eq '' || $str[0] =~ /^[ \t]*$/);
|
|
|
55a0e2 |
|
|
|
55a0e2 |
while (scalar @str) {
|
|
|
55a0e2 |
$token = shift @str;
|
|
|
55a0e2 |
if ($token eq '<') {
|
|
|
55a0e2 |
$intag = 1;
|
|
|
55a0e2 |
if (defined $text) {
|
|
|
55a0e2 |
add_text_node($parent, $text);
|
|
|
55a0e2 |
undef $text;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
} elsif ($token eq '>') {
|
|
|
55a0e2 |
$intag = 0;
|
|
|
55a0e2 |
if ($tag =~ /^\/(.*)/) { # close tag
|
|
|
55a0e2 |
$parent = pop @node_stack;
|
|
|
55a0e2 |
} elsif ($tag =~ /^([^\/]*)\/$/) {
|
|
|
55a0e2 |
empty_tag($parent, $1);
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
if (defined ($node = open_tag($parent, $tag))) {
|
|
|
55a0e2 |
push @node_stack, $parent;
|
|
|
55a0e2 |
$parent = $node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
undef $tag;
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
if ($intag == 1) {
|
|
|
55a0e2 |
if (defined $tag) {
|
|
|
55a0e2 |
$tag .= ' '. $token;
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
$tag = $token;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
if (defined $text) {
|
|
|
55a0e2 |
$text .= "\n" . $token;
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
$text = $token;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub new_document {
|
|
|
55a0e2 |
$doc = new_node( 0, '', 'DOCUMENT');
|
|
|
55a0e2 |
$doc->{CHILDREN} = [];
|
|
|
55a0e2 |
return $doc;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub new_node {
|
|
|
55a0e2 |
local ($parent_node, $tag, $type) = @_;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
my %node;
|
|
|
55a0e2 |
$node{PARENT} = $parent_node;
|
|
|
55a0e2 |
$node{TYPE} = $type;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if ($type eq 'COMMENT' || $type eq 'TEXT') {
|
|
|
55a0e2 |
$node{TEXT} = $tag;
|
|
|
55a0e2 |
$node{NAME} = $type;
|
|
|
55a0e2 |
return \%node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
local ($tname, $attr) = split(' ', $tag, 2);
|
|
|
55a0e2 |
$node{NAME} = $tname;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if (defined $attr && $attr ne '') {
|
|
|
55a0e2 |
my %attr_table;
|
|
|
55a0e2 |
local @attr_list = split ( /"/, $attr);
|
|
|
55a0e2 |
local ($name, $value);
|
|
|
55a0e2 |
while (scalar @attr_list) {
|
|
|
55a0e2 |
$name = shift @attr_list;
|
|
|
55a0e2 |
$name =~ s/[ =]//g;
|
|
|
55a0e2 |
next if ($name eq '');
|
|
|
55a0e2 |
$value = shift @attr_list;
|
|
|
55a0e2 |
$attr_table{$name} =$value;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
$node{ATTRIBUTES} = \%attr_table;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
return \%node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub add_node {
|
|
|
55a0e2 |
local ($parent_node, $node) = @_;
|
|
|
55a0e2 |
push @{$parent_node->{CHILDREN}}, $node;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
local $tname = $node->{NAME};
|
|
|
55a0e2 |
if (defined $parent_node->{$tname}) {
|
|
|
55a0e2 |
push @{$parent_node->{$tname}}, $node
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
$parent_node->{$tname} = [ $node ];
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub empty_tag {
|
|
|
55a0e2 |
local ($parent_node, $tag) = @_;
|
|
|
55a0e2 |
local $node = new_node($parent_node, $tag, 'EMPTY');
|
|
|
55a0e2 |
add_node($parent_node, $node);
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub open_tag {
|
|
|
55a0e2 |
local ($parent_node, $tag) = @_;
|
|
|
55a0e2 |
local $node;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if ($tag =~ /^\?.*/ || $tag =~ /^\!.*/) {
|
|
|
55a0e2 |
$node = new_node($parent_node, $tag, 'COMMENT');
|
|
|
55a0e2 |
add_node($parent_node, $node);
|
|
|
55a0e2 |
undef; return;
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
$node = new_node($parent_node, $tag, 'NODE');
|
|
|
55a0e2 |
$node->{CHILDREN} = [];
|
|
|
55a0e2 |
add_node($parent_node, $node);
|
|
|
55a0e2 |
return $node;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub add_text_node {
|
|
|
55a0e2 |
local ($parent_node, $text) = @_;
|
|
|
55a0e2 |
local $node = new_node($parent_node, $text, 'TEXT');
|
|
|
55a0e2 |
add_node($parent_node, $node);
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub node_by_name {
|
|
|
55a0e2 |
local ($node, $name) = @_;
|
|
|
55a0e2 |
local ($tagname, $path) = split(/\//, $name, 2);
|
|
|
55a0e2 |
|
|
|
55a0e2 |
my @nodelist;
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if ($tagname eq '') {
|
|
|
55a0e2 |
while ($node->{PARENT} != 0) {
|
|
|
55a0e2 |
$node = $node->{PARENT};
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
sublist_by_name($node, $path, \@nodelist);
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
sublist_by_name($node, $name, \@nodelist);
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
return @nodelist;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub sublist_by_name {
|
|
|
55a0e2 |
local ($node, $name, $res) = @_;
|
|
|
55a0e2 |
local ($tagname, $path) = split(/\//, $name, 2);
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if (! defined $path) {
|
|
|
55a0e2 |
push @{$res}, (@{$node->{$tagname}});
|
|
|
55a0e2 |
return;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
if ($tagname eq '..' && $node->{PARENT} != 0) {
|
|
|
55a0e2 |
$node = $node->{PARENT};
|
|
|
55a0e2 |
sublist_by_name($node, $path, $res);
|
|
|
55a0e2 |
} else {
|
|
|
55a0e2 |
local $n;
|
|
|
55a0e2 |
for $n (@{$node->{$tagname}}) {
|
|
|
55a0e2 |
sublist_by_name($n, $path, $res);
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub node_attribute {
|
|
|
55a0e2 |
local $node = @_[0];
|
|
|
55a0e2 |
if (defined $node->{ATTRIBUTES}) {
|
|
|
55a0e2 |
return $node->{ATTRIBUTES}{@_[1]};
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
undef;
|
|
|
55a0e2 |
}
|
|
|
55a0e2 |
|
|
|
55a0e2 |
sub text_child {
|
|
|
55a0e2 |
local ($node) = @_;
|
|
|
55a0e2 |
local ($child) = node_by_name($node, 'TEXT');
|
|
|
55a0e2 |
return $child->{TEXT};
|
|
|
55a0e2 |
}
|