1# -*- cperl -*-
2# Copyright (c) 2008, 2021, Oracle and/or its affiliates.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License, version 2.0,
6# as published by the Free Software Foundation.
7#
8# This program is also distributed with certain software (including
9# but not limited to OpenSSL) that is licensed under separate terms,
10# as designated in a particular file or component or in included license
11# documentation.  The authors of MySQL hereby grant you an additional
12# permission to link the program and your derivative works with the
13# separately licensed software that they have included with MySQL.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License, version 2.0, for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23
24
25package My::Options;
26
27#
28# Utility functions to work with list of options
29#
30
31use strict;
32
33
34sub same($$) {
35  my $l1= shift;
36  my $l2= shift;
37  return compare($l1,$l2) == 0;
38}
39
40
41sub compare ($$) {
42  my $l1= shift;
43  my $l2= shift;
44
45  my @l1= @$l1;
46  my @l2= @$l2;
47
48  return -1 if @l1 < @l2;
49  return  1 if @l1 > @l2;
50
51  while ( @l1 )                         # Same length
52  {
53    my $e1= shift @l1;
54    my $e2= shift @l2;
55    my $cmp= ($e1 cmp $e2);
56    return $cmp if $cmp != 0;
57  }
58
59  return 0;                             # They are the same
60}
61
62
63sub _split_option {
64  my ($option)= @_;
65  if ($option=~ /^--(.*)=(.*)$/){
66    return ($1, $2);
67  }
68  elsif ($option=~ /^--(.*)$/){
69    return ($1, undef)
70  }
71  elsif ($option=~ /^\$(.*)$/){ # $VAR
72    return ($1, undef)
73  }
74  elsif ($option=~ /^(.*)=(.*)$/){
75    return ($1, $2)
76  }
77  die "Unknown option format '$option'";
78}
79
80
81sub _build_option {
82  my ($name, $value)= @_;
83  if ($name =~ /^O, /){
84    return "-".$name."=".$value;
85  }
86  elsif ($value){
87    return "--".$name."=".$value;
88  }
89  return "--".$name;
90}
91
92
93#
94# Compare two list of options and return what would need
95# to be done to get the server running with the new settings
96#
97sub diff {
98  my ($from_opts, $to_opts)= @_;
99
100  my %from;
101  foreach my $from (@$from_opts)
102  {
103    my ($opt, $value)= _split_option($from);
104    next unless defined($opt);
105    $from{$opt}= $value;
106  }
107
108  #print "from: ", %from, "\n";
109
110  my %to;
111  foreach my $to (@$to_opts)
112  {
113    my ($opt, $value)= _split_option($to);
114    next unless defined($opt);
115    $to{$opt}= $value;
116  }
117
118  #print "to: ", %to, "\n";
119
120  # Remove the ones that are in both lists
121  foreach my $name (keys %from){
122    if (exists $to{$name} and $to{$name} eq $from{$name}){
123      #print "removing '$name'  from both lists\n";
124      delete $to{$name};
125      delete $from{$name};
126    }
127  }
128
129  #print "from: ", %from, "\n";
130  #print "to: ", %to, "\n";
131
132  # Add all keys in "to" to result
133  my @result;
134  foreach my $name (keys %to){
135    push(@result, _build_option($name, $to{$name}));
136  }
137
138  # Add all keys in "from" that are not in "to"
139  # to result as "set to default"
140  foreach my $name (keys %from){
141    if (not exists $to{$name}) {
142      push(@result, _build_option($name, "default"));
143    }
144  }
145
146  return @result;
147}
148
149
150sub is_set {
151  my ($opts, $set_opts)= @_;
152
153  foreach my $opt (@$opts){
154
155    my ($opt_name1, $value1)= _split_option($opt);
156
157    foreach my $set_opt (@$set_opts){
158      my ($opt_name2, $value2)= _split_option($set_opt);
159
160      if (option_equals($opt_name1,$opt_name2)){
161	# Option already set
162	return 1;
163      }
164    }
165  }
166
167  return 0;
168}
169
170
171sub toSQL {
172  my (@options)= @_;
173  my @sql;
174
175  foreach my $option (@options) {
176    my ($sql_name, $value)= _split_option($option);
177    #print "name: $sql_name\n";
178    #print "value: $value\n";
179    $sql_name=~ s/-/_/g;
180    push(@sql, "SET GLOBAL $sql_name=$value");
181  }
182  return join("; ", @sql);
183}
184
185
186sub toStr {
187  my $name= shift;
188  return "$name: ",
189    "['", join("', '", @_), "']\n";
190}
191
192
193sub option_equals {
194  my ($string1, $string2) = @_;
195
196  $string1 =~ s/_/-/g;
197  $string2 =~ s/_/-/g;
198
199  return ( $string1 eq $string2 );
200}
201
2021;
203
204