From 3ebf148bf3d82d25e690aec6ec49975e0837e604 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Tue, 28 Jul 2009 19:56:34 +0200 Subject: Enhance selector and case statements to match with regexp The case and selector statements define ephemeral vars, like 'if'. Usage: case statement: $var = "foobar" case $var { "foo": { notify { "got a foo": } } /(.*)bar$/: { notify{ "hey we got a $1": } } } and for selector: $val = $test ? { /^match.*$/ => "matched", default => "default" } Signed-off-by: Brice Figureau --- lib/puppet/parser/ast/caseopt.rb | 10 ++++++++ lib/puppet/parser/ast/casestatement.rb | 37 +++++++++--------------------- lib/puppet/parser/ast/selector.rb | 42 ++++++++++------------------------ 3 files changed, 33 insertions(+), 56 deletions(-) (limited to 'lib/puppet/parser/ast') diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb index 824bde853..47f32e2ee 100644 --- a/lib/puppet/parser/ast/caseopt.rb +++ b/lib/puppet/parser/ast/caseopt.rb @@ -51,6 +51,16 @@ class Puppet::Parser::AST end end + def eachopt + if @value.is_a?(AST::ASTArray) + @value.each { |subval| + yield subval + } + else + yield @value + end + end + # Evaluate the actual statements; this only gets called if # our option matched. def evaluate(scope) diff --git a/lib/puppet/parser/ast/casestatement.rb b/lib/puppet/parser/ast/casestatement.rb index 072747932..25b0fc691 100644 --- a/lib/puppet/parser/ast/casestatement.rb +++ b/lib/puppet/parser/ast/casestatement.rb @@ -20,36 +20,21 @@ class Puppet::Parser::AST # Iterate across the options looking for a match. default = nil - @options.each { |option| - option.eachvalue(scope) { |opval| - opval = opval.downcase if ! sensitive and opval.respond_to?(:downcase) - if opval == value - found = true - break - end - } - - if found - # we found a matching option - retvalue = option.safeevaluate(scope) - break + @options.each do |option| + option.eachopt do |opt| + return option.safeevaluate(scope) if opt.evaluate_match(value, scope, :file => file, :line => line, :sensitive => sensitive) end - if option.default? - default = option - end - } + default = option if option.default? + end # Unless we found something, look for the default. - unless found - if default - retvalue = default.safeevaluate(scope) - else - Puppet.debug "No true answers and no default" - retvalue = nil - end - end - return retvalue + return default.safeevaluate(scope) if default + + Puppet.debug "No true answers and no default" + return nil + ensure + scope.unset_ephemeral_var end def each diff --git a/lib/puppet/parser/ast/selector.rb b/lib/puppet/parser/ast/selector.rb index ecad163d4..1b05f57f0 100644 --- a/lib/puppet/parser/ast/selector.rb +++ b/lib/puppet/parser/ast/selector.rb @@ -12,17 +12,12 @@ class Puppet::Parser::AST # Find the value that corresponds with the test. def evaluate(scope) - retvalue = nil - found = nil - # Get our parameter. paramvalue = @param.safeevaluate(scope) sensitive = Puppet[:casesensitive] - if ! sensitive and paramvalue.respond_to?(:downcase) - paramvalue = paramvalue.downcase - end + paramvalue = paramvalue.downcase if not sensitive and paramvalue.respond_to?(:downcase) default = nil @@ -31,33 +26,20 @@ class Puppet::Parser::AST end # Then look for a match in the options. - @values.each { |obj| - param = obj.param.safeevaluate(scope) - if ! sensitive && param.respond_to?(:downcase) - param = param.downcase - end - if param == paramvalue - # we found a matching option - retvalue = obj.value.safeevaluate(scope) - found = true - break - elsif obj.param.is_a?(Default) - # Store the default, in case it's necessary. - default = obj - end - } + @values.each do |obj| + # short circuit asap if we have a match + return obj.value.safeevaluate(scope) if obj.param.evaluate_match(paramvalue, scope, :file => file, :line => line, :sensitive => sensitive) - # Unless we found something, look for the default. - unless found - if default - retvalue = default.value.safeevaluate(scope) - else - self.fail Puppet::ParseError, - "No matching value for selector param '%s'" % paramvalue - end + # Store the default, in case it's necessary. + default = obj if obj.param.is_a?(Default) end - return retvalue + # Unless we found something, look for the default. + return default.value.safeevaluate(scope) if default + + self.fail Puppet::ParseError, "No matching value for selector param '%s'" % paramvalue + ensure + scope.unset_ephemeral_var end end end -- cgit