Orthogonalized -s, changed -o to accept directories and files
Separated -s <ext> logic into a stdio/cmdline switch (-s) and a reverse/forward
semantics switch (-i <ext>). Also, -o may now specify a directory or a file.
If it specifies a file, all input files use that as the output filename.
== Invocation ==
-conv [-f <file>] [-o <dir>] [-j <procs>] [-n] [-v] <file1> [<file2> ... <filen>]
-
- -f <file> Use the specified rule file instead of Convfile
- -o <dir> Place output files in the specified directory
+conv [-f <file>] [-i <ext>] [-o <dir>|<file>] [-s] [-j <procs>] [-n] [-v]
+ <file1> [<file2> ... <filen>]
+
+ -f <file> Use the specified rule file instead of Convfile.
+ -i <ext> Files specified are input files instead of output
+ files, and will be converted to files with the given
+ extension.
+ -o <dir>|<file> Place output files in the specified directory or file.
+ Note that -o <file> implies -i <ext> using <file>'s
+ extension. Multiple input files can be specified with
+ a single output file, but this may not make sense. On
+ the other hand, if your output file is a device or
+ fifo, it could make sense.
+ -s Read filenames from stdin instead of from the
+ command-line.
-j <procs> Spawn <procs> conversions at once, for
multiprocessor machines.
- -n Don't actually do anything. Useful with -v to
- get an idea what conv is thinking.
+ -n Don't actually do anything. Useful with -v to find out
+ what conv is thinking.
-v Be more verbose.
-It is important to realize that, just like make, the files you are
-specifying are the _output_ files, not the input files. The input files
-are found automatically from the first matching rule where a file
-exists. This means that if you have foo.ogg, and you want to produce a
-mp3, you should do this:
+It is important to realize that, just like make, the files you are specifying
+are the _output_ files, not the input files (unless, of course, you've
+specified the -i switch). The input files are found automatically from the
+first matching rule where a file exists. This means that if you have foo.ogg,
+and you want to produce a mp3, you should do this:
$ conv foo.mp3
j => 1
);
-getopts('vnj:f:o:s:', \%opts);
+getopts('vnsj:f:o:i:', \%opts);
+
+my $dirout;
+if (-d $opts{o}) {
+ # output is a directory
+ $dirout = 1;
+} else {
+ # output is a single file, imply -i <ext>
+ if ($opts{o} =~ /\.(\w+)$/) {
+ $opts{i} = $1;
+ } else {
+ print "Specified -o <file>, but '$opts{o}' has no extension.\n";
+ exit 1;
+ }
+}
print "Using $opts{j} processors\n" if $opts{v};
$cmd =~ s!\$\<!"$infile"!g;
my $outfile;
if ($opts{o}) {
- # Strip leading path from base so we can stick the file in
- # another dir.
- $base = basename($base);
- $outfile = "$opts{o}/$base.$oext";
+ if ($dirout) {
+ # Strip leading path from base so we can stick the file in
+ # another dir.
+ $base = basename($base);
+ $outfile = "$opts{o}/$base.$oext";
+ } else {
+ $outfile = $opts{o};
+ }
} else {
$outfile = "$base.$oext";
}
close CONF;
my @queue;
+my @files;
# If we specify reading from stdin, do this.
if (exists $opts{s}) {
while (<STDIN>) {
next if /^#/;
chomp;
-
+
+ push @files, $_;
+ }
+} else {
+ @files = @ARGV;
+}
+
+# Reversed semantics. Files are input to be converted to the specified extension
+if ($opts{i}) {
+ unless (exists $rules{$opts{i}}) {
+ print <<EOD;
+You have specified -i <ext>, but the Convfile has no rule to convert to
+extension '$opts{i}'
+EOD
+ exit 1;
+ }
+ foreach (@files) {
unless (-e $_) {
- print "File specified on stdin, $_, does not exist.\n";
+ print "$_ does not exist.\n";
next;
}
my $base = $1;
my $iext = $2;
print "Considering $base.$iext\n" if $opts{v};
- if (exists $rules{$opts{s}}{$iext}) {
+ if (exists $rules{$opts{i}}{$iext}) {
print "Using $base.$iext\n" if $opts{v};
- push @queue, [$base, $iext, $opts{s}];
+ push @queue, [$base, $iext, $opts{i}];
}
} else {
print "I don't see an extension on $_, so I don't know what to do with it.\n";
}
}
-# Not reading filenames from stdin.
+# Make semantics, files specified are desired output files
else {
- # Do something fun
- my @tmpARGV;
- foreach (@ARGV) {
+ # Do something fun (convert *.foo into a list of files that would match if they existed)
+ my @tmpfiles;
+ foreach (@files) {
if (/^\*\.(\w+)$/) {
my $extsub = $1;
- opendir D, '.';
- my @files =
+ push @tmpfiles,
map { s/\.(\w+)$/\.$extsub/; $_ }
grep { /^[^.]/ }
- readdir D;
- closedir D;
- push @tmpARGV, @files;
+ <*>;
} else {
- push @tmpARGV, $_;
+ push @tmpfiles, $_;
}
}
- @ARGV = @tmpARGV;
+ @files = @tmpfiles;
# I like to call this the TOWER OF POWER
- for my $ofile (@ARGV) {
+ for my $ofile (@files) {
my $ofound = 0;
for my $oext (keys %rules) {
my $oext_re = $oext;
}
wait while $procs--;
-# vim:set ts=4 sts=4 sw=4 expandtab:
+# vim:ts=4 sts=4 sw=4 expandtab