#!/opt/bin/perl # usage: res2pm open STDOUT, ">:utf8", "Crossfire/Data.pm" or die "Crossfire/Data.pm: $!"; print < for more info. =cut EOF use Data::Dumper; use XML::Parser::Grove; sub dump_hash { my ($name, $ref) = @_; require Data::Dumper; $d = new Data::Dumper ([$ref], ["*$name"]); $d->Terse (1); $d->Indent (1); $d->Quotekeys (0); $d->Useqq (1); $d->Sortkeys (sub { [sort { $a > 0 && $b > 0 ? $a <=> $b : $a cmp $b } keys %{+shift}] }); my $d = $d->Dump; $d =~ s/^ /\t\t/gm; $d =~ s/^ /\t/gm; $d =~ s/\s+$//; print "our %$name = $d;\n\n"; } my $type = XML::Parser->new (Style => 'grove')->parsefile ("res/types.xml"); my %bitmask; my %list; my %type; my $attr; my %ignore_list; my %default_attr; sub string($) { local $_ = join "", @{shift->contents}; $_ =~ s/^\s+//; $_ =~ s/\s+$//; $_ =~ s/\s+/ /g; $_ } sub parse_attr { my ($e, $sect) = @_; my $arch = { name => $e->attr ("editor"), type => $e->attr ("type"), desc => string $e, $e->attr("arch_begin") ? (end => $e->attr("arch_end")) : (), }; if ($arch->{type} =~ s/^(bitmask)_(.*)/$1/) { $arch->{values} = $BITMASK{$2} ||= {}; } $sect->{$e->attr ("arch") || $e->attr("arch_begin")} = $arch; } sub parse_type { my ($e, $type) = @_; for my $e (grep ref, @{$e->contents}) { if ($e->name eq "required") { for my $i (grep ref, @{$e->contents}) { $type->{required}{$i->attr ("arch")} = $i->attr ("value"); } } elsif ($e->name eq "attribute") { parse_attr $e, $type->{attr}{Main} ||= {}; } elsif ($e->name eq "ignore") { for my $i (grep ref, @{$e->contents}) { if ($i->name eq "ignore_list") { push @{$type->{ignore}}, $ignore_list{$i->attr ("name")} ||= []; } elsif ($i->name eq "attribute") { push @{$type->{ignore}}, $i->attr ("arch"); } } } elsif ($e->name eq "import_type") { push @{$type->{import}}, $xtype{$e->attr ("name")} ||= {}; } elsif ($e->name eq "use") { $type->{use} = string $e; } elsif ($e->name eq "description") { $type->{desc} = string $e; } elsif ($e->name eq "section") { for my $i (grep ref, @{$e->contents}) { parse_attr $i, $type->{attr}{$e->attr ("name")} ||= {}; } # $type->{desc} = string $e; } else { warn "unknown types subelement ", $e->name; } } $type } for my $e (grep ref, @{$type->root->contents}) { if ($e->name eq "bitmask") { my $bm = $bitmask{$e->attr ("name")} ||= {}; for my $b (grep ref, @{$e->contents}) { $bm->{$b->attr ("bit")} = $b->attr ("name"); } } elsif ($e->name eq "list") { my $list = $list{$e->attr ("name")} ||= {}; for my $b (grep ref, @{$e->contents}) { $list->{$b->attr ("value")} = $b->attr ("name"); } } elsif ($e->name eq "ignore_list") { my $list = $ignore_list{$e->attr ("name")} ||= []; for my $b (grep ref, @{$e->contents}) { push @$list, $b->attr ("arch"); } } elsif ($e->name eq "default_type") { parse_type $e, \%default_attr; } elsif ($e->name eq "type") { my $type = $attr{$e->attr ("name")} ||= {}; parse_type $e, $type; unshift @{$type->{import}}, \%default_attr; $type{$e->attr ("number")}{type}{$e->attr ("name")} = $type; } else { warn "unknown types element ", $e->name; } } my $type = XML::Parser->new (Style => 'grove')->parsefile ("res/typenumbers.xml"); for (grep ref, @{$type->root->contents}) { $type{$_->attr ("number")}{name} = $_->attr ("name"); } dump_hash "TYPE", \%type; my $spell = XML::Parser->new (Style => 'grove')->parsefile ("res/spells.xml") or die; my %spell; for (grep ref, @{$spell->root->contents}) { $spell{$_->attr ("id")} = $_->attr ("name"); } dump_hash "SPELL", \%spell; print < http://home.schmorp.de/ The source files are part of the CFJavaEditor. =cut 1 EOF