forked from 0ad/0ad
72 lines
1.5 KiB
Perl
72 lines
1.5 KiB
Perl
use strict;
|
|
use warnings;
|
|
|
|
package DataFiles;
|
|
|
|
# Field numbers, so the arrays which (read|write)_file use can be accessed more pleasantly
|
|
use constant STR_ID => 0;
|
|
use constant STR_CONTEXT => 1;
|
|
use constant STR_DESCRIPTION => 2;
|
|
use constant STR_FLAGS => 3;
|
|
|
|
# Export the field numbers
|
|
require Exporter;
|
|
our @ISA = qw(Exporter);
|
|
our @EXPORT = qw(STR_ID STR_CONTEXT STR_DESCRIPTION STR_FLAGS);
|
|
|
|
|
|
# Read a file containing \n-separated fields and \n\n-separated records
|
|
sub read_file {
|
|
my ($filename, %params) = @_;
|
|
|
|
# If 'ignoremissing' has been passed, handle non-existent files as if they were empty
|
|
if ($params{ignoremissing} and not -e $filename) {
|
|
return [];
|
|
}
|
|
|
|
open my $f, '<', $filename or die "Error opening $filename for input: $!";
|
|
|
|
my (@records, @fields);
|
|
while (<$f>) {
|
|
chomp;
|
|
if (length) {
|
|
# Each line stores a separate field
|
|
push @fields, unescape($_);
|
|
} else {
|
|
# Split records by empty lines
|
|
push @records, [@fields];
|
|
@fields = ();
|
|
}
|
|
}
|
|
push @records, [@fields] if @fields;
|
|
|
|
return \@records;
|
|
}
|
|
|
|
# Inverse of read_file
|
|
sub write_file {
|
|
my ($filename, $data) = @_;
|
|
open my $f, '>', $filename or die "Error opening $filename for output: $!";
|
|
for (@$data) {
|
|
print $f escape($_), "\n" for @$_;
|
|
print $f "\n";
|
|
}
|
|
}
|
|
|
|
# Convert \ to \\, newlines to \n, blank lines to \
|
|
sub unescape {
|
|
my $t = $_[0];
|
|
return "" if $t eq "\\";
|
|
$t =~ s/\\n/\n/g;
|
|
$t =~ s/\\\\/\\/g;
|
|
$t;
|
|
}
|
|
sub escape {
|
|
my $t = $_[0];
|
|
return "\\" unless defined $t and length $t;
|
|
$t =~ s/\\/\\\\/g;
|
|
$t =~ s/\n/\\n/g;
|
|
$t;
|
|
}
|
|
|
|
1; |