line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Audio::Nama::Assign; |
2
|
5
|
|
|
5
|
|
22902
|
use Modern::Perl; |
|
5
|
|
|
|
|
13533
|
|
|
5
|
|
|
|
|
38
|
|
3
|
|
|
|
|
|
|
our $VERSION = 1.0; |
4
|
5
|
|
|
5
|
|
860
|
use 5.008; |
|
5
|
|
|
|
|
17
|
|
5
|
5
|
|
|
5
|
|
27
|
use feature 'state'; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
330
|
|
6
|
5
|
|
|
5
|
|
28
|
use strict; |
|
5
|
|
|
|
|
13
|
|
|
5
|
|
|
|
|
112
|
|
7
|
5
|
|
|
5
|
|
49
|
use warnings; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
187
|
|
8
|
5
|
|
|
5
|
|
51
|
no warnings q(uninitialized); |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
221
|
|
9
|
5
|
|
|
5
|
|
26
|
use Carp qw(carp confess croak cluck); |
|
5
|
|
|
|
|
14
|
|
|
5
|
|
|
|
|
361
|
|
10
|
5
|
|
|
5
|
|
5347
|
use YAML::Tiny; |
|
5
|
|
|
|
|
30003
|
|
|
5
|
|
|
|
|
344
|
|
11
|
5
|
|
|
5
|
|
15747
|
use File::Slurp; |
|
5
|
|
|
|
|
72415
|
|
|
5
|
|
|
|
|
436
|
|
12
|
5
|
|
|
5
|
|
5986
|
use File::HomeDir; |
|
5
|
|
|
|
|
31475
|
|
|
5
|
|
|
|
|
306
|
|
13
|
5
|
|
|
5
|
|
2242
|
use Audio::Nama::Log qw(logsub logpkg); |
|
5
|
|
|
|
|
17
|
|
|
5
|
|
|
|
|
362
|
|
14
|
5
|
|
|
5
|
|
4275
|
use Storable qw(nstore retrieve); |
|
5
|
|
|
|
|
22782
|
|
|
5
|
|
|
|
|
390
|
|
15
|
5
|
|
|
5
|
|
6179
|
use JSON::XS; |
|
5
|
|
|
|
|
43118
|
|
|
5
|
|
|
|
|
320
|
|
16
|
5
|
|
|
5
|
|
3261
|
use Data::Dumper::Concise; |
|
5
|
|
|
|
|
27289
|
|
|
5
|
|
|
|
|
891
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
require Exporter; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
21
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw( |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
serialize |
24
|
|
|
|
|
|
|
assign |
25
|
|
|
|
|
|
|
assign_singletons |
26
|
|
|
|
|
|
|
store_vars |
27
|
|
|
|
|
|
|
json_out |
28
|
|
|
|
|
|
|
yaml_in |
29
|
|
|
|
|
|
|
json_in |
30
|
|
|
|
|
|
|
json_out |
31
|
|
|
|
|
|
|
quote_yaml_scalars |
32
|
|
|
|
|
|
|
var_map |
33
|
|
|
|
|
|
|
config_vars |
34
|
|
|
|
|
|
|
) ] ); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
our @EXPORT = (); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
our $to_json = JSON::XS->new->utf8->allow_blessed->pretty->canonical(1) ; |
41
|
5
|
|
|
5
|
|
33
|
use Carp; |
|
5
|
|
|
|
|
12
|
|
|
5
|
|
|
|
|
15867
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
{my $var_map = { qw( |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
%devices $config->{devices} |
46
|
|
|
|
|
|
|
$alsa_playback_device $config->{alsa_playback_device} |
47
|
|
|
|
|
|
|
$alsa_capture_device $config->{alsa_capture_device} |
48
|
|
|
|
|
|
|
$soundcard_channels $config->{soundcard_channels} |
49
|
|
|
|
|
|
|
%abbreviations $config->{abbreviations} |
50
|
|
|
|
|
|
|
$mix_to_disk_format $config->{mix_to_disk_format} |
51
|
|
|
|
|
|
|
$raw_to_disk_format $config->{raw_to_disk_format} |
52
|
|
|
|
|
|
|
$cache_to_disk_format $config->{cache_to_disk_format} |
53
|
|
|
|
|
|
|
$mixer_out_format $config->{mixer_out_format} |
54
|
|
|
|
|
|
|
$sample_rate $config->{sample_rate} |
55
|
|
|
|
|
|
|
$ecasound_tcp_port $config->{engine_tcp_port} |
56
|
|
|
|
|
|
|
$ecasound_globals $config->{engine_globals} |
57
|
|
|
|
|
|
|
$ecasound_buffersize $config->{engine_buffersize} |
58
|
|
|
|
|
|
|
$realtime_profile $config->{realtime_profile} |
59
|
|
|
|
|
|
|
$eq $mastering->{fx_eq} |
60
|
|
|
|
|
|
|
$low_pass $mastering->{fx_low_pass} |
61
|
|
|
|
|
|
|
$mid_pass $mastering->{fx_mid_pass} |
62
|
|
|
|
|
|
|
$high_pass $mastering->{fx_high_pass} |
63
|
|
|
|
|
|
|
$compressor $mastering->{fx_compressor} |
64
|
|
|
|
|
|
|
$spatialiser $mastering->{fx_spatialiser} |
65
|
|
|
|
|
|
|
$limiter $mastering->{fx_limiter} |
66
|
|
|
|
|
|
|
$project_root $config->{root_dir} |
67
|
|
|
|
|
|
|
$use_group_numbering $config->{use_group_numbering} |
68
|
|
|
|
|
|
|
$press_space_to_start_transport $config->{press_space_to_start} |
69
|
|
|
|
|
|
|
$execute_on_project_load $config->{execute_on_project_load} |
70
|
|
|
|
|
|
|
$initial_mode $config->{initial_mode} |
71
|
|
|
|
|
|
|
$midish_enable $config->{use_midish} |
72
|
|
|
|
|
|
|
$quietly_remove_tracks $config->{quietly_remove_tracks} |
73
|
|
|
|
|
|
|
$use_jack_plumbing $config->{use_jack_plumbing} |
74
|
|
|
|
|
|
|
$jack_seek_delay $config->{engine_base_jack_seek_delay} |
75
|
|
|
|
|
|
|
$use_monitor_version_for_mixdown $config->{sync_mixdown_and_monitor_version_numbers} |
76
|
|
|
|
|
|
|
$mixdown_encodings $config->{mixdown_encodings} |
77
|
|
|
|
|
|
|
$volume_control_operator $config->{volume_control_operator} |
78
|
|
|
|
|
|
|
$serialize_formats $config->{serialize_formats} |
79
|
|
|
|
|
|
|
$use_git $config->{use_git} |
80
|
|
|
|
|
|
|
$autosave $config->{autosave} |
81
|
|
|
|
|
|
|
$beep_command $config->{beep_command} |
82
|
|
|
|
|
|
|
$hotkey_beep $config->{hotkey_beep} |
83
|
|
|
|
|
|
|
$eager $mode->{eager} |
84
|
|
|
|
|
|
|
$alias $config->{alias} |
85
|
|
|
|
|
|
|
$hotkeys $config->{hotkeys} |
86
|
|
|
|
|
|
|
$new_track_rw $config->{new_track_rw} |
87
|
|
|
|
|
|
|
$hotkeys_always $config->{hotkeys_always} |
88
|
|
|
|
|
|
|
$use_pager $config->{use_pager} |
89
|
|
|
|
|
|
|
$use_placeholders $config->{use_placeholders} |
90
|
|
|
|
|
|
|
$edit_playback_end_margin $config->{edit_playback_end_margin} |
91
|
|
|
|
|
|
|
$edit_crossfade_time $config->{edit_crossfade_time} |
92
|
|
|
|
|
|
|
$default_fade_length $config->{engine_fade_default_length} |
93
|
|
|
|
|
|
|
$fade_time $config->{engine_fade_length_on_start_stop} |
94
|
|
|
|
|
|
|
%mute_level $config->{mute_level} |
95
|
|
|
|
|
|
|
%fade_out_level $config->{fade_out_level} |
96
|
|
|
|
|
|
|
$fade_resolution $config->{fade_resolution} |
97
|
|
|
|
|
|
|
%unity_level $config->{unity_level} |
98
|
|
|
|
|
|
|
$enforce_channel_bounds $config->{enforce_channel_bounds} |
99
|
|
|
|
|
|
|
$midi_input_dev $midi->{input_dev} |
100
|
|
|
|
|
|
|
$midi_output_dev $midi->{output_dev} |
101
|
|
|
|
|
|
|
$controller_ports $midi->{controller_ports} |
102
|
|
|
|
|
|
|
$midi_inputs $midi->{inputs} |
103
|
|
|
|
|
|
|
$osc_listener_port $config->{osc_listener_port} |
104
|
|
|
|
|
|
|
$osc_reply_port $config->{osc_reply_port} |
105
|
|
|
|
|
|
|
$remote_control_port $config->{remote_control_port} |
106
|
|
|
|
|
|
|
$engines $config->{engines} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
) }; |
109
|
0
|
|
|
0
|
0
|
0
|
sub var_map { $var_map } # to allow outside access while keeping |
110
|
|
|
|
|
|
|
# working lexical |
111
|
0
|
|
|
0
|
0
|
0
|
sub config_vars { grep {$_ ne '**' } keys %$var_map } |
|
0
|
|
|
|
|
0
|
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub assign { |
114
|
|
|
|
|
|
|
# Usage: |
115
|
|
|
|
|
|
|
# assign ( |
116
|
|
|
|
|
|
|
# data => $ref, |
117
|
|
|
|
|
|
|
# vars => \@vars, |
118
|
|
|
|
|
|
|
# var_map => 1, |
119
|
|
|
|
|
|
|
# class => $class |
120
|
|
|
|
|
|
|
# ); |
121
|
|
|
|
|
|
|
|
122
|
4
|
|
|
4
|
0
|
7636
|
logsub("&assign"); |
123
|
|
|
|
|
|
|
|
124
|
4
|
|
|
|
|
42
|
my %h = @_; # parameters appear in %h |
125
|
4
|
|
|
|
|
6
|
my $class; |
126
|
4
|
50
|
|
|
|
15
|
logpkg(__FILE__,__LINE__,'logcarp',"didn't expect scalar here") if ref $h{data} eq 'SCALAR'; |
127
|
4
|
50
|
|
|
|
10
|
logpkg(__FILE__,__LINE__,'logcarp',"didn't expect code here") if ref $h{data} eq 'CODE'; |
128
|
|
|
|
|
|
|
# print "data: $h{data}, ", ref $h{data}, $/; |
129
|
|
|
|
|
|
|
|
130
|
4
|
50
|
|
|
|
23
|
if ( ref $h{data} !~ /^(HASH|ARRAY|CODE|GLOB|HANDLE|FORMAT)$/){ |
131
|
|
|
|
|
|
|
# we guess object |
132
|
0
|
|
|
|
|
0
|
$class = ref $h{data}; |
133
|
0
|
|
|
|
|
0
|
logpkg(__FILE__,__LINE__,'debug',"I found an object of class $class"); |
134
|
|
|
|
|
|
|
} |
135
|
4
|
|
|
|
|
9
|
$class = $h{class}; |
136
|
4
|
100
|
|
|
|
14
|
$class .= "::" unless $class =~ /::$/; # SKIP_PREPROC |
137
|
4
|
|
|
|
|
6
|
my @vars = @{ $h{vars} }; |
|
4
|
|
|
|
|
11
|
|
138
|
4
|
|
|
|
|
9
|
my $ref = $h{data}; |
139
|
4
|
|
|
|
|
6
|
my $type = ref $ref; |
140
|
4
|
|
|
|
|
28
|
logpkg(__FILE__,__LINE__,'debug',<
|
141
|
|
|
|
|
|
|
data type: $type |
142
|
|
|
|
|
|
|
data: $ref |
143
|
|
|
|
|
|
|
class: $class |
144
|
|
|
|
|
|
|
vars: @vars |
145
|
|
|
|
|
|
|
ASSIGN |
146
|
|
|
|
|
|
|
#logpkg(__FILE__,__LINE__,'debug',sub{json_out($ref)}); |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# index what sigil an identifier should get |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# we need to create search-and-replace strings |
151
|
|
|
|
|
|
|
# sigil-less old_identifier |
152
|
4
|
|
|
|
|
31
|
my %sigil; |
153
|
|
|
|
|
|
|
my %ident; |
154
|
|
|
|
|
|
|
map { |
155
|
4
|
|
|
|
|
8
|
my $oldvar = my $var = $_; |
|
16
|
|
|
|
|
27
|
|
156
|
16
|
|
|
|
|
52
|
my ($dummy, $old_identifier) = /^([\$\%\@])([\-\>\w:\[\]{}]+)$/; |
157
|
16
|
0
|
33
|
|
|
39
|
$var = $var_map->{$var} if $h{var_map} and $var_map->{$var}; |
158
|
|
|
|
|
|
|
|
159
|
16
|
50
|
|
|
|
34
|
logpkg(__FILE__,__LINE__,'debug',"oldvar: $oldvar, newvar: $var") unless $oldvar eq $var; |
160
|
16
|
|
|
|
|
46
|
my ($sigil, $identifier) = $var =~ /([\$\%\@])(\S+)/; |
161
|
16
|
|
|
|
|
31
|
$sigil{$old_identifier} = $sigil; |
162
|
16
|
|
|
|
|
43
|
$ident{$old_identifier} = $identifier; |
163
|
|
|
|
|
|
|
} @vars; |
164
|
|
|
|
|
|
|
|
165
|
4
|
|
|
0
|
|
25
|
logpkg(__FILE__,__LINE__,'debug',sub{"SIGIL\n". json_out(\%sigil)}); |
|
0
|
|
|
|
|
0
|
|
166
|
|
|
|
|
|
|
#%ident = map{ @$_ } grep{ $_->[0] ne $_->[1] } map{ [$_, $ident{$_}] } keys %ident; |
167
|
4
|
|
|
|
|
49
|
my %ident2 = %ident; |
168
|
4
|
|
|
|
|
17
|
while ( my ($k,$v) = each %ident2) |
169
|
|
|
|
|
|
|
{ |
170
|
16
|
50
|
|
|
|
66
|
delete $ident2{$k} if $k eq $v |
171
|
|
|
|
|
|
|
} |
172
|
4
|
|
|
0
|
|
20
|
logpkg(__FILE__,__LINE__,'debug',sub{"IDENT\n". json_out(\%ident2)}); |
|
0
|
|
|
|
|
0
|
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
#print join " ", "Variables:\n", @vars, $/ ; |
175
|
4
|
50
|
|
|
|
46
|
croak "expected hash" if ref $ref !~ /HASH/; |
176
|
4
|
|
|
|
|
5
|
my @keys = keys %{ $ref }; # identifiers, *no* sigils |
|
4
|
|
|
|
|
15
|
|
177
|
4
|
|
|
0
|
|
20
|
logpkg(__FILE__,__LINE__,'debug',sub{ join " ","found keys: ", keys %{ $ref },"\n---\n"}); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
178
|
|
|
|
|
|
|
map{ |
179
|
4
|
|
|
|
|
37
|
my $eval; |
|
16
|
|
|
|
|
20
|
|
180
|
16
|
|
|
|
|
25
|
my $key = $_; |
181
|
16
|
|
|
|
|
22
|
chomp $key; |
182
|
16
|
|
|
|
|
26
|
my $sigil = $sigil{$key}; |
183
|
|
|
|
|
|
|
my $full_class_path = |
184
|
16
|
50
|
|
|
|
47
|
$sigil . ($key =~/:\:/ ? '': $class) . $ident{$key}; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# use the supplied class unless the variable name |
187
|
|
|
|
|
|
|
# contains \:\: |
188
|
|
|
|
|
|
|
|
189
|
16
|
|
|
|
|
64
|
logpkg(__FILE__,__LINE__,'debug',<
|
190
|
|
|
|
|
|
|
key: $key |
191
|
|
|
|
|
|
|
sigil: $sigil |
192
|
|
|
|
|
|
|
full_class_path: $full_class_path |
193
|
|
|
|
|
|
|
DEBUG |
194
|
16
|
50
|
|
|
|
132
|
if ( ! $sigil ){ |
195
|
|
|
|
|
|
|
logpkg(__FILE__,__LINE__,'debug',sub{ |
196
|
0
|
|
|
0
|
|
0
|
"didn't find a match for $key in ", join " ", @vars, $/; |
197
|
0
|
|
|
|
|
0
|
}); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
else |
200
|
|
|
|
|
|
|
{ |
201
|
|
|
|
|
|
|
|
202
|
16
|
|
|
|
|
24
|
$eval .= $full_class_path; |
203
|
16
|
|
|
|
|
21
|
$eval .= q( = ); |
204
|
|
|
|
|
|
|
|
205
|
16
|
|
|
|
|
24
|
my $val = $ref->{$key}; |
206
|
|
|
|
|
|
|
|
207
|
16
|
100
|
66
|
|
|
87
|
if (! ref $val or ref $val eq 'SCALAR') # scalar assignment |
|
|
50
|
66
|
|
|
|
|
208
|
|
|
|
|
|
|
{ |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# extract value |
211
|
|
|
|
|
|
|
|
212
|
8
|
100
|
|
|
|
16
|
if ($val) { # if we have something, |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# dereference it if needed |
215
|
|
|
|
|
|
|
|
216
|
7
|
50
|
|
|
|
17
|
ref $val eq q(SCALAR) and $val = $$val; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# quoting for non-numerical |
219
|
|
|
|
|
|
|
|
220
|
7
|
100
|
|
|
|
29
|
$val = qq("$val") unless $val =~ /^[\d\.,+\-e]+$/ |
221
|
|
|
|
|
|
|
|
222
|
1
|
|
|
|
|
3
|
} else { $val = q(undef) }; # or set as undefined |
223
|
|
|
|
|
|
|
|
224
|
8
|
|
|
|
|
9
|
$eval .= $val; # append to assignment |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
elsif ( ref $val eq 'ARRAY' or ref $val eq 'HASH') |
228
|
|
|
|
|
|
|
{ |
229
|
8
|
50
|
|
|
|
18
|
if ($sigil eq '$') # assign reference |
230
|
|
|
|
|
|
|
{ |
231
|
0
|
|
|
|
|
0
|
$eval .= q($val) ; |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
else # dereference and assign |
234
|
|
|
|
|
|
|
{ |
235
|
8
|
|
|
|
|
12
|
$eval .= qq($sigil) ; |
236
|
8
|
|
|
|
|
12
|
$eval .= q({$val}) ; |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
} |
239
|
0
|
|
|
|
|
0
|
else { die "unsupported assignment: ".ref $val } |
240
|
16
|
|
|
|
|
53
|
logpkg(__FILE__,__LINE__,'debug',"eval string: $eval"); |
241
|
16
|
|
|
|
|
1121
|
eval($eval); |
242
|
16
|
50
|
|
|
|
105
|
logpkg(__FILE__,__LINE__,'logcarp',"failed to eval $eval: $@") if $@; |
243
|
|
|
|
|
|
|
} # end if sigil{key} |
244
|
|
|
|
|
|
|
} @keys; |
245
|
4
|
|
|
|
|
25
|
1; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# assign_singletons() assigns hash key/value entries |
250
|
|
|
|
|
|
|
# rather than a top-level hash reference to avoid |
251
|
|
|
|
|
|
|
# clobbering singleton key/value pairs initialized |
252
|
|
|
|
|
|
|
# elsewhere. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
my @singleton_idents = map{ /^.(.+)/; $1 } # remove leading '$' sigil |
255
|
|
|
|
|
|
|
qw( |
256
|
|
|
|
|
|
|
$ui |
257
|
|
|
|
|
|
|
$mode |
258
|
|
|
|
|
|
|
$file |
259
|
|
|
|
|
|
|
$graph |
260
|
|
|
|
|
|
|
$setup |
261
|
|
|
|
|
|
|
$config |
262
|
|
|
|
|
|
|
$jack |
263
|
|
|
|
|
|
|
$fx |
264
|
|
|
|
|
|
|
$fx_cache |
265
|
|
|
|
|
|
|
$text |
266
|
|
|
|
|
|
|
$gui |
267
|
|
|
|
|
|
|
$midi |
268
|
|
|
|
|
|
|
$help |
269
|
|
|
|
|
|
|
$mastering |
270
|
|
|
|
|
|
|
$project |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
); |
273
|
|
|
|
|
|
|
sub assign_singletons { |
274
|
0
|
|
|
0
|
0
|
0
|
logsub('&assign_singletons'); |
275
|
0
|
|
|
|
|
0
|
my $ref = shift; |
276
|
0
|
0
|
|
|
|
0
|
my $data = $ref->{data} or die "expected data got undefined"; |
277
|
0
|
|
0
|
|
|
0
|
my $class = $ref->{class} // 'Audio::Nama'; |
278
|
0
|
|
|
|
|
0
|
$class .= '::'; # SKIP_PREPROC |
279
|
|
|
|
|
|
|
map { |
280
|
0
|
|
|
|
|
0
|
my $ident = $_; |
|
0
|
|
|
|
|
0
|
|
281
|
0
|
0
|
|
|
|
0
|
if( defined $data->{$ident}){ |
282
|
0
|
|
|
|
|
0
|
my $type = ref $data->{$ident}; |
283
|
0
|
0
|
|
|
|
0
|
$type eq 'HASH' or die "$ident: expect hash, got $type"; |
284
|
|
|
|
|
|
|
map{ |
285
|
0
|
|
|
|
|
0
|
my $key = $_; |
286
|
0
|
|
|
|
|
0
|
my $cmd = join '', |
287
|
|
|
|
|
|
|
'$', |
288
|
|
|
|
|
|
|
$class, |
289
|
|
|
|
|
|
|
$ident, |
290
|
|
|
|
|
|
|
'->{', |
291
|
|
|
|
|
|
|
$key, |
292
|
|
|
|
|
|
|
'}', |
293
|
|
|
|
|
|
|
' = $data->{$ident}->{$key}'; |
294
|
0
|
|
|
|
|
0
|
logpkg(__FILE__,__LINE__,'debug',"eval: $cmd"); |
295
|
0
|
|
|
|
|
0
|
eval $cmd; |
296
|
0
|
0
|
|
|
|
0
|
logpkg(__FILE__,__LINE__,'logcarp',"error during eval: $@") if $@; |
297
|
0
|
|
|
|
|
0
|
} keys %{ $data->{$ident} } |
|
0
|
|
|
|
|
0
|
|
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
} @singleton_idents; # list of "singleton" variables |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
our %suffix = |
303
|
|
|
|
|
|
|
( |
304
|
|
|
|
|
|
|
storable => "bin", |
305
|
|
|
|
|
|
|
perl => "pl", |
306
|
|
|
|
|
|
|
json => "json", |
307
|
|
|
|
|
|
|
yaml => "yml", |
308
|
|
|
|
|
|
|
); |
309
|
|
|
|
|
|
|
our %dispatch = |
310
|
|
|
|
|
|
|
( storable => sub { my($ref, $path) = @_; nstore($ref, $path) }, |
311
|
|
|
|
|
|
|
perl => sub { my($ref, $path) = @_; write_file($path, Dumper $ref) }, |
312
|
|
|
|
|
|
|
yaml => sub { my($ref, $path) = @_; write_file($path, json_out($ref))}, |
313
|
|
|
|
|
|
|
json => sub { my($ref, $path) = @_; write_file($path, json_out($ref))}, |
314
|
|
|
|
|
|
|
); |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub serialize_and_write { |
317
|
0
|
|
|
0
|
0
|
0
|
my ($ref, $path, $format) = @_; |
318
|
0
|
0
|
|
|
|
0
|
$path .= ".$suffix{$format}" unless $path =~ /\.$suffix{$format}$/; |
319
|
0
|
|
|
|
|
0
|
$dispatch{$format}->($ref, $path) |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
{ |
324
|
|
|
|
|
|
|
my $parse_re = # initialize only once |
325
|
|
|
|
|
|
|
qr/ ^ # beginning anchor |
326
|
|
|
|
|
|
|
([\%\@\$]) # first character, sigil |
327
|
|
|
|
|
|
|
([\w:]+) # identifier, possibly perl namespace |
328
|
|
|
|
|
|
|
(?:->\{(\w+)})? # optional hash key for new hash-singleton vars |
329
|
|
|
|
|
|
|
$ # end anchor |
330
|
|
|
|
|
|
|
/x; |
331
|
|
|
|
|
|
|
sub serialize { |
332
|
3
|
|
|
3
|
0
|
20
|
logsub("&serialize"); |
333
|
|
|
|
|
|
|
|
334
|
3
|
|
|
|
|
27
|
my %h = @_; |
335
|
3
|
|
|
|
|
6
|
my @vars = @{ $h{vars} }; |
|
3
|
|
|
|
|
11
|
|
336
|
3
|
|
|
|
|
4
|
my $class = $h{class}; |
337
|
3
|
|
|
|
|
6
|
my $file = $h{file}; |
338
|
3
|
|
50
|
|
|
15
|
my $format = $h{format} // 'perl'; # default to Data::Dumper::Concise |
339
|
|
|
|
|
|
|
|
340
|
3
|
|
50
|
|
|
8
|
$class //= "Audio::Nama"; |
341
|
3
|
100
|
|
|
|
14
|
$class =~ /::$/ or $class .= '::'; # SKIP_PREPROC |
342
|
3
|
|
|
|
|
47
|
logpkg(__FILE__,__LINE__,'debug',"file: $file, class: $class\nvariables...@vars"); |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
# first we marshall data into %state |
345
|
|
|
|
|
|
|
|
346
|
3
|
|
|
|
|
22
|
my %state; |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
map{ |
349
|
3
|
|
|
|
|
7
|
my ($sigil, $identifier, $key) = /$parse_re/; |
|
12
|
|
|
|
|
77
|
|
350
|
|
|
|
|
|
|
|
351
|
12
|
|
|
|
|
51
|
logpkg(__FILE__,__LINE__,'debug',"found sigil: $sigil, ident: $identifier, key: $key"); |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
# note: for YAML::Reader/Writer all scalars must contain values, not references |
354
|
|
|
|
|
|
|
# more YAML adjustments |
355
|
|
|
|
|
|
|
# restore will break if a null field is not converted to '~' |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
#my $value = q(\\) |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# directly assign scalar, but take hash/array references |
360
|
|
|
|
|
|
|
# $state{ident} = $scalar |
361
|
|
|
|
|
|
|
# $state{ident} = \%hash |
362
|
|
|
|
|
|
|
# $state{ident} = \@array |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
# in case $key is provided |
365
|
|
|
|
|
|
|
# $state{ident}->{$key} = $singleton->{$key}; |
366
|
|
|
|
|
|
|
# |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
12
|
100
|
|
|
|
132
|
my $value = ($sigil ne q($) ? q(\\) : q() ) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
. $sigil |
372
|
|
|
|
|
|
|
. ($identifier =~ /:/ ? '' : $class) |
373
|
|
|
|
|
|
|
. $identifier |
374
|
|
|
|
|
|
|
. ($key ? qq(->{$key}) : q()); |
375
|
|
|
|
|
|
|
|
376
|
12
|
|
|
|
|
40
|
logpkg(__FILE__,__LINE__,'debug',"value: $value"); |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
|
379
|
12
|
50
|
|
|
|
109
|
my $eval_string = q($state{') |
380
|
|
|
|
|
|
|
. $identifier |
381
|
|
|
|
|
|
|
. q('}) |
382
|
|
|
|
|
|
|
. ($key ? qq(->{$key}) : q() ) |
383
|
|
|
|
|
|
|
. q( = ) |
384
|
|
|
|
|
|
|
. $value; |
385
|
|
|
|
|
|
|
|
386
|
12
|
50
|
|
|
|
32
|
if ($identifier){ |
387
|
12
|
|
|
|
|
41
|
logpkg(__FILE__,__LINE__,'debug',"attempting to eval $eval_string"); |
388
|
12
|
|
|
|
|
765
|
eval($eval_string); |
389
|
12
|
50
|
|
|
|
91
|
logpkg(__FILE__,__LINE__,'error', "eval failed ($@)") if $@; |
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
} @vars; |
392
|
3
|
|
|
0
|
|
16
|
logpkg(__FILE__,__LINE__,'debug',sub{join $/,'\%state', Dumper \%state}); |
|
0
|
|
|
|
|
0
|
|
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
# YAML out for screen dumps |
395
|
3
|
50
|
|
|
|
39
|
return( json_out(\%state) ) unless $h{file}; |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# now we serialize %state |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
|
|
0
|
my $path = $h{file}; |
400
|
|
|
|
|
|
|
|
401
|
0
|
|
|
|
|
0
|
serialize_and_write(\%state, $path, $format); |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub json_out { |
406
|
3
|
|
|
3
|
0
|
9
|
logsub("&json_out"); |
407
|
3
|
|
|
|
|
23
|
my $data_ref = shift; |
408
|
3
|
|
|
|
|
6
|
my $type = ref $data_ref; |
409
|
3
|
50
|
|
|
|
19
|
croak "attempting to code wrong data type: $type" |
410
|
|
|
|
|
|
|
if $type !~ /HASH|ARRAY/; |
411
|
3
|
|
|
|
|
54
|
$to_json->encode($data_ref); |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
sub json_in { |
415
|
0
|
|
|
0
|
0
|
|
logsub("&json_in"); |
416
|
0
|
|
|
|
|
|
my $json = shift; |
417
|
0
|
|
|
|
|
|
my $data_ref = decode_json($json); |
418
|
0
|
|
|
|
|
|
$data_ref |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub yaml_in { |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
# logsub("&yaml_in"); |
424
|
0
|
|
|
0
|
0
|
|
my $input = shift; |
425
|
|
|
|
|
|
|
my $yaml = $input =~ /\n/ # check whether file or text |
426
|
|
|
|
|
|
|
? $input # yaml text |
427
|
|
|
|
|
|
|
: do |
428
|
0
|
0
|
|
|
|
|
{ |
429
|
0
|
|
|
|
|
|
logpkg(__FILE__,__LINE__,'debug',"filename: $input"); |
430
|
0
|
|
|
|
|
|
read_file($input); # file name |
431
|
|
|
|
|
|
|
}; |
432
|
0
|
0
|
|
|
|
|
if ($yaml =~ /\t/){ |
433
|
0
|
|
|
|
|
|
croak "YAML file: $input contains illegal TAB character."; |
434
|
|
|
|
|
|
|
} |
435
|
0
|
|
|
|
|
|
$yaml =~ s/^\n+// ; # remove leading newline at start of file |
436
|
0
|
|
|
|
|
|
$yaml =~ s/\n*$/\n/; # make sure file ends with newline |
437
|
0
|
|
|
|
|
|
my $y = YAML::Tiny->read_string($yaml); |
438
|
0
|
0
|
|
|
|
|
Audio::Nama::throw("YAML::Tiny read error: $YAML::Tiny::errstr\n") if $YAML::Tiny::errstr; |
439
|
0
|
|
|
|
|
|
$y->[0]; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
sub quote_yaml_scalars { |
443
|
0
|
|
|
0
|
0
|
|
my $yaml = shift; |
444
|
0
|
|
|
|
|
|
my @modified; |
445
|
|
|
|
|
|
|
map |
446
|
|
|
|
|
|
|
{ |
447
|
0
|
|
|
|
|
|
chomp; |
|
0
|
|
|
|
|
|
|
448
|
0
|
0
|
|
|
|
|
if( /^(?(\s*\w+: )|(\s+- ))(?.+)$/ ){ |
449
|
5
|
|
|
5
|
|
4018
|
my($beg,$end) = ($+{beg}, $+{end}); |
|
5
|
|
|
|
|
2161
|
|
|
5
|
|
|
|
|
1313
|
|
|
0
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
# quote if contains colon and not quoted |
451
|
0
|
0
|
0
|
|
|
|
if ($end =~ /:\s/ and $end !~ /^('|")/ ){ |
452
|
0
|
|
|
|
|
|
$end =~ s(')(\\')g; # escape existing single quotes |
453
|
0
|
|
|
|
|
|
$end = qq('$end') } # single-quote string |
454
|
0
|
|
|
|
|
|
push @modified, "$beg$end\n"; |
455
|
|
|
|
|
|
|
} |
456
|
0
|
|
|
|
|
|
else { push @modified, "$_\n" } |
457
|
|
|
|
|
|
|
} split "\n", $yaml; |
458
|
0
|
|
|
|
|
|
join "", @modified; |
459
|
|
|
|
|
|
|
} |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
1; |