summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast/casestatement.rb
blob: b4197d9b4289f9c8f84d482c52a3f126b0ae1bfb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
require 'puppet/parser/ast/branch'

class Puppet::Parser::AST
    # The basic logical structure in Puppet.  Supports a list of
    # tests and statement arrays.
    class CaseStatement < AST::Branch
        attr_accessor :test, :options, :default

        # Short-curcuit evaluation.  Return the value of the statements for
        # the first option that matches.
        def evaluate(hash)
            scope = hash[:scope]
            value = @test.safeevaluate(:scope => scope)
            sensitive = Puppet[:casesensitive]
            value = value.downcase if ! sensitive and value.respond_to?(:downcase)

            retvalue = nil
            found = false
            
            # Iterate across the options looking for a match.
            @options.each { |option|
                if option.eachvalue(scope) { |opval|
                        opval = opval.downcase if ! sensitive and opval.respond_to?(:downcase)
                        # break true if opval == value
                        if opval == value
                            break true
                        end
                    }
                    # we found a matching option
                    retvalue = option.safeevaluate(:scope => scope)
                    found = true
                    break
                end
            }

            # Unless we found something, look for the default.
            unless found
                if defined? @default
                    retvalue = @default.safeevaluate(:scope => scope)
                else
                    Puppet.debug "No true answers and no default"
                    retvalue = nil
                end
            end
            return retvalue
        end

        # Do some input validation on our options.
        def initialize(hash)
            values = {}

            super

            # This won't work if we move away from only allowing
            # constants here, but for now, it's fine and useful.
            @options.each { |option|
                unless option.is_a?(CaseOpt)
                    raise Puppet::DevError, "Option is not a CaseOpt"
                end
                if option.default?
                    @default = option
                end
                option.eachvalue(nil) { |val|
                    if values.include?(val)
                        raise Puppet::ParseError,
                            "Value %s appears twice in case statement" %
                                val
                    else
                        values[val] = true
                    end
                }
            }
        end

        def tree(indent = 0)
            rettree = [
                @test.tree(indent + 1),
                ((@@indline * indent) + self.typewrap(self.pin)),
                @options.tree(indent + 1)
            ]

            return rettree.flatten.join("\n")
        end

        def each
            [@test,@options].each { |child| yield child }
        end
    end

end