summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/blink/type/typegen.rb18
-rw-r--r--lib/blink/type/typegen/filerecord.rb83
-rw-r--r--lib/blink/type/typegen/filetype.rb62
-rw-r--r--test/types/tc_filetype.rb63
4 files changed, 191 insertions, 35 deletions
diff --git a/lib/blink/type/typegen.rb b/lib/blink/type/typegen.rb
index 63bca953d..9643d8462 100644
--- a/lib/blink/type/typegen.rb
+++ b/lib/blink/type/typegen.rb
@@ -62,13 +62,15 @@ class Blink::Type::TypeGenerator < Blink::Type
[key,self]
end
}
- @options.each { |option|
- unless arghash.include?(option)
- p arghash
- raise "Must pass %s to class %s" %
- [option,self]
- end
- }
+
+ # turn off automatically checking all arguments
+ #@options.each { |option|
+ # unless arghash.include?(option)
+ # p arghash
+ # raise "Must pass %s to class %s" %
+ # [option,self]
+ # end
+ #}
if @subclasses.include?(arghash[:name])
raise "File type %s already exists" % arghash[:name]
@@ -85,7 +87,7 @@ class Blink::Type::TypeGenerator < Blink::Type
@subclasses[arghash[:name]] = klass
- @options.each { |option|
+ arghash.each { |option,value|
method = option.id2name + "="
if klass.respond_to?(method)
#Blink.debug "Setting %s on %s to '%s'" % [option,klass,arghash[option]]
diff --git a/lib/blink/type/typegen/filerecord.rb b/lib/blink/type/typegen/filerecord.rb
index a60bf01b8..e7d145d81 100644
--- a/lib/blink/type/typegen/filerecord.rb
+++ b/lib/blink/type/typegen/filerecord.rb
@@ -12,7 +12,7 @@ require 'blink/type/typegen'
class Blink::Type::FileRecord < Blink::Type::TypeGenerator
attr_accessor :fields, :namevar, :splitchar, :object
- @options = [:name, :splitchar, :fields, :namevar, :filetype]
+ @options = [:name, :splitchar, :fields, :namevar, :filetype, :regex, :joinchar]
@abstract = true
@name = :filerecord
@@ -52,13 +52,35 @@ class Blink::Type::FileRecord < Blink::Type::TypeGenerator
#---------------------------------------------------------------
#---------------------------------------------------------------
+ def FileRecord.joinchar=(char)
+ @joinchar = char
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
+ def FileRecord.joinchar
+ unless defined? @joinchar
+ @joinchar = nil
+ end
+ @joinchar
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
def FileRecord.match(object,line)
- if @regex.match(line)
+ matchobj = nil
+ begin
+ matchobj = self.regex.match(line)
+ rescue RegexpError => detail
+ raise
+ end
+
+ if matchobj.nil?
+ return nil
+ else
child = self.new(object)
- child.record = line
+ child.match = matchobj
return child
- else
- return nil
end
end
#---------------------------------------------------------------
@@ -76,7 +98,37 @@ class Blink::Type::FileRecord < Blink::Type::TypeGenerator
#---------------------------------------------------------------
#---------------------------------------------------------------
+ def FileRecord.regex=(regex)
+ @regex = regex
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
def FileRecord.regex
+ # the only time @regex is allowed to be nil is if @splitchar is defined
+ if @regex.nil?
+ if @splitchar.nil?
+ raise "%s defined incorrectly -- splitchar or regex must be specified" %
+ self
+ else
+ ary = []
+ text = @fields.collect { |field|
+ "([^%s]*)" % @splitchar
+ }.join(@splitchar)
+ begin
+ @regex = Regexp.new(text)
+ rescue RegexpError => detail
+ raise "Could not create splitregex from %s" % @splitchar
+ end
+ Blink.debug("Created regexp %s" % @regex)
+ end
+ elsif @regex.is_a?(String)
+ begin
+ @regex = Regexp.new(@regex)
+ rescue RegexpError => detail
+ raise "Could not create splitregex from %s" % @regex
+ end
+ end
return @regex
end
#---------------------------------------------------------------
@@ -84,7 +136,7 @@ class Blink::Type::FileRecord < Blink::Type::TypeGenerator
#---------------------------------------------------------------
def FileRecord.splitchar=(char)
@splitchar = char
- @regex = %r{#{char}}
+ #@regex = %r{#{char}}
end
#---------------------------------------------------------------
@@ -136,8 +188,23 @@ class Blink::Type::FileRecord < Blink::Type::TypeGenerator
#---------------------------------------------------------------
#---------------------------------------------------------------
+ def match=(matchobj)
+ @match = matchobj
+ #puts "captures are [%s]" % [matchobj.captures]
+ self.class.fields.zip(matchobj.captures) { |field,value|
+ @fields[field] = value
+ #puts "%s => %s" % [field,@fields[field]]
+ }
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
def record=(record)
- ary = record.split(self.class.regex)
+ begin
+ ary = record.split(self.class.regex)
+ rescue RegexpError=> detail
+ raise RegexpError.new(detail)
+ end
self.class.fields.each { |field|
@fields[field] = ary.shift
#puts "%s => %s" % [field,@fields[field]]
@@ -163,7 +230,7 @@ class Blink::Type::FileRecord < Blink::Type::TypeGenerator
else
@fields[field]
end
- }.join(self.class.splitchar)
+ }.join(self.class.joinchar || self.class.splitchar)
end
#---------------------------------------------------------------
end
diff --git a/lib/blink/type/typegen/filetype.rb b/lib/blink/type/typegen/filetype.rb
index 80530aaea..3140c2e79 100644
--- a/lib/blink/type/typegen/filetype.rb
+++ b/lib/blink/type/typegen/filetype.rb
@@ -10,7 +10,7 @@ require 'blink/type/typegen'
class Blink::Type::FileType < Blink::Type::TypeGenerator
attr_accessor :childtype
- @options = [:name, :linesplit]
+ @options = [:name, :linesplit, :escapednewlines]
@abstract = true
@name = :filetype
@@ -46,6 +46,12 @@ class Blink::Type::FileType < Blink::Type::TypeGenerator
@records = {}
end
hash[:filetype] = self
+
+ # default to the naming field being the first field provided
+ unless hash.include?(:namevar)
+ hash[:namevar] = hash[:fields][0]
+ end
+
recordtype = Blink::Type::FileRecord.newtype(hash)
@records[recordtype.name] = recordtype
end
@@ -58,6 +64,22 @@ class Blink::Type::FileType < Blink::Type::TypeGenerator
#---------------------------------------------------------------
#---------------------------------------------------------------
+ def FileType.escapednewlines=(value)
+ @escnlines = value
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
+ def FileType.escapednewlines
+ if @escnlines.nil?
+ return false
+ else
+ return @escnlines
+ end
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
def FileType.childtype
unless defined? @childtype
@childtype = nil
@@ -189,6 +211,12 @@ class Blink::Type::FileType < Blink::Type::TypeGenerator
#---------------------------------------------------------------
#---------------------------------------------------------------
+ def name
+ return @file
+ end
+ #---------------------------------------------------------------
+
+ #---------------------------------------------------------------
# read the whole file in and turn it into each of the appropriate
# objects
def retrieve
@@ -199,24 +227,42 @@ class Blink::Type::FileType < Blink::Type::TypeGenerator
}
}
+ if self.class.escapednewlines
+ endreg = %r{\\\n\s*}
+ str.gsub!(endreg,'')
+ end
@childary = str.split(self.class.regex).collect { |line|
- childobj = self.class.records.each { |name,recordtype|
- if child = recordtype.match(self,line)
- break child
+ childobj = nil
+ self.class.records.each { |name,recordtype|
+ if childobj = recordtype.match(self,line)
+ break
end
}
- #child = self.class.childtype.new(self)
- #child.record = record
- #puts "adding child %s" % child.name
if childobj.nil?
Blink.warning("%s: could not match %s" % [self.name,line])
+ #Blink.warning("could not match %s" % line)
next
end
+
+ begin
+ Blink.debug("got child: %s(%s)" % [childobj.class,childobj.to_s])
+ rescue NoMethodError
+ Blink.warning "Failed: %s" % childobj
+ end
childobj
+ }.reject { |child|
+ child.nil?
}
@childary.each { |child|
- @childhash[child.name] = child
+ begin
+ @childhash[child.name] = child
+ rescue NoMethodError => detail
+ p child
+ p child.class
+ puts detail
+ exit
+ end
}
end
#---------------------------------------------------------------
diff --git a/test/types/tc_filetype.rb b/test/types/tc_filetype.rb
index a8226275d..64e62c749 100644
--- a/test/types/tc_filetype.rb
+++ b/test/types/tc_filetype.rb
@@ -24,23 +24,35 @@ class TestFileType < Test::Unit::TestCase
@passwdtype.addrecord(
:name => "user",
:splitchar => ":",
- :fields => %w{name password uid gid gcos home shell},
- :namevar => "name"
+ :fields => %w{name password uid gid gcos home shell}
)
}
end
- @passwdtype = Blink::Type::FileType["passwd"]
- if @passwdtype.nil?
+ @syslogtype = Blink::Type::FileType["syslog"]
+ if @syslogtype.nil?
assert_nothing_raised() {
- @passwdtype = Blink::Type::FileType.newtype(
- :name => "passwd"
+ @syslogtype = Blink::Type::FileType.newtype(
+ :escapednewlines => true,
+ :name => "syslog"
)
- @passwdtype.addrecord(
- :name => "user",
- :splitchar => ":",
- :fields => %w{name password uid gid gcos home shell},
- :namevar => "name"
+ @syslogtype.addrecord(
+ :name => "data",
+ :regex => %r{^([^#\s]+)\s+(\S+)$},
+ :joinchar => "\t",
+ :fields => %w{logs dest}
+ )
+ @syslogtype.addrecord(
+ :name => "comment",
+ :regex => %r{^(#.*)$},
+ :joinchar => "", # not really necessary...
+ :fields => %w{comment}
+ )
+ @syslogtype.addrecord(
+ :name => "blank",
+ :regex => %r{^(\s*)$},
+ :joinchar => "", # not really necessary...
+ :fields => %w{blank}
)
}
end
@@ -120,4 +132,33 @@ class TestFileType < Test::Unit::TestCase
Kernel.system("rm /tmp/oparsepasswd")
end
+
+ def test_syslog_nochange
+ file = nil
+ type = nil
+ assert_nothing_raised() {
+ file = @syslogtype.new("/etc/syslog.conf")
+ }
+ assert_nothing_raised() {
+ file.retrieve
+ }
+
+ assert(file.insync?)
+
+ contents = ""
+ ::File.open("/etc/syslog.conf") { |ofile|
+ ofile.each { |line|
+ contents += line
+ }
+ }
+
+ file.each { |record|
+ puts "%s [%s]" % [record.class,record]
+ }
+ #assert_equal(
+ # contents,
+ # file.to_s
+ #)
+
+ end
end