[interchange-cvs] interchange - heins modified eg/te
interchange-core@icdevgroup.org
interchange-core@icdevgroup.org
Sat Aug 31 02:20:04 2002
User: heins
Date: 2002-08-31 06:19:01 GMT
Modified: eg te
Log:
* Butting into one of my favorite tools. 8-)
* Add option -s for starting value support (really only vi).
te -s os28004 <file>
Jumps to first occurrence of "os28004" in <file>. Option -i ignores case
in the search.
* Done to support my cheesy phone-list command with "edtel" to complement
"addtel" and "tel".
Revision Changes Path
2.4 +163 -108 interchange/eg/te
rev 2.4, prev_rev 2.3
Index: te
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /var/cvs/interchange/eg/te,v
retrieving revision 2.3
retrieving revision 2.4
diff -u -r2.3 -r2.4
--- te 23 Jul 2002 18:30:19 -0000 2.3
+++ te 31 Aug 2002 06:19:00 -0000 2.4
@@ -103,51 +103,97 @@
solitary CR in the last field of a line is important, you'll want to
change this behavior.
=20
+2002-08-40. Add option -s for starting value support (really only vi).
+
+ te -s os28004 <file>
+
+Jumps to first occurrence of "os28004" in <file>. Option -i ignores case
+in the search.
+
=3Dcut
=20
use strict;
use Digest::MD5;
use File::Basename 'fileparse';
+use Text::ParseWords;
+
+use Getopt::Std;
+
+my ($prog) =3D fileparse($0);
+
+my $USAGE =3D <<EOF;
+Usage: $prog [-i] [-s startpoint] tablefile1 [tablefile2 ...]
+
+Edit tab-delimited file with easy field name delineation.
+
+Options:
+ -i Ignores case on vim jump search.
+ -s TEXT Jumps to first line where TEXT is. Only for vim.
+EOF
+
+use vars qw/$opt_i $opt_s/;
+getopts('is:') or die "$@\n$USAGE";
+
+die $USAGE unless @ARGV;
=20
-die "Usage: $0 tablefile1 [tablefile2 ...]\n" unless @ARGV;
+my @ED =3D Text::ParseWords::shellwords($ENV{VISUAL} || $ENV{EDITOR} || 'v=
i');
=20
-my $editor =3D $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
+if($opt_s) {
+ my $pushed;
+ if($opt_i) {
+ push @ED, '-c';
+ $pushed++;
+ push @ED, q{set ic};
+ }
+ push @ED, '-c';
+ $opt_s =3D~ s:/:\\/:g;
+ $opt_s =3D~ s:":\\":g;
+ push @ED, qq{/$opt_s/};
+}
=20
# run gvim in foreground mode, since it otherwise immediately returns
# control to us and we never get the user's changes
-$editor .=3D ' -f' if $editor =3D~ /\bgvim\b/ and $editor !~ /\s-f\b/;
+if($ED[0] =3D~ /\bgvim\b/) {
+ my $ffound;
+ for(@ED) {
+ next unless $_ eq '-f';
+ $ffound =3D 1;
+ last;
+ }
+ push @ED, '-f' unless $ffound;
+}
=20
for my $filename (@ARGV) {
- my (@fieldnames, $fieldcount, @fields);
- my ($name, $path, $tmpfile, $newfile, $digest1, $digest2);
- unless (-e $filename) {
- warn "Skipping '$filename': file does not exist\n";
- next;
- }
- unless (-f $filename) {
- warn "Skipping '$filename': not a regular file\n";
- next;
- }
- unless (open IN, "<$filename") {
- warn "Error 'opening' $filename for reading: $!\n";
- next;
- }
- $_ =3D <IN>;
- s/\x0d?\x0a?$//;
- die "Error in '$filename' header: null field name found\n" if /\t\t/;
- $fieldcount =3D tr/\t/\t/ + 1;
- @fieldnames =3D split /\t/, $_, $fieldcount;
- ($name, $path) =3D fileparse($filename);
-
- # I tried keeping the whole file in memory (for MD5's sake) instead of
- # first writing to disk, but doing it this way turned out to be about 5
- # times faster and used 1/10th the memory on large files. (My benchmark
- # was a 12 MB products.txt database for Interchange.)
-
- $tmpfile =3D "$path.$name.tmp.$$";
- open OUT, ">$tmpfile" or die "Error opening '$tmpfile' for writing: $!\n";
- print STDERR "Prettifying $filename\n";
- print OUT <<EOF;
+ my (@fieldnames, $fieldcount, @fields);
+ my ($name, $path, $tmpfile, $newfile, $digest1, $digest2);
+ unless (-e $filename) {
+ warn "Skipping '$filename': file does not exist\n";
+ next;
+ }
+ unless (-f $filename) {
+ warn "Skipping '$filename': not a regular file\n";
+ next;
+ }
+ unless (open IN, "<$filename") {
+ warn "Error 'opening' $filename for reading: $!\n";
+ next;
+ }
+ $_ =3D <IN>;
+ s/\x0d?\x0a?$//;
+ die "Error in '$filename' header: null field name found\n" if /\t\=
t/;
+ $fieldcount =3D tr/\t/\t/ + 1;
+ @fieldnames =3D split /\t/, $_, $fieldcount;
+ ($name, $path) =3D fileparse($filename);
+
+ # I tried keeping the whole file in memory (for MD5's sake) instea=
d of
+ # first writing to disk, but doing it this way turned out to be ab=
out 5
+ # times faster and used 1/10th the memory on large files. (My benc=
hmark
+ # was a 12 MB products.txt database for Interchange.)
+
+ $tmpfile =3D "$path.$name.tmp.$$";
+ open OUT, ">$tmpfile" or die "Error opening '$tmpfile' for writing=
: $!\n";
+ print STDERR "Prettifying $filename\n";
+ print OUT <<EOF;
#
# This is a temporary file, automatically generated from the database file:
#
@@ -157,91 +203,100 @@
# format and will replace the original file.
#
EOF
- while (<IN>) {
- s/\x0d?\x0a?$//;
- @fields =3D split /\t/, $_, $fieldcount;
- for (my $i =3D 0; $i < @fieldnames; $i++) {
- print OUT $fieldnames[$i], ":",
- defined $fields[$i] ? $fields[$i] : '', "\n";
- }
- print OUT "#\n";
- }
- if (@fields) {
- print OUT <<EOF;
+ while (<IN>) {
+ s/\x0d?\x0a?$//;
+ @fields =3D split /\t/, $_, $fieldcount;
+ for (my $i =3D 0; $i < @fieldnames; $i++) {
+ print OUT $fieldnames[$i], ":",
+ defined $fields[$i] ? $fields[$i] : '', "\=
n";
+ }
+ print OUT "#\n";
+ }
+ if (@fields) {
+ print OUT <<EOF;
# You can uncomment the following lines to use as a template for inserting
# a new row into the table. Copy as many times as needed to add many rows.
#
EOF
- } else {
- print OUT <<EOF;
+ } else {
+ print OUT <<EOF;
# Your file was empty -- it had no data rows, only field definitions.
# You can copy the following empty row template as many times as needed
# to add new rows to the table.
#
EOF
- }
- print OUT join("\n", map { (@fields ? '#' : '') . $_ . ":" } @fieldnames);
- print OUT "\n#\n";
- close IN;
- print OUT <<EOF;
+ }
+ print OUT join("\n", map { (@fields ? '#' : '') . $_ . ":" } @fiel=
dnames);
+ print OUT "\n#\n";
+ close IN;
+ print OUT <<EOF;
# end of file
#
EOF
- close OUT or die "Error closing '$tmpfile' after writing: $!\n";
- open IN, "<$tmpfile" or die "Error opening '$tmpfile' for reading: $!\n";
- binmode IN;
- $digest1 =3D Digest::MD5->new->addfile(*IN)->digest;
- close IN;
- system (split(/ /, $editor), $tmpfile) =3D=3D 0
- or die "Error calling editor '$editor' with '$tmpfile': $!\n";
- open IN, "<$tmpfile" or die "Error opening '$tmpfile' for reading: $!\n";
- binmode IN;
- $digest2 =3D Digest::MD5->new->addfile(*IN)->digest;
- if ($digest1 eq $digest2) {
- print STDERR "No changes made; '$filename' untouched\n";
- close IN;
- unlink $tmpfile;
- next;
- }
- print STDERR "Importing changes back into '$filename'\n";
- $newfile =3D "$path.$name.new.$$";
- open OUT, ">$newfile" or die "Error opening '$newfile' for writing: $!\n";
- print OUT join("\t", @fieldnames), "\n";
- my $tabcounter =3D 0;
- my $fieldpos =3D 0;
- my $done;
- seek IN, 0, 0 or die "Error rewinding file '$tmpfile': $!\n";
- @fields =3D ();
- while (<IN>) {
- $done =3D 1 if /^#\s*DONE/;
- next if /^\s*#/ || /^\s*$/;
- /^([^:]+):(.*)$/ or
- die "Error parsing line $. of '$tmpfile': line format unknown:\n$_";
- $1 eq $fieldnames[$fieldpos] or
- die "Error parsing line $. of '$tmpfile': expected field name '$fieldna=
mes[$fieldpos]', found '$1'\n";
- $_ =3D $2;
- $tabcounter +=3D s/\t/ /g;
- push @fields, $_;
- if (++$fieldpos >=3D $fieldcount) {
- print OUT join("\t", @fields), "\n";
- @fields =3D ();
- $fieldpos =3D 0;
- }
- }
- print STDERR "$tabcounter tab character",
- $tabcounter =3D=3D 1 ? ' was' : 's were',
- " found in the data! Each tab was replaced with a space.\n"
- if $tabcounter;
- close OUT or die "Error closing '$filename.new' after writing: $!\n";
- close IN or die "Error closing '$tmpfile' after reading: $!\n";
- my ($mode, $uid, $gid) =3D (stat($filename))[2,4,5];
- chmod $mode, $newfile;
- chown $uid, $gid, $newfile if $> =3D=3D 0;
- rename $newfile, $filename or
- die "Error renaming '$newfile' to '$filename': $!\n";
- unlink $tmpfile;
- if ($done) {
- print STDERR "Found 'DONE' command; skipping rest of files.\n";
- last;
- }
+ close OUT or die "Error closing '$tmpfile' after writing: $!\n";
+ open IN, "<$tmpfile" or die "Error opening '$tmpfile' for reading:=
$!\n";
+ binmode IN;
+ $digest1 =3D Digest::MD5->new->addfile(*IN)->digest;
+ close IN;
+ system (@ED, $tmpfile) =3D=3D 0
+ or do {
+ @ED =3D ('gvim', '-f', 'some quotes " "', "some sp=
ace");
+ for(@ED) {
+ next unless /\s/;
+ s/"/\\"/g;
+ $_ =3D qq["$_"];
+ }
+ my $editor =3D join " ", @ED;
+ die "Error calling editor '$editor' with '$tmpfile=
': $!\n";
+ };
+ open IN, "<$tmpfile" or die "Error opening '$tmpfile' for reading:=
$!\n";
+ binmode IN;
+ $digest2 =3D Digest::MD5->new->addfile(*IN)->digest;
+ if ($digest1 eq $digest2) {
+ print STDERR "No changes made; '$filename' untouched\n";
+ close IN;
+ unlink $tmpfile;
+ next;
+ }
+ print STDERR "Importing changes back into '$filename'\n";
+ $newfile =3D "$path.$name.new.$$";
+ open OUT, ">$newfile" or die "Error opening '$newfile' for writing=
: $!\n";
+ print OUT join("\t", @fieldnames), "\n";
+ my $tabcounter =3D 0;
+ my $fieldpos =3D 0;
+ my $done;
+ seek IN, 0, 0 or die "Error rewinding file '$tmpfile': $!\n";
+ @fields =3D ();
+ while (<IN>) {
+ $done =3D 1 if /^#\s*DONE/;
+ next if /^\s*#/ || /^\s*$/;
+ /^([^:]+):(.*)$/ or
+ die "Error parsing line $. of '$tmpfile': line for=
mat unknown:\n$_";
+ $1 eq $fieldnames[$fieldpos] or
+ die "Error parsing line $. of '$tmpfile': expected=
field name '$fieldnames[$fieldpos]', found '$1'\n";
+ $_ =3D $2;
+ $tabcounter +=3D s/\t/ /g;
+ push @fields, $_;
+ if (++$fieldpos >=3D $fieldcount) {
+ print OUT join("\t", @fields), "\n";
+ @fields =3D ();
+ $fieldpos =3D 0;
+ }
+ }
+ print STDERR "$tabcounter tab character",
+ $tabcounter =3D=3D 1 ? ' was' : 's were',
+ " found in the data! Each tab was replaced with a space.\n"
+ if $tabcounter;
+ close OUT or die "Error closing '$filename.new' after writing: $!\=
n";
+ close IN or die "Error closing '$tmpfile' after reading: $!\n";
+ my ($mode, $uid, $gid) =3D (stat($filename))[2,4,5];
+ chmod $mode, $newfile;
+ chown $uid, $gid, $newfile if $> =3D=3D 0;
+ rename $newfile, $filename or
+ die "Error renaming '$newfile' to '$filename': $!\n";
+ unlink $tmpfile;
+ if ($done) {
+ print STDERR "Found 'DONE' command; skipping rest of files=
\n";
+ last;
+ }
}