2 # Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
16 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
19 @EXPORT = qw(cmp_versions quotify1 quotify_l dump_data);
24 OpenSSL::Util - small OpenSSL utilities
30 $versiondiff = cmp_versions('1.0.2k', '3.0.1');
31 # $versiondiff should be -1
33 $versiondiff = cmp_versions('1.1.0', '1.0.2a');
34 # $versiondiff should be 1
36 $versiondiff = cmp_versions('1.1.1', '1.1.1');
37 # $versiondiff should be 0
43 =item B<cmp_versions "VERSION1", "VERSION2">
45 Compares VERSION1 with VERSION2, paying attention to OpenSSL versioning.
47 Returns 1 if VERSION1 is greater than VERSION2, 0 if they are equal, and
48 -1 if VERSION1 is less than VERSION2.
54 # Until we're rid of everything with the old version scheme,
55 # we need to be able to handle older style x.y.zl versions.
56 # In terms of comparison, the x.y.zl and the x.y.z schemes
57 # are compatible... mostly because the latter starts at a
58 # new major release with a new major number.
59 sub _ossl_versionsplit {
60 my $textversion = shift;
61 return $textversion if $textversion eq '*';
62 my ($major,$minor,$edit,$letter) =
63 $textversion =~ /^(\d+)\.(\d+)\.(\d+)([a-z]{0,2})$/;
65 return ($major,$minor,$edit,$letter);
69 my @a_split = _ossl_versionsplit(shift);
70 my @b_split = _ossl_versionsplit(shift);
74 # The last part is a letter sequence (or a '*')
75 if (scalar @a_split == 1) {
76 $verdict = $a_split[0] cmp $b_split[0];
78 $verdict = $a_split[0] <=> $b_split[0];
82 last unless $verdict == 0;
88 # It might be practical to quotify some strings and have them protected
89 # from possible harm. These functions primarily quote things that might
90 # be interpreted wrongly by a perl eval.
96 This adds quotes (") around the given string, and escapes any $, @, \,
97 " and ' by prepending a \ to them.
105 $s =~ s/([\$\@\\"'])/\\$1/g;
113 For each defined element in LIST (i.e. elements that aren't undef), have
114 it quotified with 'quotify1'.
115 Undefined elements are ignored.
129 =item dump_data REF, OPTS
131 Dump the data from REF into a string that can be evaluated into the same
134 OPTS is the rest of the arguments, expected to be pairs formed with C<< => >>.
135 The following OPTS keywords are understood:
139 =item B<delimiters =E<gt> 0 | 1>
141 Include the outer delimiter of the REF type in the resulting string if C<1>,
144 =item B<indent =E<gt> num>
146 The indentation of the caller, i.e. an initial value. If not given, there
147 will be no indentation at all, and the string will only be one line.
156 # indent => callers indentation ( undef for no indentation,
157 # an integer otherwise )
158 # delimiters => 1 if outer delimiters should be added
161 my $indent = $opts{indent} // 1;
162 # Indentation of the whole structure, where applicable
163 my $nlindent1 = defined $opts{indent} ? "\n" . ' ' x $indent : ' ';
164 # Indentation of individual items, where applicable
165 my $nlindent2 = defined $opts{indent} ? "\n" . ' ' x ($indent + 4) : ' ';
168 $subopts{delimiters} = 1;
169 $subopts{indent} = $opts{indent} + 4 if defined $opts{indent};
171 my $product; # Finished product, or reference to a function that
172 # produces a string, given $_
173 # The following are only used when $product is a function reference
174 my $delim_l; # Left delimiter of structure
175 my $delim_r; # Right delimiter of structure
176 my $separator; # Item separator
177 my @items; # Items to iterate over
179 if (ref($ref) eq "ARRAY") {
180 if (scalar @$ref == 0) {
181 $product = $opts{delimiters} ? '[]' : '';
184 dump_data(\$_, %subopts)
186 $delim_l = ($opts{delimiters} ? '[' : '').$nlindent2;
187 $delim_r = $nlindent1.($opts{delimiters} ? ']' : '');
188 $separator = ",$nlindent2";
191 } elsif (ref($ref) eq "HASH") {
192 if (scalar keys %$ref == 0) {
193 $product = $opts{delimiters} ? '{}' : '';
196 quotify1($_) . " => " . dump_data($ref->{$_}, %subopts);
198 $delim_l = ($opts{delimiters} ? '{' : '').$nlindent2;
199 $delim_r = $nlindent1.($opts{delimiters} ? '}' : '');
200 $separator = ",$nlindent2";
201 @items = sort keys %$ref;
203 } elsif (ref($ref) eq "SCALAR") {
204 $product = defined $$ref ? quotify1 $$ref : "undef";
206 $product = defined $ref ? quotify1 $ref : "undef";
209 if (ref($product) eq "CODE") {
210 $delim_l . join($separator, map { &$product } @items) . $delim_r;