You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcpcfg/helper/set-value

118 lines
3.2 KiB

#!/usr/bin/perl -wCSD
use strict;
use warnings;
use Safe;
use YAML::XS;
use Scalar::Util qw(looks_like_number);
my ($file, @data) = @ARGV;
unless (defined($file)) {
print {*STDERR} ("1st parameter 'file' is not defined\n");
exit (1);
}
unless (@data) {
print {*STDERR} ("2nd parameter 'data' is not defined\n");
exit (1);
}
my $yaml = YAML::XS::LoadFile($file);
my $compartment = Safe->new();
foreach my $option_data (@data) {
my ($option, $value) = $option_data =~ m/^([\w\.\[\]]+)=(.+)$/;
if (!(defined($option)) || !(defined($value))) {
print {*STDERR} ("Error: can't parse '$option_data'\n");
exit (1);
}
else {
set_value($option, $value);
}
}
YAML::XS::DumpFile($file, $yaml);
sub log_debug {
my $message = shift;
if (defined($ENV{DEBUG})) {
print "$message\n";
}
}
sub set_value {
my $option = shift;
my $value = shift;
my $valref = \$yaml;
if ($value =~ /^['"]+.*['"]+$/) {
log_debug ('$value is already quoted.');
}
elsif (looks_like_number($value)) {
log_debug ('Not quoting $value for integers.');
}
elsif ($value =~ /^\[.*\]$/) {
log_debug ('Not quoting $value for arrays.');
if ($value =~ /^\[\]$/) {
log_debug ('Empty array, do not check quoting');
}
elsif ($value !~ /^\[['"].+['"]\]$/) {
print {*STDERR} ("Error: Elements in array '$value' should be quoted\n");
exit (1);
}
}
elsif ($value =~ /^\{.*\}$/) {
log_debug ('Not quoting $value for hashes.');
}
else {
$value = "\"$value\"";
}
# If the value is a float number like N.0 - reval turns it into int N
# even if it's quoted.
if ($value =~ /^['"]*(\d+\.\d+)['"]*$/ ) {
$value = $1;
log_debug ('$value is a float number so no need to reval() it');
}
else {
$value = $compartment->reval($value);
}
for my $component (split(/\./, $option)) {
if (ref($valref) eq 'SCALAR' && defined(${$valref})) {
print {*STDERR} ("Key resolved to a SCALAR at '$component'; cannot continue.\n");
exit (1);
}
elsif (looks_like_number($component) && (! defined(${$valref}) || ref(${$valref}) eq 'ARRAY')) {
$valref = \${$valref}->[$component];
}
elsif ($component eq 'APPEND' && ref($$valref) eq 'ARRAY') {
$valref = \${$valref}->[$#{$$valref}+1];
}
elsif (! defined(${$valref}) || ref(${$valref}) eq 'HASH') {
$valref = \${$valref}->{$component};
}
else {
print {*STDERR} ("Key resolved to a " . ref(${$valref}) . " reference; refusing to overwrite.\n");
exit (1);
}
}
if (! defined(${$valref}) || ref($valref) eq 'SCALAR') {
${$valref} = $value;
}
elsif (ref(${$valref}) eq 'ARRAY' && ref($value) eq 'ARRAY') {
${$valref} = $value;
}
elsif (ref(${$valref}) eq 'HASH' && ref($value) eq 'HASH') {
${$valref} = $value;
}
else {
print {*STDERR} ("Key resolved to a " . ref(${$valref}) . " reference; refusing to overwrite.\n");
exit (1);
}
}