diff options
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | lib/puppet/parser/functions/regsubst.rb | 93 | ||||
-rw-r--r-- | spec/unit/parser/functions/regsubst.rb | 88 |
3 files changed, 183 insertions, 0 deletions
@@ -1,4 +1,6 @@ 0.24.8 + Fixed #1830 - Added regsubst function + Updated up2date and service confines to add support for Oracle EL and VM Fixing #1948 and #1953 - augeas ins bug: wrong number of arguments (1 for 3) diff --git a/lib/puppet/parser/functions/regsubst.rb b/lib/puppet/parser/functions/regsubst.rb new file mode 100644 index 000000000..067d75c51 --- /dev/null +++ b/lib/puppet/parser/functions/regsubst.rb @@ -0,0 +1,93 @@ +module Puppet::Parser::Functions + newfunction(:regsubst, :type => :rvalue, + :doc => "\ + Perform regexp replacement on a string. + + Parameters (in order): + + :str: + The string to operate on. + + :regexp: + The regular expression matching the 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 occurances of the regexp in + the string will be replaced. Without this, only the + first occurance 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| + flag_mapping = { + "E" => Regexp::EXTENDED, + "I" => Regexp::IGNORECASE, + "M" => Regexp::MULTILINE, + } + if args.length < 3 or args.length > 5 + raise Puppet::ParseError, ("regsub(): wrong number of arguments" + + " (#{args.length}; min 3, max 5)") + end + str, regexp, replacement, flags, lang = args + reflags = 0 + global = false + (flags or "").each_byte do |f| + f = f.chr + if f == "G" + global = true + else + fvalue = flag_mapping[f] + if !fvalue + raise Puppet::ParseError, "regsub(): bad flag `#{f}'" + end + reflags |= fvalue + end + end + re = Regexp.compile(regexp, reflags, lang) + if global + result = str.gsub(re, replacement) + else + result = str.sub(re, replacement) + end + return result + end +end diff --git a/spec/unit/parser/functions/regsubst.rb b/spec/unit/parser/functions/regsubst.rb new file mode 100644 index 000000000..18f49f7d4 --- /dev/null +++ b/spec/unit/parser/functions/regsubst.rb @@ -0,0 +1,88 @@ +#! /usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the regsubst function" do + + before :each do + @scope = Puppet::Parser::Scope.new() + end + + it "should exist" do + Puppet::Parser::Functions.function("regsubst").should == "function_regsubst" + end + + it "should raise a ParseError if there is less than 3 arguments" do + lambda { @scope.function_regsubst(["foo", "bar"]) }.should( + raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there is more than 5 arguments" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( + raise_error(Puppet::ParseError)) + end + + + it "should raise a ParseError when given a bad flag" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( + raise_error(Puppet::ParseError)) + end + + it "should handle groups" do + result = @scope.function_regsubst( + [ '130.236.254.10', + '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', + '\4-\3-\2-\1' + ]) + result.should(eql("10-254-236-130")) + end + + it "should handle simple regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks banana trees", + "b[an]*a", + "coconut" + ]) + result.should(eql("the monkey breaks coconut trees")) + end + + it "should handle case-sensitive regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks baNAna trees", + "b[an]+a", + "coconut" + ]) + result.should(eql("the monkey breaks baNAna trees")) + end + + it "should handle case-insensitive regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks baNAna trees", + "b[an]+a", + "coconut", + "I" + ]) + result.should(eql("the monkey breaks coconut trees")) + end + + it "should handle global substitutions" do + result = @scope.function_regsubst( + [ "the monkey breaks\tbanana trees", + "[ \t]", + "--", + "G" + ]) + result.should(eql("the--monkey--breaks--banana--trees")) + end + + it "should handle global substitutions with groups" do + result = @scope.function_regsubst( + [ '130.236.254.10', + '([0-9]+)', + '<\1>', + 'G' + ]) + result.should(eql('<130>.<236>.<254>.<10>')) + end + +end |