summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/functions/regsubst.rb
blob: f655db7b3485b1cc2079c06db9ffdfa4cf55b755 (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
91
92
93
94
95
96
97
98
99
100
module Puppet::Parser::Functions

  newfunction(
  :regsubst, :type => :rvalue,

  :doc => "
  Perform regexp replacement on a string or array of strings.

* *Parameters* (in order):

    _target_  The string or array of strings to operate on.  If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.

    _regexp_  The regular expression matching the target string.  If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.

    _replacement_  Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.

    _flags_  Optional. String of single letter flags for how the regexp is interpreted:

        - *E*         Extended regexps
        - *I*         Ignore case in regexps
        - *M*         Multiline regexps
        - *G*         Global replacement; all occurrences of the regexp in each target string will be replaced.  Without this, only the first occurrence will be replaced.

    _lang_  Optional.  How to handle multibyte characters.  A single-character string with the following values:

        - *N*         None
        - *E*         EUC
        - *S*         SJIS
        - *U*         UTF-8

* *Examples*

Get the third octet from the node's IP address:

    $i3 = regsubst($ipaddress,'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$','\\3')

Put angle brackets around each octet in the node's IP address:

    $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
") \
  do |args|
    unless args.length.between?(3, 5)

      raise(
        Puppet::ParseError,

          "regsubst(): got #{args.length} arguments, expected 3 to 5")
    end
    target, regexp, replacement, flags, lang = args
    reflags = 0
    operation = :sub
    if flags == nil
      flags = []
    elsif flags.respond_to?(:split)
      flags = flags.split('')
    else

      raise(
        Puppet::ParseError,

          "regsubst(): bad flags parameter #{flags.class}:`#{flags}'")
    end
    flags.each do |f|
      case f
      when 'G' then operation = :gsub
      when 'E' then reflags |= Regexp::EXTENDED
      when 'I' then reflags |= Regexp::IGNORECASE
      when 'M' then reflags |= Regexp::MULTILINE
      else raise(Puppet::ParseError, "regsubst(): bad flag `#{f}'")
      end
    end
    begin
      re = Regexp.compile(regexp, reflags, lang)
    rescue RegexpError, TypeError

      raise(
        Puppet::ParseError,

          "regsubst(): Bad regular expression `#{regexp}'")
    end
    if target.respond_to?(operation)
      # String parameter -> string result
      result = target.send(operation, re, replacement)
    elsif target.respond_to?(:collect) and
      target.respond_to?(:all?) and
      target.all? { |e| e.respond_to?(operation) }
      # Array parameter -> array result
      result = target.collect { |e|
        e.send(operation, re, replacement)
      }
    else

      raise(
        Puppet::ParseError,

          "regsubst(): bad target #{target.class}:`#{target}'")
    end
    return result
  end
end