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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
require 'puppet/util/autoload'
require 'puppet/parser/scope'
module Puppet::Parser
module Functions
# A module for managing parser functions. Each specified function
# becomes an instance method on the Scope class.
@functions = {}
class << self
include Puppet::Util
end
def self.autoloader
unless defined? @autoloader
@autoloader = Puppet::Util::Autoload.new(self,
"puppet/parser/functions",
:wrap => false
)
end
@autoloader
end
# Create a new function type.
def self.newfunction(name, options = {}, &block)
name = symbolize(name)
if @functions.include? name
raise Puppet::DevError, "Function %s already defined" % name
end
# We want to use a separate, hidden module, because we don't want
# people to be able to call them directly.
unless defined? FCollection
eval("module FCollection; end")
end
ftype = options[:type] || :statement
unless ftype == :statement or ftype == :rvalue
raise Puppet::DevError, "Invalid statement type %s" % ftype.inspect
end
fname = "function_" + name.to_s
Puppet::Parser::Scope.send(:define_method, fname, &block)
# Someday we'll support specifying an arity, but for now, nope
#@functions[name] = {:arity => arity, :type => ftype}
@functions[name] = {:type => ftype, :name => fname}
if options[:doc]
@functions[name][:doc] = options[:doc]
end
end
# Remove a function added by newfunction
def self.rmfunction(name)
name = symbolize(name)
unless @functions.include? name
raise Puppet::DevError, "Function %s is not defined" % name
end
@functions.delete(name)
fname = "function_" + name.to_s
Puppet::Parser::Scope.send(:remove_method, fname)
end
# Determine if a given name is a function
def self.function(name)
name = symbolize(name)
unless @functions.include? name
autoloader.load(name)
end
if @functions.include? name
return @functions[name][:name]
else
return false
end
end
def self.functiondocs
autoloader.loadall
ret = ""
@functions.sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
#ret += "%s\n%s\n" % [name, hash[:type]]
ret += "%s\n%s\n" % [name, "-" * name.to_s.length]
if hash[:doc]
ret += Puppet::Util::Docs.scrub(hash[:doc])
else
ret += "Undocumented.\n"
end
ret += "\n\n- **Type**: %s\n\n" % hash[:type]
end
return ret
end
def self.functions
@functions.keys
end
# Determine if a given function returns a value or not.
def self.rvalue?(name)
name = symbolize(name)
if @functions.include? name
case @functions[name][:type]
when :statement: return false
when :rvalue: return true
end
else
return false
end
end
# Runs a newfunction to create a function for each of the log levels
Puppet::Util::Log.levels.each do |level|
newfunction(level, :doc => "Log a message on the server at level
#{level.to_s}.") do |vals|
send(level, vals.join(" "))
end
end
end
end
|