1#!/usr/bin/env perl 2 3#This script replaces MRW attribute names with their values from the 4#MRW XML in any file. In addition, it can evaluate mathematical 5#expressions if they are in [[ ]]s and can use variables passed in from 6#the command line in those expressions. 7# 8#For example, if the attribute FOO has a value of 50 in the MRW, and 9#the program was started with: -v "MY_VAR1=200 MY_VAR2=400" 10# 11#then the line 12# [[(MRW_FOO * MY_VAR1) + 5]]..[[MRW_FOO * MY_VAR2]] 13# 14#would get written out as: 15# 10005..20000 16# 17 18use strict; 19use warnings; 20 21use mrw::Targets; # Set of APIs allowing access to parsed ServerWiz2 XML output 22use Getopt::Long; # For parsing command line arguments 23 24# Globals 25my $force = 0; 26my $serverwizFile = ""; 27my $debug = 0; 28my $outputFile = ""; 29my $settingsFile = ""; 30my $expressionVars = ""; 31my %exprVars; 32 33# Command line argument parsing 34GetOptions( 35"f" => \$force, # numeric 36"i=s" => \$serverwizFile, # string 37"o=s" => \$outputFile, # string 38"s=s" => \$settingsFile, # string 39"v=s" => \$expressionVars, # string 40"d" => \$debug, 41) 42or printUsage(); 43 44if (($serverwizFile eq "") or ($outputFile eq "") or ($settingsFile eq "") ) 45{ 46 printUsage(); 47} 48 49# API used to access parsed XML data 50my $targetObj = Targets->new; 51if($debug == 1) 52{ 53 $targetObj->{debug} = 1; 54} 55 56if($force == 1) 57{ 58 $targetObj->{force} = 1; 59} 60 61$targetObj->loadXML($serverwizFile); 62print "Loaded MRW XML: $serverwizFile \n"; 63 64open(my $inFh, '<', $settingsFile) or die "Could not open file '$settingsFile' $!"; 65open(my $outFh, '>', $outputFile) or die "Could not open file '$outputFile' $!"; 66 67if (length($expressionVars) > 0) 68{ 69 loadVars($expressionVars); 70} 71 72# Process all the targets in the XML 73foreach my $target (sort keys %{$targetObj->getAllTargets()}) 74{ 75 # A future improvement could be to specify the MRW target. 76 next if ("SYS" ne $targetObj->getType($target, "TYPE")); 77 # Read the settings YAML replacing any MRW_<variable name> with their 78 # MRW value 79 while (my $row = <$inFh>) 80 { 81 while ($row =~ /MRW_(.*?)\W/g) 82 { 83 my $setting = $1; 84 my $settingValue = $targetObj->getAttribute($target, $setting); 85 $row =~ s/MRW_${setting}/$settingValue/g; 86 } 87 88 #If there are [[ ]] expressions, evaluate them and replace the 89 #[[expression]] with the value 90 while ($row =~ /\[\[(.*?)\]\]/) 91 { 92 my $expr = $1; 93 my $value = evaluate($expr); 94 95 #Break the row apart, remove the [[ ]]s, and put the 96 #value in the middle when putting back together. 97 my $exprStart = index($row, $expr); 98 my $front = substr($row, 0, $exprStart - 2); 99 my $back = substr($row, $exprStart + length($expr) + 2); 100 101 $row = $front . $value . $back; 102 } 103 104 print $outFh $row; 105 } 106 last; 107 close $inFh; 108 close $outFh; 109} 110 111#Evaluate the expression passed in. Substitute any variables with 112#their values passed in on the command line. 113sub evaluate 114{ 115 my $expr = shift; 116 117 #Put in the value for the variable. 118 for my $var (keys %exprVars) 119 { 120 $expr =~ s/$var/$exprVars{$var}/; 121 } 122 123 my $value = eval($expr); 124 if (not defined $value) 125 { 126 die "Invalid expression found: $expr\n"; 127 } 128 129 #round it to an integer 130 $value = sprintf("%.0f", $value); 131 return $value; 132} 133 134#Parse the variable=value string passed in from the 135#command line and load it into %exprVars. 136sub loadVars 137{ 138 my $varString = shift; 139 140 #Example: "VAR1=VALUE1 VAR2=VALUE2" 141 my @entries = split(' ', $varString); 142 143 for my $entry (@entries) 144 { 145 my ($var, $value) = $entry =~ /(.+)=(.+)/; 146 147 if ((not defined $var) || (not defined $value)) 148 { 149 die "Could not parse expression variable string $varString\n"; 150 } 151 152 $exprVars{$var} = $value; 153 } 154} 155 156# Usage 157sub printUsage 158{ 159 print " 160 $0 -i [XML filename] -s [Settings YAML] -o [Output filename] -v [expr vars] [OPTIONS] 161 162Required: 163 -i = MRW XML filename 164 -s = The Setting YAML with MRW variables in MRW_<MRW variable name> format 165 -o = YAML output filename 166Optional: 167 -v = Variables and values for any [[expression]] evaluation 168 in the form: \"VAR1=VALUE1 VAR2=VALUE2\" 169Options: 170 -f = force output file creation even when errors 171 -d = debug mode 172 \n"; 173 exit(1); 174} 175