Blame xml2lst.pl

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