#!/usr/bin/perl #- small script to mix the good of cvs-rdiff and cvs-log #- didn't find a way to do it directly with cvs :/ #- #- given a date, it will list differences from this date #- to now, showing first the log entries for all revisions #- in between, then the cvs diff #- #- example usage at the end of this file. use strict; if (@ARGV != 2) { die "$0 \n"; } my $module = $ARGV[0]; my $date = $ARGV[1]; my @rdiff = chomp_(`cvs rdiff -s -D "$date" $module`); chdir $module; foreach (@rdiff) { if (my ($f, $r1, $r2) = $_ =~ /^File (\S+) changed from revision (\S+) to (\S+)/) { $f =~ s|^\Q$module/||; my @log = `cvs log -r${r1}::${r2} $f`; my $real_log; @log = map { $real_log = 1 if /^revision/; $real_log ? $_ : '' } @log; my ($index, $sep, undef, undef, undef, undef, @diff) = `cvs diff -r $r1 -r $r2 $f`; chomp $index; print "$index [$r1 -> $r2]\n$sep", join('', @log, @diff); } if (my ($f) = $_ =~ /^File (\S+) is new/) { print ">>> added $f\n"; } if (my ($f) = $_ =~ /^File (\S+) is removed/) { print "<<< removed $f\n"; } print "\n"; } #- functions from perl-MDK-Common sub chomp_ { my @l = map { my $l = $_; chomp $l; $l } @_; wantarray() ? @l : $l[0] } # Example usage: # # [gc@frozen /tmp/src] CVSROOT=":pserver:anonymous@cvs.sourceforge.net:/cvsroot/pleac" cvsdiff pleac "2 days ago" # Index: pleac/pleac_forth.data [1.3 -> 1.4] # =================================================================== # revision 1.4 # date: 2004/10/11 20:22:33; author: ggc; state: Exp; lines: +186 -0 # Weldon Goree # ============================================================================= # --- pleac/pleac_forth.data 1 Jul 2003 10:26:28 -0000 1.3 # +++ pleac/pleac_forth.data 11 Oct 2004 20:22:33 -0000 1.4 # @@ -222,3 +222,189 @@ # : map-xt ( xt c- u -- variable stack effect ) # 0 do 2dup i chars + c@ swap execute loop # ; # + # +( @@PLEAC@@_1.6 ) # + # +: 4dup-nip ( a b c d -- a b c d a b d ) # + 2over 2over nip # +; # + # +: c[i]@ ( c- i -- c ) chars + c@ # +; # + # +: c[i]! ( c- i c -- ) # + chars + c! # +; # + # +: -cmove ( c- x c- -- c- x ) # + over 0 # + u+do i 4dup-nip # + 1+ - c[i]@ # + 2over nip rot c[i]! # + loop # + rot drop swap # +; # + # +: revbytes ( c- x -- c- x ) # + dup allocate throw # + -cmove # +; # + # +: gnirts s" string" revbytes ; # + # +: space? # + 32 = # +; # + # +: ^? ( c c- a -- c t ) # + c[i]@ # + tuck space? not swap space? and ; # + # +: -^? ( c c- a -- c t ) # + c[i]@ # + tuck # + space? # + swap # + space? not and # +; # + # +: count-words ( c- x -- x ) # + 0 -rot 32 swap # + 0 u+do # + over i ^? if # + rot 1+ -rot # + then # + loop # + drop drop # +; # + # +: last-spaces ( c- x -- x ) # + 0 -rot # + begin # + 1- # + 2dup # + c[i]@ # + space? # + over 0 >= # + and # + while # + rot 1+ -rot # + repeat # + drop drop # +; # + # +: last-word ( c- x -- x ) # + 0 -rot # + begin # + 1- # + 2dup # + c[i]@ # + space? not # + over 0 >= # + and # + while # + rot 1+ -rot # + repeat # + drop drop # +; # + # +: back>front ( c- x c- x -- ) # + 2swap 2dup last-word -rot # + chars + over chars - swap # + rot drop rot swap # + cmove ; # + # +: sback>front ( c- x c- x -- ) # + 2swap 2dup last-spaces -rot # + chars + over chars - swap # + rot drop rot swap # + cmove # +; # + # +: sdrow ( c- x -- c- x ) 2dup last-spaces - # +dup >r dup chars allocate throw # + dup >r # + over 2swap 2dup count-words 0 u+do # +2dup last-word >r 2over 2over 2swap back>front r@ # + - rot drop dup -rot 2swap # + r> # + rot + swap 2swap # + 2dup last-spaces >r # + 2over 2over 2swap sback>front r@ # + - rot drop dup -rot 2swap # + r> # + rot + swap 2swap # + loop # + 2drop 2drop # + r> r> # +; # + # +: count-spaces ( c- x -- x ) # + 0 -rot # + 0 u+do # + dup i c[i]@ space? if # + swap 1+ swap # + then # + loop # + drop # +; # + # +: move-if-not-space ( c- c- -- f ) # + swap c@ dup space? # + if # + drop drop false # + else # + swap c! true # + then # +; # + # +: squash-words ( c- x -- c- x ) # + 2dup count-spaces # + over swap - # + dup chars allocate throw # + swap >r dup >r # + -rot # + 0 u+do # + 2dup # + i chars + # + swap # + move-if-not-space if # + swap 1 chars + swap # + then # + loop # + drop drop r> r> # +; # + # +: confused ( c- x -- c- x ) # + squash-words # + revbytes # +; # + # +80 constant biggest-word # +create buff biggest-word 2 + allot # + # +: palindrome? ( c- x -- f ) # + 2dup revbytes # + compare not # +; # + # +: chomp ( c- x -- c- x ) # + 2dup last-spaces - # +; # +s" /usr/share/dict/words" r/o open-file throw value dict # + # +: scan-dictionary ( c- x -- ) # + begin # + buff biggest-word dict read-line throw # + while # + dup buff swap chomp # + dup 5 > -rot # + palindrome? and if # + buff swap type cr # + else # + drop # + then # + repeat # +; # + # + # # Index: pleac/pleac_python.data [1.57 -> 1.59] # =================================================================== # revision 1.59 # date: 2004/10/11 07:36:55; author: pixel_; state: Exp; lines: +50 -0 # 6.4 from Engelbert Gruber # ---------------------------- # revision 1.58 # date: 2004/10/11 06:59:39; author: pixel_; state: Exp; lines: +89 -0 # 6.0, 6.1 and 6.3 from Engelbert Gruber # ============================================================================= # --- pleac/pleac_python.data 4 Oct 2004 07:46:38 -0000 1.57 # +++ pleac/pleac_python.data 11 Oct 2004 07:36:55 -0000 1.59 # @@ -2476,6 +2476,145 @@ # if __name__ == "__main__": # main() # # + # +# @@PLEAC@@_6.0 # +import re # "re" is the regular expression module. # +re.search("sheep",meadow) # returns a MatchObject is meadow contains "sheep". # +if not re.search("sheep",meadow): # + print "no sheep on this meadow only a fat python." # +# replacing strings is not done by "re"gular expressions. # +meadow = meadow.replace("old","new") # replace "old" with "new" and assign result. # +#----------------------------- # +re.search("ovine",meadow) # + # +meadow = """Fine bovines demand fine toreadors. # +Muskoxen are polar ovibovine species. # +Grooviness went out of fashion decades ago.""" # + # +meadow = "Ovines are found typically in ovaries." # + # +# "\b" should work but fails. # +if re.search("\bovines\b",meadow,re.I) : print "Here be sheep!" # +#----------------------------- # +# The tricky bit # +string = "good food" # +string.replace("o","e") # gives "geed feed" # +# with regular expressions # +re.sub("o*","e",string) # gives "egede efede" # + # +echo ababacaca | python -c "import sys,re; print re.search('(a|ba|b)+(a|ac)+',sys.stdin.read()).group()" # +#----------------------------- # +# pattern matching modifiers # +# assume perl code iterates over some file # +import re, fileinput # +for ln = fileinput.input(): # + fnd = re.findall("(\d+)",ln) # + if len(fnd) > 0: # + print "Found number %s" % (fnd[0]) # +# ---------------------------- # +digits = "123456789" # +nonlap = re.findall("(\d\d\d)", digits) # +yeslap = ["not yet"] # +print "Non-overlapping:",",".join(nonlap) # +print "Overlapping :",",".join(yeslap) # +# ---------------------------- # +string = "And little lambs eat ivy" # +fnd = re.search("(l[^s]*s)",string) # +print "(%s) (%s) (%s)" % \ # + (string[:fnd.start()], string[fnd.start():fnd.end()], string[fnd.end():]) # +# (And ) (little lambs) ( eat ivy) # + # +# @@PLEAC@@_6.1 # +import re # +dst = re.sub("this","that",src) # +#----------------------------- # +# strip to basename # +basename = re.sub(".*/(?=[^/]+)","",progname) # + # +# Make All Words Title-Cased # +def cap(mo): return mo.group().capitalize() # +re.sub("(?P\w+)",cap,"make all words title-cased") # + # +# /usr/man/man3/foo.1 changes to /usr/man/cat3/foo.1 # +manpage = "/usr/man/man3/foo.1" # +catpage = re.sub("man(?=\d)","cat",manpage) # +#----------------------------- # +bindirs = "/usr/bin /bin /usr/local/bin".split() # +libdirs = bindirs # +for i in range(len(libdirs)): # + libdirs[i] = libdirs[i].replace("bin","lib") # + # +print " ".join(libdirs),"\n" # +# /usr/lib /lib /usr/local/lib # +#----------------------------- # +# strings are never modified in place. # +#----------------------------- # + # +# @@PLEAC@@_6.3 # +# Matching Words # +"\S+" # as many non-whitespace bytes as possible # +"[A-Za-z'-]+" # as many letters, apostrophes, and hyphens # + # +# string split is similar to splitting on "\s+" # +"A text with some\tseparator".split() # + # +"\b*([A-Za-z]+)\b*" # word boundaries # +"\s*([A-Za-z]+)\s*" # might work too as on letters are allowed. # + # +re.search("\Bis\B","this thistle") # matches on thistle not on this # +re.search("\Bis\B","vis-a-vis") # does not match # + # +# @@PLEAC@@_6.4 # +#----------------------------- # +#!/usr/bin/python # +# resname - change all "foo.bar.com" style names in the input stream # +# into "foo.bar.com [204.148.40.9]" (or whatever) instead # + # +import socket # load inet_addr # +import fileinput # +import re # + # +match = re.compile("""(?P # capture hostname # + (?: # these parens for grouping only # + [\w-]+ # hostname component # + \. # ant the domain dot # + ) + # now repeat that whole thing a bunch of times # + [A-Za-z] # next must be a letter # + [\w-] + # now trailing domain part # + ) # end of hostname capture # + """,re.VERBOSE) # for nice formatting # + # +def repl(match_obj): # + try: # + addr = socket.gethostbyname(match_obj.group("hostname")) # + except: # + addr = "???" # + return "%s [%s]" % ( # + match_obj.group("hostname"), # the original hostname # + addr ) # +for ln in fileinput.input(): # + print match.sub(repl, ln) # +#----------------------------- # +re.sub("""(?x) # nicer formatting # + \# # a pound sign # + (\w+) # the variable name # + \# # another pound sign # + """, # + lambda m: eval(m.group(1)), # replace with the value of the global variable # + line # + ) # +##----------------------------- # +re.sub("""(?x) # nicer formatting # + \# # a pound sign # + (\w+) # the variable name # + \# # another pound sign # + """, # + lambda m: eval(eval(m.group(1))), # replace with the value of *any* variable # + line # + ) # +##----------------------------- # + # + # # @@PLEAC@@_7.0 # input = open("/usr/local/widgets/data") # for line in input: # # Index: pleac/pleac_ruby.data [1.68 -> 1.69] # =================================================================== # revision 1.69 # date: 2004/10/11 21:47:27; author: internetlabor; state: Exp; lines: +142 -4 # Added file sections from Andrew # ============================================================================= # --- pleac/pleac_ruby.data 3 Oct 2004 21:11:46 -0000 1.68 # +++ pleac/pleac_ruby.data 11 Oct 2004 21:47:27 -0000 1.69 # @@ -2415,7 +2415,23 @@ # end # #----------------------------- # # Ruby doesn't have the String.pos or a /c re modifier like Perl # -# @@INCOMPLETE@@ # +# But it does have StringScanner in the standard library (strscn) # +# which allows similar functionality: # + # +require 'strscan' # +text = 'the year 1752 lost 10 days on the 3rd of September' # +sc = StringScanner.new(text) # +while sc.scan(/.*?(\d+)/) # + print "found: #{sc[1]}\n" # +end # +if sc.scan(/\S+/) # + puts "Found #{sc[0]} after last number" # +end # +#----------------------------- # +# assuming continuing from above: # +puts "The position in 'text' is: #{sc.pos}" # +sc.pos = 30 # +puts "The position in 'text' is: #{sc.pos}" # # # #@@PLEAC@@_6.15 # @@ -3112,10 +3128,97 @@ # end # # # +# @@PLEAC@@_7.9 # +#% ruby -i.orig -pe 'FILTER COMMAND' file1 file2 file3 ... # +# # +#----------------------------- # +##!/usr/bin/ruby -i.orig -p # +# filter commands go here # +#----------------------------- # + # +#% ruby -pi.orig -e 'gsub!(/DATE/){Time.now)' # + # +# effectively becomes: # +ARGV << 'I' # +oldfile = "" # +while gets # + if ARGF.filename != oldfile # + newfile = ARGF.filename # + File.rename(newfile, newfile + ".orig") # + $stdout = File.open(newfile,'w') # + oldfile = newfile # + end # + gsub!(/DATE/){Time.now} # + print # +end # +$stdout = STDOUT # +#----------------------------- # +#% ruby -i.old -pe 'gsub!(%r{\bhisvar\b}, 'hervar')' *.[Cchy] # + # +#----------------------------- # +# set up to iterate over the *.c files in the current directory, # +# editing in place and saving the old file with a .orig extension # +$-i = '.orig' # set up -i mode # +ARGV.replace(Dir['*.[Cchy]']) # +while gets # + if $. == 1 # + print "This line should appear at the top of each file\n" # + end # + gsub!(/\b(p)earl\b/i, '\1erl') # Correct typos, preserving case # + print # + ARGF.close if ARGF.eof # +end # + # + # +# @@PLEAC@@_7.10 # +File.open('itest', 'r+') do |f| # open file for update # + lines = f.readlines # read into array of lines # + lines.each do |it| # modify lines # + it.gsub!(/foo/, 'QQQ') # + end # + f.pos = 0 # back to start # + f.print lines # write out modified lines # + f.truncate(f.pos) # truncate to new length # +end # file is automatically closed # +#----------------------------- # +File.open('itest', 'r+') do |f| # + out = "" # + f.each do |line| # + out << line.gsub(/DATE/) {Time.now} # + end # + f.pos = 0 # + f.print out # + f.truncate(f.pos) # +end # + # +# @@PLEAC@@_7.11 # +File.open('infile', 'r+') do |f| # + f.flock File::LOCK_EX # + # update file # +end # +#----------------------------- # +File::LOCK_SH # shared lock (for reading) # +File::LOCK_EX # exclusive lock (for writing) # +File::LOCK_NB # non-blocking request # +File::LOCK_UN # free lock # +#----------------------------- # +unless f.flock File::LOCK_EX | File::LOCK_NB # + warn "can't get immediate lock: blocking ..." # + f.flock File::LOCK_EX # +end # +#----------------------------- # +File.open('numfile', File::RDWR|File::CREAT) do |f| # + f.flock(File::LOCK_EX) # + num = f.gets.to_i || 0 # + f.pos = 0 # + f.truncate 0 # + f.puts num + 1q # +end # + # + # # @@PLEAC@@_7.12 # output_handle.sync = true # # Please note that like in Perl, $stderr is already unbuffered # - # #----------------------------- # #!/usr/bin/ruby -w # # seeme - demo stdio output buffering # @@ -3124,8 +3227,43 @@ # sleep 2 # puts "now you do" # #----------------------------- # - # -# @@INCOMPLETE@@ # +$stderr.sync = true # +afile.sync = false # +#----------------------------- # +# assume 'remote_con' is an interactive socket handle, # +# but 'disk_file' is a handle to a regular file. # +remote_con.sync = true # unbuffer for clarity # +disk_file.sync = false # buffered for speed # +#----------------------------- # +require 'socket' # +sock = TCPSocket.new('www.ruby-lang.org', 80) # +sock.sync = true # +sock.puts "GET /en/ HTTP/1.0 \n\n" # +resp = sock.read # +print "DOC IS: #{resp}\n" # + # + # +# @@PLEAC@@_7.13 # +#----------------------------- # +# assumes fh1, fh2, fh2 are oen IO objects # +nfound = select([$stdin, fh1, fh2, fh3], nil, nil, 0) # +nfound[0].each do |file| # + case file # + when fh1 # + # do something with fh1 # + when fh2 # + # do something with fh2 # + when fh3 # + # do something with fh3 # + end # +end # +#----------------------------- # +input_files = [] # +# repeat next line for all in-files to poll # +input_files << fh1 # +if nfound = select(input_files, nil, nil, 0) # + # input ready on files in nfound[0] # +end # # # # @@PLEAC@@_8.0