xwords/xwords4/dawg/par.pl

235 lines
6.3 KiB
Perl
Raw Normal View History

2003-11-01 07:19:20 +01:00
#!/usr/bin/perl
# Copyright 2002 by Eric House (xwords@eehouse.org) All rights reserved.
2003-11-01 07:19:20 +01:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Only enough of par's features to support building a crosswords dict
# pdb
use strict;
my $debug = 0;
# stolen from par source
my $PRC_FLAGS_RESOURCE = (0x1<<0);
my $PRC_FLAGS_READONLY = (0x1<<1);
my $PRC_FLAGS_DIRTY = (0x1<<2);
my $PRC_FLAGS_BACKUP = (0x1<<3);
my $PRC_FLAGS_NEWER = (0x1<<4);
my $PRC_FLAGS_RESET = (0x1<<5);
my $PRC_FLAGS_COPYPREVENT = (0x1<<6);
my $PRC_FLAGS_STREAM = (0x1<<7);
my $PRC_FLAGS_HIDDEN = (0x1<<8);
my $PRC_FLAGS_LAUNCHABLE = (0x1<<9);
my $PRC_FLAGS_RECYCLABLE = (0x1<<10);
my $PRC_FLAGS_BUNDLE = (0x1<<11);
my $PRC_FLAGS_OPEN = (0x1<<15);
my $gAttrs = 0;
my $gVersion = 1; # par defaults this to 1
my $cmd = shift( @ARGV );
die "only 'c' supported now" if $cmd ne "c" && $cmd ne "-c";
readHOptions( \@ARGV );
my $dbfile = shift( @ARGV );
my $name = shift( @ARGV );
die "name $name too long" if length($name) > 31;
my $type = shift( @ARGV );
die "type $type must be of length 4" if length($type) != 4;
my $cid = shift( @ARGV );
die "cid $cid must be of length 4" if length($cid) != 4;
my @fileNames;
my @fileLengths;
my $nFiles = 0;
while ( @ARGV > 0 ) {
my $filename = shift( @ARGV );
push @fileNames, $filename;
push @fileLengths, -s $filename;
++$nFiles;
}
# from par's prcp.h; thanks djw!
# typedef struct prc_file_t {
# prc_byte_t name[32];
# prc_byte_t flags[2];
# prc_byte_t version[2];
# prc_byte_t ctime[4];
# prc_byte_t mtime[4];
# prc_byte_t btime[4];
# prc_byte_t modnum[4];
# prc_byte_t appinfo[4];
# prc_byte_t sortinfo[4];
# prc_byte_t type[4];
# prc_byte_t cid[4];
# prc_byte_t unique_id_seed[4];
# prc_byte_t next_record_list[4];
# prc_byte_t nrecords[2];
# } prc_file_t;
my $str;
my $offset = 0;
open OUTFILE, "> $dbfile" or die "couldn't open outfile $dbfile for writing";
# print the string, then pad with 0s
$offset = length($name);
print OUTFILE $name;
while ( $offset < 32 ) {
print OUTFILE pack("c", 0);
++$offset;
}
$str = pack("n", $gAttrs); # flags
print OUTFILE $str;
$offset += length($str);
$str = pack("n", $gVersion); # version
print OUTFILE $str;
$offset += length($str);
my $time = time() + 2082844800;
$str = pack("NNN", $time, $time, 0); # ctime, mtime, btime
print OUTFILE $str;
$offset += length($str);
$str = pack("N", 0 ); # mod num
print OUTFILE $str;
$offset += length($str);
$str = pack("N", 0 ); # appinfo
print OUTFILE $str;
$offset += length($str);
$str = pack("N", 0 ); # sortinfo
print OUTFILE $str;
$offset += length($str);
print OUTFILE $type; # type
print OUTFILE $cid; # cid
$offset += 8;
$str = pack("NN", 0, 0 ); # unique_id_seed, next_record_list
print OUTFILE $str;
$offset += length($str);
$str = pack("n", $nFiles ); # nrecords
print OUTFILE $str;
$offset += length($str);
$offset += $nFiles * 8;
$offset += 2; # djw adds 2 bytes after size list; see below
foreach my $len ( @fileLengths ) {
print OUTFILE pack( "N", $offset );
print OUTFILE pack( "N", 0 );
$offset += $len;
}
print OUTFILE pack( "n", 0 ); # djw does this sans comment: flush.c, line 87
foreach my $file ( @fileNames ) {
open INFILE, "<$file" or die "couldn't open infile $file\n";
my $buffer;
while ( read INFILE, $buffer, 1024 ) {
print OUTFILE $buffer;
}
close INFILE;
}
close OUTFILE;
exit 0;
##############################################################################
# Subroutines
##############################################################################
sub readHOptions {
my ( $argvR ) = @_;
for ( ; ; ) {
my $opt = ${$argvR}[0];
if ( $opt !~ /^-/ ) {
last;
}
# it starts with a '-': use it; else don't consume anything
shift @{$argvR};
if ( $opt eq "-a" ) {
my $attrs = shift @{$argvR};
processAttrString( $attrs );
} elsif ( $opt eq "-v" ) {
$gVersion = shift @{$argvR};
} else {
die "what's with \"$opt\": -a and -v are the only hattrs supported";
}
}
} # readHOptions
sub processAttrString {
my ( $attrs ) = @_;
foreach my $flag ( split /\|/, $attrs ) {
print STDERR "looking at flag $flag\n" if $debug;
if ( $flag =~ /resource/ ) {
$gAttrs |= $PRC_FLAGS_RESOURCE;
die "resource attr not supported";
} elsif ( $flag =~ /readonly/ ) {
$gAttrs |= $PRC_FLAGS_READONLY;
} elsif ( $flag =~ /dirty/ ) {
$gAttrs |= $PRC_FLAGS_DIRTY;
} elsif ( $flag =~ /backup/ ) {
$gAttrs |= $PRC_FLAGS_BACKUP;
} elsif ( $flag =~ /newer/ ) {
$gAttrs |= $PRC_FLAGS_NEWER;
} elsif ( $flag =~ /reset/ ) {
$gAttrs |= $PRC_FLAGS_RESET;
} elsif ( $flag =~ /copyprevent/ ) {
$gAttrs |= $PRC_FLAGS_COPYPREVENT;
} elsif ( $flag =~ /stream/ ) {
$gAttrs |= $PRC_FLAGS_STREAM;
die "stream attr not supported";
} elsif ( $flag =~ /hidden/ ) {
$gAttrs |= $PRC_FLAGS_HIDDEN;
} elsif ( $flag =~ /launchable/ ) {
$gAttrs |= $PRC_FLAGS_LAUNCHABLE;
} elsif ( $flag =~ /recyclable/ ) {
$gAttrs |= $PRC_FLAGS_RECYCLABLE;
} elsif ( $flag =~ /bundle/ ) {
$gAttrs |= $PRC_FLAGS_BUNDLE;
} elsif ( $flag =~ /open/ ) {
$gAttrs |= $PRC_FLAGS_OPEN;
} else {
die "flag $flag not supportd";
}
}
} # processAttrString