[X2Go-Commits] [x2goserver] 13/30: x2goserver/lib/x2goupdateoptionsstring: add functionality for options removal.

git-admin at x2go.org git-admin at x2go.org
Thu Dec 13 11:22:47 CET 2018


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goserver.

commit 4f95c1d54c3aa8381252823d3acaa223fe6ae1db
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Sun Dec 9 02:05:36 2018 +0100

    x2goserver/lib/x2goupdateoptionsstring: add functionality for options removal.
---
 debian/changelog                       |   2 +
 x2goserver/lib/x2goupdateoptionsstring | 149 ++++++++++++++++++++++++++++++++-
 2 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 04a6f6f..8df7ab8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -33,6 +33,8 @@ x2goserver (4.1.0.4-0x2go1) UNRELEASED; urgency=medium
       with filehandles in curly braces.
     - x2goserver/lib/x2goupdateoptionsstring: fix some "errors" reported by
       Perl::Critic in brutal mode.
+    - x2goserver/lib/x2goupdateoptionsstring: add functionality for options
+      removal.
   * debian/control:
     + Build-depend upon lsb-release for distro version detection.
   * debian/x2goserver.manpages:
diff --git a/x2goserver/lib/x2goupdateoptionsstring b/x2goserver/lib/x2goupdateoptionsstring
index 694567c..4bbe0f5 100755
--- a/x2goserver/lib/x2goupdateoptionsstring
+++ b/x2goserver/lib/x2goupdateoptionsstring
@@ -21,10 +21,11 @@ use strict;
 use warnings;
 
 #use X2Go::Utils qw (is_int);
-use Data::Dumper qw (Dumper);
+use English qw (-no_match_vars);
 use Getopt::Long;
 use Pod::Usage;
-use English qw (-no_match_vars);
+use Storable qw (dclone);
+use Data::Dumper qw (Dumper);
 
 # Accepts an option string and returns a reference to an array of hashes
 # (actually hash references) corresponding to the parsed key-value pairs.
@@ -286,6 +287,144 @@ sub intermediate_to_string {
   return $ret;
 }
 
+# Helper for a grep operation on the intermediate options array.
+#
+# Takes the option to remove, the current element and amount of elements left
+# in the array as arguments and returns true if the element is not to be
+# removed, false otherwise.
+sub filter_option_remove {
+  my $ret = 1;
+  my $error_detected = 0;
+  my $to_remove = shift;
+  my $cur_option = shift;
+  my $elems_left = shift;
+
+  if (!((defined ($to_remove)) && (defined ($cur_option)) && (defined ($elems_left)))) {
+    # Undefined values are an error in this context, but erroring out in a
+    # comparison function is... weird, so let's treat such errors as "don't
+    # modify the array".
+    print {*STDERR} "Invalid options passed to removal filter, keeping entry.\n";
+    $error_detected = 1;
+  }
+
+  if (!($error_detected)) {
+    if ('HASH' ne ref ($cur_option)) {
+      print {*STDERR} "Option passed to removal filter is not a hash reference, keeping entry.\n";
+      $error_detected = 1;
+    }
+  }
+
+  if (!($error_detected)) {
+    if (1 < scalar (keys (%{$cur_option}))) {
+      print {*STDERR} "Option passed to removal filter has more than one entry in hash, keeping entry.\n";
+      $error_detected = 1;
+    }
+  }
+
+  my $to_remove_key = undef;
+  my $to_remove_value = undef;
+  my @to_remove_kv = split (/=/smx, $to_remove, 2);
+
+  if (!($error_detected)) {
+    if (2 < scalar (@to_remove_kv)) {
+      print {*STDERR} "Option-to-be-removed string in removal filter has three or more components, this is a bug in $PROGRAM_NAME. Keeping entry.\n";
+      $error_detected = 1;
+    }
+  }
+
+  if (!($error_detected) && (0 < $elems_left)) {
+    $to_remove_key = shift (@to_remove_kv);
+
+    # Key can be undef if splitting failed, e.g., due to an empty input string.
+    # We don't consider this an error, so reset the key to an empty string.
+    if (!(defined ($to_remove_key))) {
+      $to_remove_key = q{};
+    }
+
+    $to_remove_value = shift (@to_remove_kv);
+
+    my $option_key = q{};
+    my $option_value = undef;
+
+    foreach my $tmp_option_key (keys (%{$cur_option})) {
+      $option_key = $tmp_option_key;
+      $option_value = $cur_option->{$tmp_option_key};
+    }
+
+    if ($to_remove_key eq $option_key) {
+      # Okay, we've got a match. But we might have to also check the value...
+      if (defined ($to_remove_value)) {
+        # Yep, value must match, too, but beware of undef values in the current
+        # option entry.
+        if ((defined ($option_value)) && ($to_remove_value eq $option_value)) {
+          # Everything matches, mark for removal.
+          $ret = 0;
+        }
+      }
+      else {
+        $ret = 0;
+      }
+    }
+  }
+
+  return $ret;
+}
+
+# Removes an entry from the intermediate options array.
+#
+# If only a key is specified, removes any entry that matches this key,
+# regardless of its value.
+#
+# If both a key and a value are specified, only matching combinations will be
+# removed from the array. That is, if the array already contains such a key
+# with either no value or a different value, it will be unaffected.
+#
+# Returns a reference to a modified copy of the intermediate options array.
+#
+# On error, returns a reference to undef.
+sub remove_option {
+  my $ret = undef;
+  my $error_detected = 0;
+
+  my $options = shift;
+  my $option = shift;
+
+  if ('ARRAY' ne ref ($options)) {
+    print {*STDERR} 'Invalid options reference type passed (' . ref ($options) . "), erroring out.\n";
+    $error_detected = 1;
+  }
+
+  if (!($error_detected)) {
+    if (1 == scalar (@{$options})) {
+      foreach my $entry (@{$options}) {
+        if (!defined ($entry)) {
+          print {*STDERR} "Invalid options array passed, erroring out.\n";
+          $error_detected = 1;
+        }
+      }
+    }
+  }
+
+  if (!($error_detected)) {
+    if (!(defined ($option))) {
+      print {*STDERR} "No or invalid option to be removed passed, erroring out.\n";
+      $error_detected = 1;
+    }
+  }
+
+  if (!($error_detected)) {
+    # Set return value to a *deep copy* of our original array.
+    $ret = dclone ($options);
+
+    my $elements_left = @{$ret};
+
+    # Let the filter function handle the actual work.
+    @{$ret} = grep { filter_option_remove ($option, $_, --$elements_left) } (@{$ret});
+  }
+
+  return $ret;
+}
+
 Getopt::Long::Configure('gnu_getopt', 'no_auto_abbrev');
 
 my $help = 0;
@@ -302,6 +441,12 @@ print {*STDERR} Dumper ($intermediate) . "\n";
 
 print {*STDERR} Dumper (intermediate_to_string ($intermediate)) . "\n";
 
+my $option_to_remove = shift;
+
+print {*STDERR} Dumper (remove_option ($intermediate, $option_to_remove)) . "\n";
+
+print {*STDERR} Dumper (intermediate_to_string (remove_option ($intermediate, $option_to_remove))) . "\n";
+
 #my $value = shift;
 #my $allow_negative = shift;
 #

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goserver.git


More information about the x2go-commits mailing list