#!/usr/local/bin/perl -w # -*- perl -*- ###################################################################### # placeableitems2resrefs.pl -- Change items in placeables to resrefs # Copyright (c) 2007 Tero Kivinen # All Rights Reserved. ###################################################################### # Program: placeableitems2resrefs.pl # $Source: /u/samba/nwn/bin/RCS/placeableitems2resrefs.pl,v $ # Author : $Author: kivinen $ # # (C) Tero Kivinen 2007 # # Creation : 16:52 Nov 19 2007 kivinen # Last Modification : 17:37 Nov 19 2007 kivinen # Last check in : $Date: 2008/01/06 19:49:43 $ # Revision number : $Revision: 1.1 $ # State : $State: Exp $ # Version : 1.43 # Edit time : 31 min # # Description : Change items in placeables with tag # matching given regexp to comma separated # list of resrefs stored on placeable. # # $Log: placeableitems2resrefs.pl,v $ # Revision 1.1 2008/01/06 19:49:43 kivinen # Created. # # $EndLog$ # # # # ###################################################################### # initialization require 5.6.0; package PlaceableItems2ResRefs; use strict; use Getopt::Long; use File::Glob ':glob'; use Gff; use GffRead; use GffWrite; use Pod::Usage; ###################################################################### # Get version information open(PROGRAM, "<$0") || die "Cannot open myself from $0 : $!"; undef $/; $Prog::program = ; $/ = "\n"; close(PROGRAM); if ($Prog::program =~ /\$revision:\s*([\d.]*)\s*\$/i) { $Prog::revision = $1; } else { $Prog::revision = "?.?"; } if ($Prog::program =~ /version\s*:\s*([\d.]*\.)*([\d]*)\s/mi) { $Prog::save_version = $2; } else { $Prog::save_version = "??"; } if ($Prog::program =~ /edit\s*time\s*:\s*([\d]*)\s*min\s*$/mi) { $Prog::edit_time = $1; } else { $Prog::edit_time = "??"; } $Prog::version = "$Prog::revision.$Prog::save_version.$Prog::edit_time"; $Prog::progname = $0; $Prog::progname =~ s/^.*\///g; $| = 1; $Opt::verbose = 0; $Opt::variable = 'Fill'; $Opt::tag_regexp = '^shop_'; $Opt::no_write = 0; ###################################################################### # Read rc-file if (defined($ENV{'HOME'})) { read_rc_file("$ENV{'HOME'}/.placeableitems2resrefsrc"); } ###################################################################### # Option handling Getopt::Long::Configure("no_ignore_case"); if (!GetOptions("config=s" => \$Opt::config, "verbose|v+" => \$Opt::verbose, "help|h" => \$Opt::help, "tag|t=s" => \$Opt::tag_regexp, "variable=s" => \$Opt::variable, "no-write|n" => \$Opt::no_write, "version|V" => \$Opt::version) || defined($Opt::help)) { usage(); } if (defined($Opt::version)) { print("\u$Prog::progname version " . "$Prog::version by Tero Kivinen.\n"); exit(0); } while (defined($Opt::config)) { my($tmp); $tmp = $Opt::config; undef $Opt::config; if (-f $tmp) { read_rc_file($tmp); } else { die "Config file $Opt::config not found: $!"; } } ###################################################################### # Main loop $| = 1; my($i, $j, $k, $l, $name, $next, $file); if (join(";", @ARGV) =~ /[*?]/) { my(@argv); foreach $i (@ARGV) { push(@argv, bsd_glob($i)); } @ARGV = @argv; } foreach $i (@ARGV) { my($gff, %levels, $classstr, $cls, $lvl); if ($Opt::verbose) { print("Reading file $i...\n"); } $PlaceableItems2ResRefs::file = $i; $gff = GffRead::read(filename => $i); if ($Opt::verbose) { printf("Read done\n"); } $PlaceableItems2ResRefs::modified = 0; $gff->find(find_label => '/Placeable List\[\d+\]/$', #' proc => \&check_placeable); if ($PlaceableItems2ResRefs::modified && !$Opt::no_write) { if ($Opt::verbose) { print("Writing file $i...\n"); } $gff->GffWrite::write(filename => $i); if ($Opt::verbose) { printf("Write done\n"); } } } exit 0; ###################################################################### # check_placeable sub check_placeable { my($gff, $full_label, $label, $value, $parent_gffs) = @_; if ($$gff{'Tag'} =~ /$Opt::tag_regexp/) { my($value); printf("Found placeable %s:%s (%s)\n", $PlaceableItems2ResRefs::file, $$gff{Tag}, $$gff{LocName}{0}) if ($Opt::verbose > 1); @PlaceableItems2ResRefs::items = (); $gff->find(find_label => '/ItemList\[\d+\]/$', # ' proc => \&find_items); $value = join(',', @PlaceableItems2ResRefs::items); if ($value ne '') { if (defined($gff->variable($Opt::variable))) { $value = $gff->variable($Opt::variable)->varvalue . "," . $value; } printf("Final variable %s = %s\n", $Opt::variable, $value) if ($Opt::verbose > 1); $gff->variable($Opt::variable, $value); delete $$gff{ItemList}; $PlaceableItems2ResRefs::modified = 1; } } } ###################################################################### # check_placeable sub find_items { my($gff, $full_label, $label, $value, $parent_gffs) = @_; printf("Found item tag = %s, resref = %s\n", $$gff{Tag}, $$gff{TemplateResRef}) if ($Opt::verbose > 2); if ($$gff{Tag} ne $$gff{TemplateResRef}) { warn "Item $$gff{Tag} in $$gff{''} does have different tag " . "than resref $$gff{TemplateResRef}"; } push(@PlaceableItems2ResRefs::items, $$gff{TemplateResRef}); } ###################################################################### # Read rc file sub read_rc_file { my($file) = @_; my($next, $space); if (open(RCFILE, "<$file")) { while () { chomp; while (/\\$/) { $space = 0; if (/\s+\\$/) { $space = 1; } s/\s*\\$//g; $next = ; chomp $next; if ($next =~ s/^\s+//g) { $space = 1; } if ($space) { $_ .= " " . $next; } else { $_ .= $next; } } if (/^\s*([a-zA-Z0-9_]+)\s*$/) { eval('$Opt::' . lc($1) . ' = 1;'); } elsif (/^\s*([a-zA-Z0-9_]+)\s*=\s*\"([^\"]*)\"\s*$/) { my($key, $value) = ($1, $2); $value =~ s/\\n/\n/g; $value =~ s/\\t/\t/g; eval('$Opt::' . lc($key) . ' = $value;'); } elsif (/^\s*([a-zA-Z0-9_]+)\s*=\s*(.*)\s*$/) { my($key, $value) = ($1, $2); $value =~ s/\\n/\n/g; $value =~ s/\\t/\t/g; eval('$Opt::' . lc($key) . ' = $value;'); } } close(RCFILE); } } ###################################################################### # Usage sub usage { Pod::Usage::pod2usage(0); } =head1 NAME placeableitems2resrefsrc - Change items in placeables to resrefs =head1 SYNOPSIS placeableitems2resrefsrc [B<--help>|B<-h>] [B<--version>|B<-V>] [B<--verbose>|B<-v>] [B<--config> I] [B<--no-write>|B<-n>] [B<--tag>|B<-t> I] [B<--variable> I] I ... placeableitems2resrefsrc B<--help> =head1 DESCRIPTION B changes items in placeables with tag matching given regexp to comma separated list of resrefs stored on placeable as given variable. =head1 OPTIONS =over 4 =item B<--help> B<-h> Prints out the usage information. =item B<--version> B<-V> Prints out the version information. =item B<--verbose> B<-v> Enables the verbose prints. This option can be given multiple times, and each time it enables more verbose prints. =item B<--config> I All options given by the command line can also be given in the configuration file. This option is used to read another configuration file in addition to the default configuration file. =item B<--no-write> B<-n> Do not write anything, but do the modifications etc. This can be used to check that everything is modified properly before actually doing the modification. =item B<--tag> B<-t> I Process only placeables having given tag. =item B<--variable> I Store comma separated list of resrefs to variable name given here. =back =head1 EXAMPLES placeableitems2resrefsrc.pl *.git =head1 FILES =over 6 =item ~/.placeableitems2resrefsrc Default configuration file. =back =head1 SEE ALSO gffmodify(1), gffprint(1), Gff(3), GffWrite(3), and GffRead(3). =head1 AUTHOR Tero Kivinen . =head1 HISTORY This program evolved when we needed to convert shops made before to use resref variable system instead, so the items in the shops would be corrected automatically with the latest blueprint.