e127705df82ce75b4cf7a5a8098ca3dc9e7dc36d
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / is_numeric.rb
1 #
2 # is_numeric.rb
3 #
4 module Puppet::Parser::Functions
5   newfunction(:is_numeric, :type => :rvalue, :doc => <<-DOC
6     Returns true if the given argument is a Numeric (Integer or Float),
7     or a String containing either a valid integer in decimal base 10 form, or
8     a valid floating point string representation.
9
10     The function recognizes only decimal (base 10) integers and float but not
11     integers in hex (base 16) or octal (base 8) form.
12
13     The string representation may start with a '-' (minus). If a decimal '.' is used,
14     it must be followed by at least one digit.
15
16     Valid examples:
17
18       77435
19       10e-12
20       -8475
21       0.2343
22       -23.561e3
23     DOC
24              ) do |arguments|
25
26     function_deprecation([:is_numeric, 'This method is deprecated, please use the stdlib validate_legacy function,
27                           with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.'])
28
29     if arguments.size != 1
30       raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments given #{arguments.size} for 1")
31     end
32
33     value = arguments[0]
34
35     # Regex is taken from the lexer of puppet
36     # puppet/pops/parser/lexer.rb but modified to match also
37     # negative values and disallow invalid octal numbers or
38     # numbers prefixed with multiple 0's (except in hex numbers)
39     #
40     # TODO these parameters should be constants but I'm not sure
41     # if there is no risk to declare them inside of the module
42     # Puppet::Parser::Functions
43
44     # TODO: decide if this should be used
45     # HEX numbers like
46     # 0xaa230F
47     # 0X1234009C
48     # 0x0012
49     # -12FcD
50     # numeric_hex = %r{^-?0[xX][0-9A-Fa-f]+$}
51
52     # TODO: decide if this should be used
53     # OCTAL numbers like
54     # 01234567
55     # -045372
56     # numeric_oct = %r{^-?0[1-7][0-7]*$}
57
58     # Integer/Float numbers like
59     # -0.1234568981273
60     # 47291
61     # 42.12345e-12
62     numeric = %r{^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$}
63
64     if value.is_a?(Numeric) || (value.is_a?(String) &&
65       value.match(numeric) # or
66                                  #  value.match(numeric_hex) or
67                                  #  value.match(numeric_oct)
68                                )
69       return true
70     else
71       return false
72     end
73   end
74 end