8 $0: to check ODP sets of actions for equivalence
9 usage: $0 ACTIONS1 ACTIONS2 [NAME=NUMBER]...
10 where ACTIONS1 and ACTIONS2 are sets of ODP actions as output by, e.g.
11 "ovs-dpctl dump-flows" and each NAME=NUMBER pair identifies an ODP
12 port's name-to-number mapping.
14 Exits with status 0 if ACTIONS1 and ACTIONS2 are equivalent, with
15 status 1 if they differ.
20 # Construct mappings between port numbers and names.
21 our (%name_to_number);
22 our (%number_to_name);
23 for (@ARGV[2..$#ARGV]) {
24 my ($name, $number) = /([^=]+)=([0-9]+)/
25 or die "$_: bad syntax (use --help for help)\n";
26 $number_to_name{$number} = $name;
27 $name_to_number{$name} = $number;
30 my $n1 = normalize_odp_actions($ARGV[0]);
31 my $n2 = normalize_odp_actions($ARGV[1]);
32 print "Normalized action set 1: $n1\n";
33 print "Normalized action set 2: $n2\n";
36 sub normalize_odp_actions {
39 # Transliterate all commas inside parentheses into semicolons.
40 undef while $actions =~ s/(\([^),]*),([^)]*\))/$1;$2/g;
43 my (@actions) = split(',', $actions);
45 # Map port numbers into port names.
46 foreach my $s (@actions) {
47 $s = $number_to_name{$s} if exists($number_to_name{$s});
50 # Sort sequential groups of port names into alphabetical order.
51 for (my $i = 0; $i <= $#actions; ) {
53 if (exists($name_to_number{$actions[$i]})) {
54 for (; $j <= $#actions; $j++) {
55 last if !exists($name_to_number{$actions[$j]});
58 @actions[$i..($j - 1)] = sort(@actions[$i..($j - 1)]);
62 # Now compose a string again and transliterate semicolons back to commas.
63 $actions = join(',', @actions);