#!/usr/bin/ruby -w
# -*- ruby -*-
require './regexp'
require './log'
# Represents .p4ignore files, which are modeled on .cvsignore files.
class IgnoredPatterns < Hash
include Log
def initialize(ignorename)
@ignorename = ignorename
@dirsread = Array.new
end
def read(dir)
# from the CVS default settings -- ignoring overrides
log "reading ignored patterns for " + dir
return if @dirsread.include?(dir)
@dirsread.push(dir)
pats = %w{
CVS
*~
.p4ignore
.p4config
*.o
*$
*.BAK
*.Z
*.a
*.bak
*.elc
*.exe
*.ln
*.obj
*.olb
*.old
*.orig
*.rej
*.so
.
..
.del-*
.make.state
.nse_depinfo
CVS.adm
RCS
RCSLOG
SCCS
TAGS
_$*
core
cvslog.*
tags
}
# can't put these guys in the qw() list:
['.#*', '#*', ',*'].each { |p| pats.push(p) }
# read ~/<ignore>
homedir = ENV["HOME"] # unix
unless homedir # windows
homedir = ENV["HOMEDRIVE"]
homepath = ENV["HOMEPATH"]
if homepath then
if homedir then
homedir += homepath
else
homedir = homepath
end
end
end
global = read_ignore_file(homedir)
pats.push(*global) unless global.length == 0
# read <ignore> in the current directory
local = read_ignore_file(dir)
pats.push(*local) unless local.length == 0
# prepend the current directory to the patterns, contending with the fact
# that the directory might actually be a valid regular expression.
# wildcard if the pattern is a directory
pats = pats.collect do |p|
p += "/*" if File.directory?(dir + "/" + p)
p
end
qdir = Regexp.quote(dir)
pats = pats.collect do |p|
p = Regexp.unixre_to_string(p)
qdir + "/" + p
end
# make a regular expression for each one, to be the entire string (^...$)
self[dir] = Array.new
pats.each do |p|
re = Regexp.new("^" + p + "$")
# log "IgnoredPatterns: storing re " + re.source + " for dir " + dir
self[dir].push(re)
end
end
def read_ignore_file(dir)
pats = Array.new
if dir then
cifile = dir + "/" + @ignorename
if File.exists?(cifile)
IO.foreach(cifile) do |line|
line.chomp!
line.gsub!(/\+/, '\\+')
pats.push(*line.split)
end
else
log "no ignore file in " + dir
end
end
pats
end
# Returns if the file is ignored. Checks the name as both "./name" and "name".
def is_ignored?(name)
log "is_ignored?(" + name + ")"
if name.index("./") == 0
withpref, nopref = name, name.sub!("./", "")
else
withpref, nopref = "./" + name, name
end
[ withpref, nopref ].each do |name|
dir = name
log "dirs = " + keys.join(", ")
while dir = File.dirname(dir)
if include?(dir)
regexps = self[dir]
regexps.each do |re|
# log "matching " + name + " against " + re.source
# stop as soon as we find out it is ignored
return true if re.match(name)
end
else
log "dir " + dir + " is not included"
end
break if dir == "." # else we'll cycle continuously
end
end
return false # it's not ignored
end
end
syntax highlighted by Code2HTML, v. 0.9.1