commit:b4bc84a2cdacbf8c1958e611f5383474d1b3d719
author:Chip Black
committer:Chip Black
date:Tue Jun 3 00:35:09 2008 -0500
parents:5d7a3245aa4b35438ddbee6308b87b01550ccd29
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.
diff --git a/README b/README
line changes: +22/-11
index 18d753c..98db032
--- a/README
+++ b/README
@@ -32,21 +32,32 @@ Which is not to say that conv is useless. Far from it. Conv does:
 
 == 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
 

diff --git a/conv.pl b/conv.pl
line changes: +54/-22
index 218dae1..2293a36
--- a/conv.pl
+++ b/conv.pl
@@ -10,7 +10,21 @@ my %opts = (
     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};
 
@@ -24,10 +38,14 @@ sub convert {
     $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";
     }
@@ -66,15 +84,32 @@ while (<CONF>) {
 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;
         }
 
@@ -82,9 +117,9 @@ if (exists $opts{s}) {
             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";
@@ -92,28 +127,25 @@ if (exists $opts{s}) {
     }
 }
 
-# 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;
@@ -156,4 +188,4 @@ foreach my $chunk (@queue) {
 }
 wait while $procs--;
 
-# vim:set ts=4 sts=4 sw=4 expandtab:
+# vim:ts=4 sts=4 sw=4 expandtab