Procházet zdrojové kódy

Bug 27673: Replace YAML with YAML::XS

From tht YAML pod:

"""
This module has been released to CPAN as YAML::Old, and soon YAML.pm will be changed to just be a frontend interface module for all the various Perl YAML implementation modules, including YAML::Old.

If you want robust and fast YAML processing using the normal Dump/Load API, please consider switching to YAML::XS. It is by far the best Perl module for YAML at this time. It requires that you have a C compiler, since it is written in C.
"""

See also
https://gitlab.com/koha-community/qa-test-tools/-/merge_requests/35

Test plan:
Try some place where YAML::XS is not used and confirm that it works
correctly

QA note: This patch removes some uses of YAML that were not useful

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Joonas Kylmälä <joonas.kylmala@helsinki.fi>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
21.05.x
Jonathan Druart před 3 roky
rodič
revize
46f7239b08
  1. 4
      C4/Auth_with_cas.pm
  2. 4
      C4/Circulation.pm
  3. 4
      C4/Context.pm
  4. 4
      C4/Items.pm
  5. 6
      C4/Record.pm
  6. 3
      C4/Ris.pm
  7. 4
      C4/SMS.pm
  8. 1
      C4/Search.pm
  9. 4
      C4/Utils/DataTables/TablesSettings.pm
  10. 2
      Koha/Filter/MARC/EmbedItems.pm
  11. 1
      Koha/Template/Plugin/TablesSettings.pm
  12. 4
      Koha/Z3950Responder/GenericSession.pm
  13. 8
      about.pl
  14. 6
      acqui/addorderiso2709.pl
  15. 1
      admin/columns_settings.pl
  16. 2
      admin/systempreferences.pl
  17. 3
      circ/pendingreserves.pl
  18. 2
      cpanfile
  19. 1
      misc/maintenance/fix_mysql_constraints.pl
  20. 8
      misc/migration_tools/bulkmarcimport.pl
  21. 12
      misc/migration_tools/ifla/update.pl
  22. 4
      misc/search_tools/export_elasticsearch_mappings.pl
  23. 3
      opac/opac-ISBDdetail.pl
  24. 3
      opac/opac-search.pl
  25. 4
      reports/reserves_stats.pl
  26. 4
      t/Context.t
  27. 2
      t/Installer_PerlModules.t
  28. 2
      t/db_dependent/Budgets.t
  29. 4
      t/db_dependent/Koha/Z3950Responder/GenericSession.t
  30. 1
      t/db_dependent/Koha/Z3950Responder/ZebraSession.t
  31. 8
      t/db_dependent/OAI/Server.t
  32. 2
      t/db_dependent/Search.t
  33. 1
      t/db_dependent/Serials.t
  34. 1
      xt/sample_notices.t
  35. 4
      xt/yaml_valid.pl

4
C4/Auth_with_cas.pm

@ -26,7 +26,7 @@ use Koha::AuthUtils qw(get_script_name);
use Authen::CAS::Client;
use CGI qw ( -utf8 );
use FindBin;
use YAML;
use YAML::XS;
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug);
@ -44,7 +44,7 @@ my $yamlauthfile = C4::Context->config('intranetdir') . "/C4/Auth_cas_servers.ya
# If there's a configuration for multiple cas servers, then we get it
if (multipleAuth()) {
($defaultcasserver, $casservers) = YAML::LoadFile($yamlauthfile);
($defaultcasserver, $casservers) = YAML::XS::LoadFile($yamlauthfile);
$defaultcasserver = $defaultcasserver->{'default'};
} else {
# Else, we fall back to casServerUrl syspref

4
C4/Circulation.pm

@ -21,6 +21,8 @@ package C4::Circulation;
use Modern::Perl;
use DateTime;
use POSIX qw( floor );
use YAML::XS;
use Koha::DateUtils;
use C4::Context;
use C4::Stats;
@ -2014,7 +2016,7 @@ sub AddReturn {
if ($yaml) {
$yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
my $rules;
eval { $rules = YAML::Load($yaml); };
eval { $rules = YAML::XS::Load($yaml); };
if ($@) {
warn "Unable to parse UpdateNotForLoanStatusOnCheckin syspref : $@";
}

4
C4/Context.pm

@ -96,7 +96,7 @@ use Encode;
use File::Spec;
use Module::Load::Conditional qw(can_load);
use POSIX ();
use YAML qw/Load/;
use YAML::XS;
use ZOOM;
use C4::Boolean;
@ -445,7 +445,7 @@ the value cannot be properly decoded as YAML.
sub yaml_preference {
my ( $self, $preference ) = @_;
my $yaml = eval { YAML::Load( $self->preference( $preference ) ); };
my $yaml = eval { YAML::XS::Load( $self->preference( $preference ) ); };
if ($@) {
warn "Unable to parse $preference syspref : $@";
return;

4
C4/Items.pm

@ -57,7 +57,7 @@ use MARC::Record;
use C4::ClassSource;
use C4::Log;
use List::MoreUtils qw(any);
use YAML qw(Load);
use YAML::XS;
use DateTime::Format::MySQL;
use Data::Dumper; # used as part of logging item record changes, not just for
# debugging; so please don't remove this
@ -982,7 +982,7 @@ sub GetHiddenItemnumbers {
$yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
my $hidingrules;
eval {
$hidingrules = YAML::Load($yaml);
$hidingrules = YAML::XS::Load($yaml);
};
if ($@) {
warn "Unable to parse OpacHiddenItems syspref : $@";

6
C4/Record.pm

@ -29,7 +29,7 @@ use Unicode::Normalize; # _entity_encode
use C4::Biblio; #marc2bibtex
use C4::Koha; #marc2csv
use C4::XSLT ();
use YAML; #marcrecords2csv
use YAML::XS; #marcrecords2csv
use Template;
use Text::CSV::Encoded; #marc2csv
use Koha::Items;
@ -415,7 +415,7 @@ sub marc2csv {
my $configfile = "../tools/csv-profiles/$id.yaml";
my ($preprocess, $postprocess, $fieldprocessing);
if (-e $configfile){
($preprocess,$postprocess, $fieldprocessing) = YAML::LoadFile($configfile);
($preprocess,$postprocess, $fieldprocessing) = YAML::XS::LoadFile($configfile);
}
# Preprocessing
@ -800,7 +800,7 @@ sub marc2bibtex {
my $additional_fields;
if ($BibtexExportAdditionalFields) {
$BibtexExportAdditionalFields = "$BibtexExportAdditionalFields\n\n";
$additional_fields = eval { YAML::Load($BibtexExportAdditionalFields); };
$additional_fields = eval { YAML::XS::Load($BibtexExportAdditionalFields); };
if ($@) {
warn "Unable to parse BibtexExportAdditionalFields : $@";
$additional_fields = undef;

3
C4/Ris.pm

@ -63,6 +63,7 @@ package C4::Ris;
use Modern::Perl;
use List::MoreUtils qw/uniq/;
use YAML::XS;
use vars qw(@ISA @EXPORT);
use Koha::SimpleMARC qw(read_field);
@ -119,7 +120,7 @@ sub marc2ris {
my $ris_additional_fields;
if ($RisExportAdditionalFields) {
$RisExportAdditionalFields = "$RisExportAdditionalFields\n\n";
$ris_additional_fields = eval { YAML::Load($RisExportAdditionalFields); };
$ris_additional_fields = eval { YAML::XS::Load($RisExportAdditionalFields); };
if ($@) {
warn "Unable to parse RisExportAdditionalFields : $@";
$ris_additional_fields = undef;

4
C4/SMS.pm

@ -102,8 +102,8 @@ sub send_sms {
my %args;
if ( -f $conf_file ) {
require YAML;
my $conf = YAML::LoadFile( $conf_file );
require YAML::XS;
my $conf = YAML::XS::LoadFile( $conf_file );
%args = map { q{_} . $_ => $conf->{$_} } keys %$conf;
}

1
C4/Search.pm

@ -33,7 +33,6 @@ use Koha::ItemTypes;
use Koha::Libraries;
use Koha::Patrons;
use Koha::RecordProcessor;
use YAML;
use URI::Escape;
use Business::ISBN;
use MARC::Record;

4
C4/Utils/DataTables/TablesSettings.pm

@ -2,7 +2,7 @@ package C4::Utils::DataTables::TablesSettings;
use Modern::Perl;
use List::Util qw( first );
use YAML;
use YAML::XS;
use C4::Context;
use Koha::Database;
use Koha::Caches;
@ -13,7 +13,7 @@ sub get_yaml {
my $yaml = $cache->get_from_cache('TablesSettingsYaml');
unless ($yaml) {
$yaml = eval { YAML::LoadFile($yml_path) };
$yaml = eval { YAML::XS::LoadFile($yml_path) };
warn "ERROR: the yaml file for DT::TablesSettings is not correctly formatted: $@"
if $@;
$cache->set_in_cache( 'TablesSettingsYaml', $yaml, { expiry => 3600 } );

2
Koha/Filter/MARC/EmbedItems.pm

@ -31,7 +31,7 @@ my $biblio = Koha::Biblios->find(
my $opachiddenitems_rules;
eval {
my $yaml = C4::Context->preference('OpacHiddenItems') . "\n\n";
$opachiddenitems_rules = YAML::Load($yaml);
$opachiddenitems_rules = YAML::XS::Load($yaml);
};
my @items = grep { !$_->hidden_in_opac({ rules => $opachiddenitems_rules }) @{$biblio->items};

1
Koha/Template/Plugin/TablesSettings.pm

@ -54,7 +54,6 @@ use Modern::Perl;
use Template::Plugin;
use base qw( Template::Plugin );
use YAML qw( LoadFile );
use JSON qw( to_json );
use C4::Context qw( config );

4
Koha/Z3950Responder/GenericSession.pm

@ -49,8 +49,8 @@ sub start_search {
my ( $self, $args, $num_to_prefetch ) = @_;
if (!defined $self->{'attribute_mappings'}) {
require YAML;
$self->{'attribute_mappings'} = YAML::LoadFile($self->{server}->{config_dir} . 'attribute_mappings.yaml');
require YAML::XS;
$self->{'attribute_mappings'} = YAML::XS::LoadFile($self->{server}->{config_dir} . 'attribute_mappings.yaml');
}
my $database = $args->{DATABASES}->[0];

8
about.pl

@ -33,7 +33,7 @@ use XML::Simple;
use Config;
use Search::Elasticsearch;
use Try::Tiny;
use YAML qw/LoadFile/;
use YAML::XS;
use C4::Output;
use C4::Auth;
@ -429,7 +429,7 @@ my @bad_yaml_prefs;
foreach my $syspref (@yaml_prefs) {
my $yaml = C4::Context->preference( $syspref );
if ( $yaml ) {
eval { YAML::Load( "$yaml\n\n" ); };
eval { YAML::XS::Load( "$yaml\n\n" ); };
if ($@) {
push @bad_yaml_prefs, $syspref;
}
@ -666,7 +666,7 @@ if ( defined C4::Context->config('docdir') ) {
## Release teams
my $teams =
-e "$docdir" . "/teams.yaml"
? LoadFile( "$docdir" . "/teams.yaml" )
? YAML::XS::LoadFile( "$docdir" . "/teams.yaml" )
: {};
my $dev_team = (sort {$b <=> $a} (keys %{$teams->{team}}))[0];
my $short_version = substr($versions{'kohaVersion'},0,5);
@ -678,7 +678,7 @@ $template->param( development_version => $development_version );
## Contributors
my $contributors =
-e "$docdir" . "/contributors.yaml"
? LoadFile( "$docdir" . "/contributors.yaml" )
? YAML::XS::LoadFile( "$docdir" . "/contributors.yaml" )
: {};
for my $version ( sort { $a <=> $b } keys %{$teams->{team}} ) {
for my $role ( keys %{ $teams->{team}->{$version} } ) {

6
acqui/addorderiso2709.pl

@ -24,7 +24,7 @@
use Modern::Perl;
use CGI qw ( -utf8 );
use Carp;
use YAML qw/Load/;
use YAML::XS;
use List::MoreUtils qw/uniq/;
use C4::Context;
@ -678,7 +678,7 @@ sub get_infos_syspref {
my $syspref = C4::Context->preference($syspref_name);
$syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
my $yaml = eval {
YAML::Load($syspref);
YAML::XS::Load($syspref);
};
if ( $@ ) {
warn "Unable to parse $syspref syspref : $@";
@ -724,7 +724,7 @@ sub get_infos_syspref_on_item {
my $syspref = C4::Context->preference($syspref_name);
$syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
my $yaml = eval {
YAML::Load($syspref);
YAML::XS::Load($syspref);
};
if ( $@ ) {
warn "Unable to parse $syspref syspref : $@";

1
admin/columns_settings.pl

@ -2,7 +2,6 @@
use Modern::Perl;
use CGI;
use YAML qw( LoadFile );
use C4::Auth;
use C4::Context;
use C4::Output;

2
admin/systempreferences.pl

@ -50,7 +50,7 @@ use C4::Koha;
use C4::Languages qw(getTranslatedLanguages);
use C4::ClassSource;
use C4::Output;
use YAML::Syck qw( Dump LoadFile );
use YAML::Syck qw( LoadFile );
my %tabsysprefs; #we do no longer need to keep track of a tab per pref (yaml)

3
circ/pendingreserves.pl

@ -21,6 +21,7 @@ use Modern::Perl;
use constant PULL_INTERVAL => 2;
use List::MoreUtils qw( uniq );
use YAML::XS;
use C4::Context;
use C4::Output;
@ -109,7 +110,7 @@ if ( $op eq 'cancel_reserve' and $reserve_id ) {
if ( my $yaml = C4::Context->preference('UpdateItemWhenLostFromHoldList') ) {
$yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
my $assignments;
eval { $assignments = YAML::Load($yaml); };
eval { $assignments = YAML::XS::Load($yaml); };
if ($@) {
warn "Unable to parse UpdateItemWhenLostFromHoldList syspref : $@" if $@;
}

2
cpanfile

@ -129,7 +129,7 @@ requires 'XML::RSS', '1.31';
requires 'XML::SAX::ParserFactory', '1.01';
requires 'XML::SAX::Writer', '0.44';
requires 'XML::Simple', '2.14';
requires 'YAML', '0.71';
requires 'YAML::XS', '0.71';
requires 'YAML::Syck', '0.71';
recommends 'AnyEvent', '5.0';
recommends 'AnyEvent::HTTP', '2.13';

1
misc/maintenance/fix_mysql_constraints.pl

@ -28,7 +28,6 @@ BEGIN {
use Getopt::Long;
use Pod::Usage;
use YAML;
use Try::Tiny;
use Koha::Script;
use C4::Context;

8
misc/migration_tools/bulkmarcimport.pl

@ -26,7 +26,7 @@ use C4::Charset;
use C4::Items;
use C4::MarcModificationTemplates;
use YAML;
use YAML::XS;
use Unicode::Normalize;
use Time::HiRes qw(gettimeofday);
use Getopt::Long;
@ -565,7 +565,7 @@ if ($logfile){
}
if ($yamlfile) {
open my $yamlfileout, q{>}, "$yamlfile" or die "cannot open $yamlfile \n";
print $yamlfileout Dump($yamlhash);
print $yamlfileout YAML::XS::Dump($yamlhash);
}
exit 0;
@ -631,9 +631,9 @@ sub printlog{
sub get_heading_fields{
my $headingfields;
if ($authtypes){
$headingfields=YAML::LoadFile($authtypes);
$headingfields = YAML::XS::LoadFile($authtypes);
$headingfields={C4::Context->preference('marcflavour')=>$headingfields};
$debug && warn YAML::Dump($headingfields);
$debug && warn YAML::XS::Dump($headingfields);
}
unless ($headingfields){
$headingfields=$dbh->selectall_hashref("SELECT auth_tag_to_report, authtypecode from auth_types",'auth_tag_to_report',{Slice=>{}});

12
misc/migration_tools/ifla/update.pl

@ -24,7 +24,7 @@ use File::Basename;
use FindBin qw($Bin);
use Getopt::Long;
use Locale::PO;
use YAML qw(LoadFile);
use YAML::XS;
use utf8;
use Koha::Database;
@ -68,17 +68,17 @@ EOT
exit 0;
}
my $defaults = LoadFile("$Bin/data/defaults.yml");
my $authorised_values = LoadFile("$Bin/data/authorised_values.yml");
my $authtypes = LoadFile("$Bin/data/authtypes.yml");
my $defaults = YAML::XS::LoadFile("$Bin/data/defaults.yml");
my $authorised_values = YAML::XS::LoadFile("$Bin/data/authorised_values.yml");
my $authtypes = YAML::XS::LoadFile("$Bin/data/authtypes.yml");
my @authtags;
my @authsubfields;
for my $authfw (qw(default CLASS CO EXP FAM GENRE_FORM NP NTEXP NTWORK PA PERS PUB SAUTTIT SNC SNG TM TU WORK)) {
my $file = LoadFile("$Bin/data/auth/$authfw.yml");
my $file = YAML::XS::LoadFile("$Bin/data/auth/$authfw.yml");
push @authtags, @{ $file->{authtags} };
push @authsubfields, @{ $file->{authsubfields} };
}
my $biblio = LoadFile("$Bin/data/biblio/default.yml");
my $biblio = YAML::XS::LoadFile("$Bin/data/biblio/default.yml");
my @tags = @{ $biblio->{tags} };
my @subfields = @{ $biblio->{subfields} };

4
misc/search_tools/export_elasticsearch_mappings.pl

@ -59,7 +59,7 @@ use Koha::SearchFields;
use Koha::SearchMarcMaps;
use Koha::SearchEngine::Elasticsearch;
use YAML;
use YAML::XS;
use Getopt::Long;
use Pod::Usage;
@ -81,4 +81,4 @@ if ( $type && $type !~ /^(marc21|unimarc|normarc)$/ ) {
my $mappings = Koha::SearchEngine::Elasticsearch::raw_elasticsearch_mappings( $type );
binmode STDOUT, ":encoding(UTF-8)";
print Dump($mappings);
print YAML::XS::Dump($mappings);

3
opac/opac-ISBDdetail.pl

@ -40,6 +40,7 @@ the items attached to the biblio
=cut
use Modern::Perl;
use YAML::XS;
use C4::Auth;
use C4::Context;
@ -82,7 +83,7 @@ my $patron = Koha::Patrons->find($loggedinuser);
my $opachiddenitems_rules;
eval {
my $yaml = C4::Context->preference('OpacHiddenItems') . "\n\n";
$opachiddenitems_rules = YAML::Load($yaml);
$opachiddenitems_rules = YAML::XS::Load($yaml);
};
unless ( $patron and $patron->category->override_hidden_items ) {

3
opac/opac-search.pl

@ -30,6 +30,7 @@ use Modern::Perl;
use C4::Context;
use List::MoreUtils q/any/;
use Try::Tiny;
use YAML::XS;
use Data::Dumper; # TODO remove
@ -245,7 +246,7 @@ my $yaml = C4::Context->preference('OpacHiddenItems');
if ( $yaml =~ /\S/ ) {
$yaml = "$yaml\n\n"; # YAML expects trailing newline. Surplus does not hurt.
eval {
$hidingrules = YAML::Load($yaml);
$hidingrules = YAML::XS::Load($yaml);
};
if ($@) {
warn "Unable to parse OpacHiddenItems syspref : $@";

4
reports/reserves_stats.pl

@ -34,7 +34,7 @@ use Koha::ItemTypes;
use Koha::Libraries;
use Koha::Patron::Categories;
use List::MoreUtils qw/any/;
use YAML;
use YAML::XS;
=head1 NAME
@ -218,7 +218,7 @@ sub calculate {
my @sqlorparams;
my @sqlor;
my @sqlwhere;
($debug) and print STDERR Dump($filters_hashref);
($debug) and print STDERR YAML::XS::Dump($filters_hashref);
foreach my $filter (keys %$filters_hashref){
my $string;
my $stringfield=$filter;

4
t/Context.t

@ -21,7 +21,7 @@ use DBI;
use Test::More tests => 35;
use Test::MockModule;
use Test::Warn;
use YAML;
use YAML::XS;
use t::lib::Mocks;
@ -36,7 +36,7 @@ subtest 'yaml_preference() tests' => sub {
my $data = [ 'uno', 'dos', { 'tres' => 'cuatro' } ];
my $context = Test::MockModule->new( 'C4::Context' );
$context->mock( 'preference', YAML::Dump($data) );
$context->mock( 'preference', YAML::XS::Dump($data) );
my $pref = C4::Context->new->yaml_preference( 'nothing' );

2
t/Installer_PerlModules.t

@ -16,7 +16,7 @@ ok ($modules = C4::Installer::PerlModules->new(), 'Tests modules object');
my $prereq_pm = $modules->prereq_pm();
ok (exists($prereq_pm->{"DBI"}), 'DBI required for installer to run');
ok (exists($prereq_pm->{"CGI"}), 'CGI required for installer to run' );
ok (exists($prereq_pm->{"YAML"}), 'YAML required for installer to run');
ok (exists($prereq_pm->{"YAML::XS"}), 'YAML::XS required for installer to run');
subtest 'versions_info' => sub {
plan tests => 4;

2
t/db_dependent/Budgets.t

@ -20,8 +20,6 @@ use t::lib::TestBuilder;
use t::lib::Mocks;
use Koha::DateUtils;
use YAML;
use t::lib::Mocks;
t::lib::Mocks::mock_preference('OrderPriceRounding','');

4
t/db_dependent/Koha/Z3950Responder/GenericSession.t

@ -11,7 +11,7 @@ use File::Basename;
use File::Copy;
use FindBin qw($Bin);
use XML::LibXML;
use YAML;
use YAML::XS;
use ZOOM;
BEGIN {
@ -51,7 +51,7 @@ subtest 'test_search' => sub {
MARC::Field->new('999', '', '', c => '1234567'),
);
my $yaml = Test::MockModule->new('YAML');
my $yaml = Test::MockModule->new('YAML::XS');
$yaml->mock('LoadFile', sub {
return {
biblios => {

1
t/db_dependent/Koha/Z3950Responder/ZebraSession.t

@ -6,7 +6,6 @@ use Test::More tests => 3;
use Test::MockObject;
use t::lib::Mocks qw(mock_preference);
use YAML;
use ZOOM;
BEGIN {

8
t/db_dependent/OAI/Server.t

@ -27,7 +27,7 @@ use File::Spec;
use Test::MockModule;
use Test::Warn;
use XML::Simple;
use YAML;
use YAML::XS;
use t::lib::Mocks;
@ -176,9 +176,9 @@ sub test_query {
delete $response->{responseDate};
unless (is_deeply($response, \%full_expected, $test)) {
diag
"PARAM:" . Dump($param) .
"EXPECTED:" . Dump(\%full_expected) .
"RESPONSE:" . Dump($response);
"PARAM:" . YAML::XS::Dump($param) .
"EXPECTED:" . YAML::XS::Dump(\%full_expected) .
"RESPONSE:" . YAML::XS::Dump($response);
}
}

2
t/db_dependent/Search.t

@ -19,8 +19,6 @@ use Modern::Perl;
use utf8;
use YAML;
use C4::Debug;
use C4::AuthoritiesMarc qw( SearchAuthorities );
use C4::XSLT;

1
t/db_dependent/Serials.t

@ -4,7 +4,6 @@
# Add more tests here!!!
use Modern::Perl;
use YAML;
use C4::Serials;
use C4::Serials::Frequency;

1
xt/sample_notices.t

@ -78,7 +78,6 @@ sub compare_notices {
open( my $trans_fh,"<", "$root_dir/$trans_file" ),
"Open translated sample notices file $root_dir/$trans_file" );
my $trans_notice = get_notices_from_sql_file( $trans_fh );
use YAML;
my @trans_notices = sort { lc $a cmp lc $b } keys %$trans_notice;
cmp_ok(
$#trans_notices, '>=', 0,

4
xt/yaml_valid.pl

@ -19,7 +19,7 @@
use Modern::Perl;
use Getopt::Long;
use YAML;
use YAML::XS;
my $usage = <<EOF;
yaml_valid.pl - give it a filename and it will told you if it is an exact yaml file.
@ -39,7 +39,7 @@ GetOptions(
die $usage if $help;
say "Testing file: $file";
eval { YAML::LoadFile($file); };
eval { YAML::XS::LoadFile($file); };
if ($@) {
print "KO!\n$@\n";
}

Načítá se…
Zrušit
Uložit