| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Audio::Nama::Assign; |
|
2
|
5
|
|
|
5
|
|
22502
|
use Modern::Perl; |
|
|
5
|
|
|
|
|
13306
|
|
|
|
5
|
|
|
|
|
32
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = 1.0; |
|
4
|
5
|
|
|
5
|
|
737
|
use 5.008; |
|
|
5
|
|
|
|
|
17
|
|
|
5
|
5
|
|
|
5
|
|
25
|
use feature 'state'; |
|
|
5
|
|
|
|
|
9
|
|
|
|
5
|
|
|
|
|
297
|
|
|
6
|
5
|
|
|
5
|
|
59
|
use strict; |
|
|
5
|
|
|
|
|
14
|
|
|
|
5
|
|
|
|
|
102
|
|
|
7
|
5
|
|
|
5
|
|
50
|
use warnings; |
|
|
5
|
|
|
|
|
8
|
|
|
|
5
|
|
|
|
|
171
|
|
|
8
|
5
|
|
|
5
|
|
50
|
no warnings q(uninitialized); |
|
|
5
|
|
|
|
|
12
|
|
|
|
5
|
|
|
|
|
218
|
|
|
9
|
5
|
|
|
5
|
|
26
|
use Carp qw(carp confess croak cluck); |
|
|
5
|
|
|
|
|
12
|
|
|
|
5
|
|
|
|
|
366
|
|
|
10
|
5
|
|
|
5
|
|
4730
|
use YAML::Tiny; |
|
|
5
|
|
|
|
|
29996
|
|
|
|
5
|
|
|
|
|
323
|
|
|
11
|
5
|
|
|
5
|
|
4896
|
use File::Slurp; |
|
|
5
|
|
|
|
|
70681
|
|
|
|
5
|
|
|
|
|
389
|
|
|
12
|
5
|
|
|
5
|
|
4351
|
use File::HomeDir; |
|
|
5
|
|
|
|
|
1517594
|
|
|
|
5
|
|
|
|
|
359
|
|
|
13
|
5
|
|
|
5
|
|
2665
|
use Audio::Nama::Log qw(logsub logpkg); |
|
|
5
|
|
|
|
|
17
|
|
|
|
5
|
|
|
|
|
354
|
|
|
14
|
5
|
|
|
5
|
|
10625
|
use Storable qw(nstore retrieve); |
|
|
5
|
|
|
|
|
21830
|
|
|
|
5
|
|
|
|
|
427
|
|
|
15
|
5
|
|
|
5
|
|
6468
|
use JSON::XS; |
|
|
5
|
|
|
|
|
42989
|
|
|
|
5
|
|
|
|
|
326
|
|
|
16
|
5
|
|
|
5
|
|
3228
|
use Data::Dumper::Concise; |
|
|
5
|
|
|
|
|
27009
|
|
|
|
5
|
|
|
|
|
903
|
|
|
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
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
16024
|
|
|
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
|
7589
|
logsub("&assign"); |
|
123
|
|
|
|
|
|
|
|
|
124
|
4
|
|
|
|
|
41
|
my %h = @_; # parameters appear in %h |
|
125
|
4
|
|
|
|
|
7
|
my $class; |
|
126
|
4
|
50
|
|
|
|
13
|
logpkg(__FILE__,__LINE__,'logcarp',"didn't expect scalar here") if ref $h{data} eq 'SCALAR'; |
|
127
|
4
|
50
|
|
|
|
11
|
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
|
|
|
|
21
|
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
|
|
|
|
|
7
|
my @vars = @{ $h{vars} }; |
|
|
4
|
|
|
|
|
13
|
|
|
138
|
4
|
|
|
|
|
8
|
my $ref = $h{data}; |
|
139
|
4
|
|
|
|
|
7
|
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
|
|
|
|
|
30
|
my %sigil; |
|
153
|
|
|
|
|
|
|
my %ident; |
|
154
|
|
|
|
|
|
|
map { |
|
155
|
4
|
|
|
|
|
8
|
my $oldvar = my $var = $_; |
|
|
16
|
|
|
|
|
26
|
|
|
156
|
16
|
|
|
|
|
49
|
my ($dummy, $old_identifier) = /^([\$\%\@])([\-\>\w:\[\]{}]+)$/; |
|
157
|
16
|
0
|
33
|
|
|
41
|
$var = $var_map->{$var} if $h{var_map} and $var_map->{$var}; |
|
158
|
|
|
|
|
|
|
|
|
159
|
16
|
50
|
|
|
|
27
|
logpkg(__FILE__,__LINE__,'debug',"oldvar: $oldvar, newvar: $var") unless $oldvar eq $var; |
|
160
|
16
|
|
|
|
|
47
|
my ($sigil, $identifier) = $var =~ /([\$\%\@])(\S+)/; |
|
161
|
16
|
|
|
|
|
32
|
$sigil{$old_identifier} = $sigil; |
|
162
|
16
|
|
|
|
|
38
|
$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
|
|
|
|
|
47
|
my %ident2 = %ident; |
|
168
|
4
|
|
|
|
|
18
|
while ( my ($k,$v) = each %ident2) |
|
169
|
|
|
|
|
|
|
{ |
|
170
|
16
|
50
|
|
|
|
67
|
delete $ident2{$k} if $k eq $v |
|
171
|
|
|
|
|
|
|
} |
|
172
|
4
|
|
|
0
|
|
21
|
logpkg(__FILE__,__LINE__,'debug',sub{"IDENT\n". json_out(\%ident2)}); |
|
|
0
|
|
|
|
|
0
|
|
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
#print join " ", "Variables:\n", @vars, $/ ; |
|
175
|
4
|
50
|
|
|
|
45
|
croak "expected hash" if ref $ref !~ /HASH/; |
|
176
|
4
|
|
|
|
|
6
|
my @keys = keys %{ $ref }; # identifiers, *no* sigils |
|
|
4
|
|
|
|
|
16
|
|
|
177
|
4
|
|
|
0
|
|
19
|
logpkg(__FILE__,__LINE__,'debug',sub{ join " ","found keys: ", keys %{ $ref },"\n---\n"}); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
178
|
|
|
|
|
|
|
map{ |
|
179
|
4
|
|
|
|
|
34
|
my $eval; |
|
|
16
|
|
|
|
|
21
|
|
|
180
|
16
|
|
|
|
|
20
|
my $key = $_; |
|
181
|
16
|
|
|
|
|
24
|
chomp $key; |
|
182
|
16
|
|
|
|
|
22
|
my $sigil = $sigil{$key}; |
|
183
|
|
|
|
|
|
|
my $full_class_path = |
|
184
|
16
|
50
|
|
|
|
49
|
$sigil . ($key =~/:\:/ ? '': $class) . $ident{$key}; |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# use the supplied class unless the variable name |
|
187
|
|
|
|
|
|
|
# contains \:\: |
|
188
|
|
|
|
|
|
|
|
|
189
|
16
|
|
|
|
|
61
|
logpkg(__FILE__,__LINE__,'debug',<
|
|
190
|
|
|
|
|
|
|
key: $key |
|
191
|
|
|
|
|
|
|
sigil: $sigil |
|
192
|
|
|
|
|
|
|
full_class_path: $full_class_path |
|
193
|
|
|
|
|
|
|
DEBUG |
|
194
|
16
|
50
|
|
|
|
128
|
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
|
|
|
|
|
20
|
$eval .= $full_class_path; |
|
203
|
16
|
|
|
|
|
18
|
$eval .= q( = ); |
|
204
|
|
|
|
|
|
|
|
|
205
|
16
|
|
|
|
|
26
|
my $val = $ref->{$key}; |
|
206
|
|
|
|
|
|
|
|
|
207
|
16
|
100
|
66
|
|
|
86
|
if (! ref $val or ref $val eq 'SCALAR') # scalar assignment |
|
|
|
50
|
66
|
|
|
|
|
|
208
|
|
|
|
|
|
|
{ |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# extract value |
|
211
|
|
|
|
|
|
|
|
|
212
|
8
|
100
|
|
|
|
15
|
if ($val) { # if we have something, |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# dereference it if needed |
|
215
|
|
|
|
|
|
|
|
|
216
|
7
|
50
|
|
|
|
15
|
ref $val eq q(SCALAR) and $val = $$val; |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# quoting for non-numerical |
|
219
|
|
|
|
|
|
|
|
|
220
|
7
|
100
|
|
|
|
30
|
$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
|
|
|
|
16
|
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
|
|
|
|
|
1074
|
eval($eval); |
|
242
|
16
|
50
|
|
|
|
99
|
logpkg(__FILE__,__LINE__,'logcarp',"failed to eval $eval: $@") if $@; |
|
243
|
|
|
|
|
|
|
} # end if sigil{key} |
|
244
|
|
|
|
|
|
|
} @keys; |
|
245
|
4
|
|
|
|
|
23
|
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
|
17
|
logsub("&serialize"); |
|
333
|
|
|
|
|
|
|
|
|
334
|
3
|
|
|
|
|
26
|
my %h = @_; |
|
335
|
3
|
|
|
|
|
4
|
my @vars = @{ $h{vars} }; |
|
|
3
|
|
|
|
|
10
|
|
|
336
|
3
|
|
|
|
|
6
|
my $class = $h{class}; |
|
337
|
3
|
|
|
|
|
5
|
my $file = $h{file}; |
|
338
|
3
|
|
50
|
|
|
13
|
my $format = $h{format} // 'perl'; # default to Data::Dumper::Concise |
|
339
|
|
|
|
|
|
|
|
|
340
|
3
|
|
50
|
|
|
7
|
$class //= "Audio::Nama"; |
|
341
|
3
|
100
|
|
|
|
12
|
$class =~ /::$/ or $class .= '::'; # SKIP_PREPROC |
|
342
|
3
|
|
|
|
|
45
|
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
|
|
|
|
|
5
|
my ($sigil, $identifier, $key) = /$parse_re/; |
|
|
12
|
|
|
|
|
74
|
|
|
350
|
|
|
|
|
|
|
|
|
351
|
12
|
|
|
|
|
49
|
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
|
|
|
|
124
|
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
|
|
|
|
|
38
|
logpkg(__FILE__,__LINE__,'debug',"value: $value"); |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
|
|
379
|
12
|
50
|
|
|
|
101
|
my $eval_string = q($state{') |
|
380
|
|
|
|
|
|
|
. $identifier |
|
381
|
|
|
|
|
|
|
. q('}) |
|
382
|
|
|
|
|
|
|
. ($key ? qq(->{$key}) : q() ) |
|
383
|
|
|
|
|
|
|
. q( = ) |
|
384
|
|
|
|
|
|
|
. $value; |
|
385
|
|
|
|
|
|
|
|
|
386
|
12
|
50
|
|
|
|
30
|
if ($identifier){ |
|
387
|
12
|
|
|
|
|
34
|
logpkg(__FILE__,__LINE__,'debug',"attempting to eval $eval_string"); |
|
388
|
12
|
|
|
|
|
836
|
eval($eval_string); |
|
389
|
12
|
50
|
|
|
|
86
|
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
|
7
|
logsub("&json_out"); |
|
407
|
3
|
|
|
|
|
22
|
my $data_ref = shift; |
|
408
|
3
|
|
|
|
|
6
|
my $type = ref $data_ref; |
|
409
|
3
|
50
|
|
|
|
18
|
croak "attempting to code wrong data type: $type" |
|
410
|
|
|
|
|
|
|
if $type !~ /HASH|ARRAY/; |
|
411
|
3
|
|
|
|
|
51
|
$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
|
|
4402
|
my($beg,$end) = ($+{beg}, $+{end}); |
|
|
5
|
|
|
|
|
2211
|
|
|
|
5
|
|
|
|
|
1281
|
|
|
|
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; |