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

x2go pushed a commit to branch master
in repository x2goserver.

commit 38189f763eedeff2ed61949b872c86aa1cdb954e
Author: Mihai Moldovan <io...@ionic.de>
Date:   Sat Nov 7 11:00:53 2020 +0100

    X2Go/Server/Agent/NX/Options.pm: add new function compact_intermediate, 
used to remove duplicated and empty elements.
---
 X2Go/Server/Agent/NX/Options.pm | 105 +++++++++++++++++++++++++++++++++++++++-
 debian/changelog                |   2 +
 2 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/X2Go/Server/Agent/NX/Options.pm b/X2Go/Server/Agent/NX/Options.pm
index 67cbb343..a73d4e46 100644
--- a/X2Go/Server/Agent/NX/Options.pm
+++ b/X2Go/Server/Agent/NX/Options.pm
@@ -28,7 +28,7 @@ use English qw (-no_match_vars);
 use Storable qw (dclone);
 
 our @EXPORT_OK = qw (MODE_INVALID MODE_ADD_UPDATE MODE_REMOVE
-                     parse_options interpret_transform transform_intermediate 
intermediate_to_string);
+                     parse_options interpret_transform transform_intermediate 
intermediate_to_string compact_intermediate);
 
 
 # These are actually supposed to be enums, but since Perl doesn't have a
@@ -671,6 +671,109 @@ sub interpret_transform {
   return $ret;
 }
 
+# Compacts entries in the intermediate options array.
+#
+# Expects an intermediate options reference as its first and only parameter.
+#
+# Compacting means that:
+#   - Duplicated keys are removed, only the last one is kept.
+#   - Empty key-value pairs are discarded (unless it's the only element).
+#
+# Returns a reference to the modified, compacted intermediate options array.
+#
+# On error, returns a reference to undef.
+sub compact_intermediate {
+  my $ret = undef;
+  my $error_detected = 0;
+  my @new_intermediate = ();
+
+  my $intermediate = shift;
+
+  if ('ARRAY' ne ref ($intermediate)) {
+    print {*STDERR} 'Invalid options reference type passed (' . ref 
($intermediate) . "), erroring out.\n";
+    $error_detected = 1;
+  }
+
+  if (!($error_detected)) {
+    if (0 < scalar (@{$intermediate})) {
+      foreach my $entry (@{$intermediate}) {
+        if (!defined ($entry)) {
+          print {*STDERR} "Invalid options array passed, erroring out.\n";
+          $error_detected = 1;
+        }
+      }
+    }
+  }
+
+  if (!($error_detected)) {
+    # First, save display number part.
+    my $display_number = pop (@{$intermediate});
+
+    # Here's the clever part:
+    #   - Copy data into a single hash.
+    #     This will not preserve the order, but make sure that each entry is
+    #     unique.
+    #   - To preserve the order, evict entries from the original intermediate
+    #     array iff this temporary hash already contains such a key.
+    #     This makes sure that the original intermediate array will only
+    #     contain unique entries in the right order - at least if the order is
+    #     "first seen". Implementing this in a "last seen" manner would be a
+    #     lot more complicated.
+    my %temp_hash = ();
+    @{$intermediate} = grep {
+      my $grep_ret = 0;
+
+      # This foreach loop will only execute at most once, really, since each
+      # hash in an intermediate array is supposed to contain just one element.
+      #
+      # Additionally, it might not execute at all if the hash is empty, which
+      # will implicitly remove the empty element through our $grep_ret's
+      # initial value.
+      #
+      # Do not use each () here. It doesn't shorten the code and is very
+      # sensitive to the internal iterator. Additionally, it makes
+      # modifications unsafe. While we don't need that right now, it's
+      # probably a good idea to keep this future-proof.
+      foreach my $key (keys (%{$_})) {
+        my $value = $_->{$key};
+
+        # If the key exists in the temporary hash, this element is a duplicate
+        # and we can mark it for deletion.
+        # Otherwise, we'll have to keep it.
+        if (!(exists ($temp_hash{$key}))) {
+          $grep_ret = 1;
+        }
+
+        # And in any case, update the value (or create a new entry).
+        $temp_hash{$key} = $value;
+      }
+
+      $grep_ret;
+    } @{$intermediate};
+
+    # Lastly, map values from the temporary hash back to the intermediate
+    # array.
+    foreach my $entry (@{$intermediate}) {
+      foreach my $key (keys (%{$entry})) {
+        $entry->{$key} = $temp_hash{$key};
+      }
+    }
+
+    # We need to add an empty element if the intermediate array is now empty.
+    if (0 == scalar (@{$intermediate})) {
+      print {*STDERR} "Compacting operation led to option string being empty, 
adding empty element though deprecated.\n";
+      push (@{$intermediate}, { });
+    }
+
+    # Lastly, re-add the display number part.
+    push (@{$intermediate}, $display_number);
+
+    $ret = $intermediate;
+  }
+
+  return $ret;
+}
+
 1;
 __END__
 
diff --git a/debian/changelog b/debian/changelog
index e42be487..2d73e953 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -222,6 +222,8 @@ x2goserver (4.1.0.4-0x2go1.2) UNRELEASED; urgency=medium
       include undef entries.
     - x2goserver/lib/x2goupdateoptionsstring: switch to "X2Go/NX Agent" term
       and make it bold to denote something special.
+    - X2Go/Server/Agent/NX/Options.pm: add new function compact_intermediate,
+      used to remove duplicated and empty elements.
   * debian/control:
     + Build-depend upon lsb-release for distro version detection.
   * debian/x2goserver.manpages:

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on 
/srv/git/code.x2go.org/x2goserver.git
_______________________________________________
x2go-commits mailing list
x2go-commits@lists.x2go.org
https://lists.x2go.org/listinfo/x2go-commits

Reply via email to