| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
|
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2006,2007,2009 -- leonerd@leonerd.org.uk |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package String::Expand; |
|
7
|
|
|
|
|
|
|
|
|
8
|
3
|
|
|
3
|
|
77806
|
use strict; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
112
|
|
|
9
|
3
|
|
|
3
|
|
18
|
use warnings; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
100
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
3
|
|
|
3
|
|
26
|
use Exporter; |
|
|
3
|
|
|
|
|
13
|
|
|
|
3
|
|
|
|
|
287
|
|
|
12
|
|
|
|
|
|
|
our @ISA = qw( Exporter ); |
|
13
|
|
|
|
|
|
|
our @EXPORT = qw( |
|
14
|
|
|
|
|
|
|
expand_string |
|
15
|
|
|
|
|
|
|
expand_strings |
|
16
|
|
|
|
|
|
|
); |
|
17
|
|
|
|
|
|
|
|
|
18
|
3
|
|
|
3
|
|
19
|
use Carp; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
2290
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our $VERSION = '0.04'; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $VARNAME_MATCH = qr/\$([A-Z_][A-Z0-9_]*|\{.*?\})/; |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 NAME |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
C - string utility functions for expanding variables in |
|
27
|
|
|
|
|
|
|
self-referential sets |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use String::Expand qw( expand_strings ); |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my %vars = ( MESSAGE => 'My home is $HOME', |
|
34
|
|
|
|
|
|
|
TEXT => 'Message is "$MESSAGE"' ); |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
expand_strings( \%vars, \%ENV ); |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# %vars now contains something like: |
|
39
|
|
|
|
|
|
|
# MESSAGE => 'My home is /home/user', |
|
40
|
|
|
|
|
|
|
# TEXT => 'Message is "My home is /home/user"' |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
This module implements utility functions for expanding embedded variables in a |
|
45
|
|
|
|
|
|
|
string. Variable references are embedded in strings in a similar form to the |
|
46
|
|
|
|
|
|
|
Bourne shell, namely, in the form C<$NAME> or C<${NAME}>. In the former case, |
|
47
|
|
|
|
|
|
|
the C must consist of a capital letter or underscore, and may be |
|
48
|
|
|
|
|
|
|
followed by zero or more capital letters, digits or underscores. In the latter |
|
49
|
|
|
|
|
|
|
case, the name can consist of any characters, but will be terminated by the |
|
50
|
|
|
|
|
|
|
first close brace character C<'}'>. |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
The string may also contain literal dollar marks, escaped by C<\$>, and |
|
53
|
|
|
|
|
|
|
literal escape marks, escaped by C<\\>. These will be converted to C<$> and |
|
54
|
|
|
|
|
|
|
C<\> respectively on return. |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
While there are many other modules that also provide expansion such as this, |
|
57
|
|
|
|
|
|
|
this module provides the function C, which will perform |
|
58
|
|
|
|
|
|
|
variable expansions in all the values in a given hash, where values can refer |
|
59
|
|
|
|
|
|
|
to other values within the same hash. |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=cut |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=cut |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub expand_one_var($$) |
|
68
|
|
|
|
|
|
|
{ |
|
69
|
5
|
|
|
5
|
0
|
12
|
my ( $var, $vars ) = @_; |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# Chop off delimiting {braces} if present |
|
72
|
5
|
|
|
|
|
19
|
$var =~ s/^\{(.*)\}$/$1/; |
|
73
|
|
|
|
|
|
|
|
|
74
|
5
|
100
|
|
|
|
19
|
unless( defined $vars->{$var} ) { |
|
75
|
1
|
|
|
|
|
29
|
croak "Unknown variable '$var'"; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
4
|
|
|
|
|
21
|
return $vars->{$var}; |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=head2 $expanded = expand_string( $str, \%vars ) |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
This function expands embedded variable references in the passed string, and |
|
84
|
|
|
|
|
|
|
returns the expanded copy. |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=over 8 |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item $str |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
A string possibly containing variable expansions |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=item \%vars |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Reference to a hash containing variable values |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item Returns |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
A string with variables expanded |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=back |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=cut |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub expand_string($$) |
|
105
|
|
|
|
|
|
|
{ |
|
106
|
7
|
|
|
7
|
1
|
4252
|
my ( $str, $vars ) = @_; |
|
107
|
|
|
|
|
|
|
|
|
108
|
7
|
|
|
|
|
120
|
$str =~ s{\\([\\\$])|$VARNAME_MATCH} |
|
109
|
8
|
100
|
|
|
|
49
|
{ $1 or expand_one_var( $2, $vars )}eg; |
|
110
|
|
|
|
|
|
|
|
|
111
|
6
|
|
|
|
|
24
|
return $str; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub expand_strings_inner($$$$); |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub expand_strings_one_var($$$$) |
|
117
|
|
|
|
|
|
|
{ |
|
118
|
8
|
|
|
8
|
0
|
18
|
my ( $var, $strs, $overlay, $done ) = @_; |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# Chop off delimiting {braces} if present |
|
121
|
8
|
|
|
|
|
31
|
$var =~ s/^\{(.*)\}$/$1/; |
|
122
|
|
|
|
|
|
|
|
|
123
|
8
|
100
|
|
|
|
26
|
if( exists $strs->{$var} ) { |
|
124
|
5
|
100
|
|
|
|
20
|
return $strs->{$var} if( $done->{$var} ); |
|
125
|
|
|
|
|
|
|
# Detect loops |
|
126
|
4
|
100
|
|
|
|
10
|
if( exists $done->{$var} ) { |
|
127
|
1
|
|
|
|
|
29
|
croak "Variable loop trying to expand '$var'"; |
|
128
|
|
|
|
|
|
|
} |
|
129
|
3
|
|
|
|
|
5
|
$done->{$var} = 0; |
|
130
|
3
|
|
|
|
|
8
|
expand_strings_inner( $strs, $overlay, $var, $done ); |
|
131
|
2
|
|
|
|
|
10
|
return $strs->{$var}; |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
|
|
134
|
3
|
50
|
|
|
|
24
|
return $overlay->{$var} if( exists $overlay->{$var} ); |
|
135
|
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
0
|
croak "Unknown variable '$var'"; |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub expand_strings_inner($$$$) |
|
140
|
|
|
|
|
|
|
{ |
|
141
|
17
|
|
|
17
|
0
|
31
|
my ( $strs, $overlay, $v, $done ) = @_; |
|
142
|
|
|
|
|
|
|
|
|
143
|
17
|
100
|
|
|
|
63
|
if( $strs->{$v} =~ m/[\\\$]/ ) { |
|
144
|
11
|
|
|
|
|
145
|
$strs->{$v} =~ s{\\([\\\$])|$VARNAME_MATCH} |
|
145
|
12
|
100
|
|
|
|
58
|
{ $1 or expand_strings_one_var( $2, $strs, $overlay, $done )}eg; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
15
|
|
|
|
|
58
|
$done->{$v} = 1; |
|
149
|
|
|
|
|
|
|
} |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 expand_strings( \%strs, \%overlay ) |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
This function takes a hash of strings, and expands variable names embedded in |
|
154
|
|
|
|
|
|
|
any of them, in the same form as the string passed to C. |
|
155
|
|
|
|
|
|
|
Expansions may refer to other strings, or to values in the C> |
|
156
|
|
|
|
|
|
|
hash. Values in the main variables hash take precidence over values in the |
|
157
|
|
|
|
|
|
|
overlay. |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
Where values refer to other values, care must be taken to avoid cycles. If a |
|
160
|
|
|
|
|
|
|
cycle is detected while attempting to expand the values, then an exception is |
|
161
|
|
|
|
|
|
|
thrown. |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=over 8 |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=item \%strs |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Reference to a hash containing variables to expand |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=item \%overlay |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
Reference to a hash containing other variable values |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=item Returns |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Nothing |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=back |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=cut |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub expand_strings($$) |
|
182
|
|
|
|
|
|
|
{ |
|
183
|
7
|
|
|
7
|
1
|
4545
|
my ( $strs, $overlay ) = @_; |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# 0: a variable expansion is in progress |
|
186
|
|
|
|
|
|
|
# 1: value has been correctly expanded |
|
187
|
7
|
|
|
|
|
9
|
my %done; |
|
188
|
|
|
|
|
|
|
|
|
189
|
7
|
|
|
|
|
49
|
foreach my $v ( keys %$strs ) { |
|
190
|
14
|
|
|
|
|
31
|
expand_strings_inner( $strs, $overlay, $v, \%done ); |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Keep perl happy; keep Britain tidy |
|
195
|
|
|
|
|
|
|
1; |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
__END__ |