Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 1 | #!/usr/bin/env perl |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 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 | |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 18 | use strict; |
| 19 | use warnings; |
| 20 | |
| 21 | use mrw::Targets; # Set of APIs allowing access to parsed ServerWiz2 XML output |
| 22 | use Getopt::Long; # For parsing command line arguments |
| 23 | |
| 24 | # Globals |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 25 | my $force = 0; |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 26 | my $serverwizFile = ""; |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 27 | my $debug = 0; |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 28 | my $outputFile = ""; |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 29 | my $settingsFile = ""; |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 30 | my $expressionVars = ""; |
| 31 | my %exprVars; |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 32 | |
| 33 | # Command line argument parsing |
| 34 | GetOptions( |
| 35 | "f" => \$force, # numeric |
| 36 | "i=s" => \$serverwizFile, # string |
| 37 | "o=s" => \$outputFile, # string |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 38 | "s=s" => \$settingsFile, # string |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 39 | "v=s" => \$expressionVars, # string |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 40 | "d" => \$debug, |
| 41 | ) |
| 42 | or printUsage(); |
| 43 | |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 44 | if (($serverwizFile eq "") or ($outputFile eq "") or ($settingsFile eq "") ) |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 45 | { |
| 46 | printUsage(); |
| 47 | } |
| 48 | |
| 49 | # API used to access parsed XML data |
| 50 | my $targetObj = Targets->new; |
| 51 | if($debug == 1) |
| 52 | { |
| 53 | $targetObj->{debug} = 1; |
| 54 | } |
| 55 | |
| 56 | if($force == 1) |
| 57 | { |
| 58 | $targetObj->{force} = 1; |
| 59 | } |
| 60 | |
| 61 | $targetObj->loadXML($serverwizFile); |
| 62 | print "Loaded MRW XML: $serverwizFile \n"; |
| 63 | |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 64 | open(my $inFh, '<', $settingsFile) or die "Could not open file '$settingsFile' $!"; |
| 65 | open(my $outFh, '>', $outputFile) or die "Could not open file '$outputFile' $!"; |
| 66 | |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 67 | if (length($expressionVars) > 0) |
| 68 | { |
| 69 | loadVars($expressionVars); |
| 70 | } |
| 71 | |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 72 | # Process all the targets in the XML |
| 73 | foreach 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 | } |
Matt Spinler | 64e084d | 2018-03-08 16:35:29 -0600 | [diff] [blame] | 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 | |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 104 | print $outFh $row; |
| 105 | } |
| 106 | last; |
| 107 | close $inFh; |
| 108 | close $outFh; |
| 109 | } |
| 110 | |
Matt Spinler | 64e084d | 2018-03-08 16:35:29 -0600 | [diff] [blame] | 111 | #Evaluate the expression passed in. Substitute any variables with |
| 112 | #their values passed in on the command line. |
| 113 | sub 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 | |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 134 | #Parse the variable=value string passed in from the |
| 135 | #command line and load it into %exprVars. |
| 136 | sub 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 | |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 156 | # Usage |
| 157 | sub printUsage |
| 158 | { |
| 159 | print " |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 160 | $0 -i [XML filename] -s [Settings YAML] -o [Output filename] -v [expr vars] [OPTIONS] |
Gunnar Mills | 4576533 | 2017-09-26 16:19:32 -0500 | [diff] [blame] | 161 | |
| 162 | Required: |
| 163 | -i = MRW XML filename |
| 164 | -s = The Setting YAML with MRW variables in MRW_<MRW variable name> format |
| 165 | -o = YAML output filename |
Matt Spinler | ab2b9c3 | 2018-03-08 16:08:32 -0600 | [diff] [blame] | 166 | Optional: |
| 167 | -v = Variables and values for any [[expression]] evaluation |
| 168 | in the form: \"VAR1=VALUE1 VAR2=VALUE2\" |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 169 | Options: |
| 170 | -f = force output file creation even when errors |
| 171 | -d = debug mode |
Gunnar Mills | bff5684 | 2017-09-25 15:49:16 -0500 | [diff] [blame] | 172 | \n"; |
| 173 | exit(1); |
| 174 | } |