#!/usr/bin/perl # # NHtext # $NHDT-Date$ # clean/smudge filter for handling substitutions use strict; #my $debug = 0; # save trace to file #my $debug2 = 0; # annotate output when running from command line #my $sink = ($^O eq "MSWin32")? "NUL" :"/dev/null"; #my $dbgfile = ($^O eq "MSWin32") ? "$ENV{TEMP}.$$" : "/tmp/trace.$$"; #open TRACE, ">>", ($debug==0)? $sink : $dbgfile; sub git_config { my($section, $var) = @_; local($_); # Sigh. Without GIT_DIR we have to do it the slow way, and sometimes we don't # have GIT_DIR. if(0 == length($ENV{GIT_DIR})){ my $raw = `git config --local --get $section.$var`; chomp($raw); return $raw } open(CONFIG, "<", "$ENV{GIT_DIR}/config") or die "Missing .git/config: $!"; while(){ m/^\[$section]/ && do { while(){ m/^\s+$var\s+=\s+(.*)/ && do { return $1; }; } }; } die "Missing config var: [$section] $var\n"; } # pick up the prefix for substitutions in this repo my $PREFIX = &git_config('nethack','substprefix'); my $submode = 0; # ok to make non-cleaning changes to file my $mode; if($ARGV[0] eq "--clean"){ $mode = "c"; if(0 == 0+$ENV{NHMODE}){ $submode = 1; # do NOT add extra changes to the file # print TRACE "SKIPPING\n"; } } elsif($ARGV[0] eq "--smudge"){ $mode = "s"; } else { warn "Unknown mode '$ARGV[0]'\n"; exit 1; } # XXX for now, there isn't any - if we get called, we subst. No options for now. # get relevent config info #XXX #git check-attr -a $ARGV[1] # Process stdin to stdout. # For speed we read in the entire file then do the substitutions. local($_) = ''; my $len; while(1){ # On at least some systems we only get 64K. my $len = sysread(STDIN, $_, 999999, length($_)); last if($len == 0); die "read failed: $!" unless defined($len); } # $1 - var and value (including trailing space but not $) # $2 - var # $4 - value or undef # s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\N{DOLLAR SIGN}]+))?)\$/&handlevar($2,$4)/eg; s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2,$4)/ego; die "write failed: $!" unless defined syswrite(STDOUT, $_); exit 0; sub handlevar { my($var, $val) = @_; # print "HIT '$var' '$val'\n" if($debug2); my $subname = "PREFIX::$var"; if(defined &$subname){ no strict; $val =~ s/\s+$//; $val = &$subname($val,$mode,$submode); } else { warn "No handler for \$$PREFIX-$var\n"; } if(length $val){ return "\$$PREFIX-$var: $val \$"; } else { return "\$$PREFIX-$var\$"; } } package PREFIX; use POSIX qw(strftime); # On push, put in the current date because we changed the file. # On pull, keep the current value so we can see the last change date. sub Date { my($val, $mode, $submode) = @_; if($mode eq "c"){ if($submode==0){ # we add this to make merge easier for now XXX my $now = time; # not %s below - may not be portable # YYYY/MM/DD HH:MM:SS $val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); } } # if($mode eq "s"){ # } return $val; } #sub Header { #} #sub Author { #} # NB: the standard-ish Revision line isn't enough - you need Branch:Revision - # but we split it into 2 so we can use the standard processing code on Revision # and just slip Branch in. sub Branch { my($val, $mode, $submode) = @_; if($mode eq "c"){ if($submode==0){ $val = `git symbolic-ref -q --short HEAD`; $val =~ s/[\n\r]*$//; $val =~ s/^\*\s*//; $val = "(unknown)" unless($val =~ m/^[[:print:]]+$/); } } # if($mode eq "s"){ # } return $val; } sub Revision { my($val, $mode, $submode) = @_; if($mode eq "c"){ if($submode==0){ my $file = $ARGV[1]; my @val = `git log --follow --oneline $file`; my $ver = 0+$#val; $ver = 0 if($ver < 0); $val = "1.$ver"; } } # if($mode eq "s"){ # } return $val; }