0001-Add-regsubst-rvalue-function-bug-1830.patch

Patch implementing regsubst(), with unit tests. - Thomas Bellman, 01/28/2009 09:53 am

Download (5.4 kB)

b/lib/puppet/parser/functions/regsubst.rb
1
module Puppet::Parser::Functions
2
    newfunction(:regsubst, :type => :rvalue,
3
		:doc => "\
4
	Perform regexp replacement on a string.
5

  
6
	Parameters (in order):
7

  
8
	:str:
9
		The string to operate on.
10

  
11
	:regexp:
12
		The regular expression matching the string.  If you want it
13
		anchored at the start and/or end of the string, you must do
14
		that with ^ and $ yourself.
15

  
16
	:replacement:
17
		Replacement string.  Can contain back references to what was
18
		matched using \\0, \\1, and so on.
19

  
20
	:flags:
21
		Optional.  String of single letter flags for how the regexp
22
		is interpreted:
23

  
24
		- **E**
25
			Extended regexps
26
		- **I**
27
			Ignore case in regexps
28
		- **M**
29
			Multiline regexps
30
		- **G**
31
			Global replacement; all occurances of the regexp in
32
			the string will be replaced.  Without this, only the
33
			first occurance will be replaced.
34

  
35
	:lang:
36
		Optional.  How to handle multibyte characters.  A
37
		single-character string with the following values:
38

  
39
		- **N**
40
			None
41
		- **E**
42
			EUC
43
		- **S**
44
			SJIS
45
		- **U**
46
			UTF-8
47

  
48
	**Examples**
49

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

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

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

  
58
	    $x = regsubst($ipaddress, '([0-9]+)', '<\\\\1>', 'G')
59
	") \
60
    do |args|
61
	flag_mapping = {
62
	    "E" => Regexp::EXTENDED,
63
	    "I" => Regexp::IGNORECASE,
64
	    "M" => Regexp::MULTILINE,
65
	}
66
	if args.length < 3  or  args.length > 5
67
	    raise Puppet::ParseError, ("regsub(): wrong number of arguments" +
68
				       " (#{args.length}; min 3, max 5)")
69
	end
70
	str, regexp, replacement, flags, lang = args
71
	reflags = 0
72
	global = false
73
	(flags or "").each_byte do |f|
74
	    f = f.chr
75
	    if f == "G"
76
		global = true
77
	    else
78
		fvalue = flag_mapping[f]
79
		if !fvalue
80
		    raise Puppet::ParseError, "regsub(): bad flag `#{f}'"
81
		end
82
		reflags |= fvalue
83
	    end
84
	end
85
	re = Regexp.compile(regexp, reflags, lang)
86
	if global
87
	    result = str.gsub(re, replacement)
88
	else
89
	    result = str.sub(re, replacement)
90
	end
91
	return result
92
    end
93
end
b/spec/unit/parser/functions/regsubst.rb
1
#! /usr/bin/env ruby
2

  
3
require File.dirname(__FILE__) + '/../../../spec_helper'
4

  
5
describe "the regsubst function" do
6

  
7
    before :each do
8
        @scope = Puppet::Parser::Scope.new()
9
    end
10

  
11
    it "should exist" do
12
        Puppet::Parser::Functions.function("regsubst").should == "function_regsubst"
13
    end
14

  
15
    it "should raise a ParseError if there is less than 3 arguments" do
16
        lambda { @scope.function_regsubst(["foo", "bar"]) }.should(
17
		raise_error(Puppet::ParseError))
18
    end
19

  
20
    it "should raise a ParseError if there is more than 5 arguments" do
21
        lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should(
22
		raise_error(Puppet::ParseError))
23
    end
24

  
25

  
26
    it "should raise a ParseError when given a bad flag" do
27
        lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should(
28
		raise_error(Puppet::ParseError))
29
    end
30

  
31
    it "should handle groups" do
32
	result = @scope.function_regsubst(
33
		[ '130.236.254.10',
34
		  '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
35
		  '\4-\3-\2-\1'
36
		])
37
	result.should(eql("10-254-236-130"))
38
    end
39

  
40
    it "should handle simple regexps" do
41
	result = @scope.function_regsubst(
42
		[ "the monkey breaks banana trees",
43
		  "b[an]*a",
44
		  "coconut"
45
		])
46
	result.should(eql("the monkey breaks coconut trees"))
47
    end
48

  
49
    it "should handle case-sensitive regexps" do
50
	result = @scope.function_regsubst(
51
		[ "the monkey breaks baNAna trees",
52
		  "b[an]+a",
53
		  "coconut"
54
		])
55
	result.should(eql("the monkey breaks baNAna trees"))
56
    end
57

  
58
    it "should handle case-insensitive regexps" do
59
	result = @scope.function_regsubst(
60
		[ "the monkey breaks baNAna trees",
61
		  "b[an]+a",
62
		  "coconut",
63
		  "I"
64
		])
65
	result.should(eql("the monkey breaks coconut trees"))
66
    end
67

  
68
    it "should handle global substitutions" do
69
	result = @scope.function_regsubst(
70
		[ "the monkey breaks\tbanana trees",
71
		  "[ \t]",
72
		  "--",
73
		  "G"
74
		])
75
	result.should(eql("the--monkey--breaks--banana--trees"))
76
    end
77

  
78
    it "should handle global substitutions with groups" do
79
	result = @scope.function_regsubst(
80
		[ '130.236.254.10',
81
		  '([0-9]+)',
82
		  '<\1>',
83
		  'G'
84
		])
85
	result.should(eql('<130>.<236>.<254>.<10>'))
86
    end
87

  
88
end
0
-