-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7b07a4f
commit e8521fb
Showing
10 changed files
with
581 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include "pcrenet.h" | ||
|
||
typedef struct | ||
{ | ||
pcre2_code* code; | ||
uint16_t* subject; | ||
uint32_t subject_length; | ||
uint32_t start_index; | ||
uint32_t additional_options; | ||
uint16_t* replacement; | ||
uint32_t replacement_length; | ||
} pcrenet_substitute_input; | ||
|
||
typedef struct | ||
{ | ||
int32_t result_code; | ||
uint16_t* output; | ||
uint32_t output_length; | ||
} pcrenet_substitute_result; | ||
|
||
PCRENET_EXPORT(void, substitute)(const pcrenet_substitute_input* input, pcrenet_substitute_result* result) | ||
{ | ||
pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(input->code, NULL); | ||
pcre2_match_context* context = pcre2_match_context_create(NULL); | ||
|
||
PCRE2_SIZE output_length = 0; | ||
|
||
// Treat result as invalid | ||
result->output = NULL; | ||
result->output_length = 0; | ||
|
||
result->result_code = pcre2_substitute( | ||
input->code, | ||
input->subject, | ||
input->subject_length, | ||
input->start_index, | ||
input->additional_options | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, | ||
match_data, | ||
context, | ||
input->replacement, | ||
input->replacement_length, | ||
NULL, | ||
&output_length | ||
); | ||
|
||
if (result->result_code == PCRE2_ERROR_NOMEMORY) | ||
{ | ||
result->output = malloc(output_length * sizeof(PCRE2_UCHAR)); | ||
|
||
result->result_code = pcre2_substitute( | ||
input->code, | ||
input->subject, | ||
input->subject_length, | ||
input->start_index, | ||
input->additional_options | PCRE2_NO_UTF_CHECK, | ||
match_data, | ||
context, | ||
input->replacement, | ||
input->replacement_length, | ||
result->output, | ||
&output_length | ||
); | ||
|
||
result->output_length = result->result_code >= 0 ? output_length : 0; | ||
} | ||
|
||
pcre2_match_context_free(context); | ||
pcre2_match_data_free(match_data); | ||
} | ||
|
||
PCRENET_EXPORT(void, substitute_result_free)(pcrenet_substitute_result* result) | ||
{ | ||
if (!result) | ||
return; | ||
|
||
if (result->output) | ||
{ | ||
free(result->output); | ||
result->output = NULL; | ||
} | ||
|
||
result->output_length = 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using NUnit.Framework; | ||
|
||
namespace PCRE.Tests.PcreNet; | ||
|
||
[TestFixture] | ||
public class SubstituteTests | ||
{ | ||
[Test] | ||
[TestCase("foo", "bar", "foo")] | ||
[TestCase("abbc", "bar", "bar")] | ||
[TestCase(" abc abc ", "bar", " bar abc ")] | ||
[TestCase(" abbbc abc ", "$1", " bbb abc ")] | ||
public void should_substitute_default(string subject, string replacement, string result) | ||
{ | ||
var re = new PcreRegex("a(b+)c"); | ||
|
||
Assert.That(re.Substitute(subject, replacement), Is.EqualTo(result)); | ||
} | ||
|
||
[Test] | ||
[TestCase("foo", "bar", "foo")] | ||
[TestCase("abbc", "bar", "bar")] | ||
[TestCase(" abc abc ", "bar", " bar bar ")] | ||
[TestCase(" abbbc abc ", "$1", " bbb b ")] | ||
[TestCase(" abbbc abc ", "$1$$", " bbb$ b$ ")] | ||
public void should_substitute_global(string subject, string replacement, string result) | ||
{ | ||
var re = new PcreRegex("a(b+)c"); | ||
|
||
Assert.That(re.Substitute(subject, replacement, PcreSubstituteOptions.SubstituteGlobal), Is.EqualTo(result)); | ||
} | ||
|
||
[Test] | ||
[TestCase("foo", "$1", "foo")] | ||
[TestCase("abbc", "$1", "$1")] | ||
[TestCase(" abbbc abc ", "$1", " $1 abc ")] | ||
public void should_substitute_literal(string subject, string replacement, string result) | ||
{ | ||
var re = new PcreRegex("a(b+)c"); | ||
|
||
Assert.That(re.Substitute(subject, replacement, PcreSubstituteOptions.SubstituteLiteral), Is.EqualTo(result)); | ||
} | ||
|
||
[Test] | ||
[TestCase("foo", "$1", "")] | ||
[TestCase("abbc", "$1", "bb")] | ||
[TestCase(" abbbc abc ", "$1", "bbb")] | ||
public void should_substitute_replacement_only(string subject, string replacement, string result) | ||
{ | ||
var re = new PcreRegex("a(b+)c"); | ||
|
||
Assert.That(re.Substitute(subject, replacement, PcreSubstituteOptions.SubstituteReplacementOnly), Is.EqualTo(result)); | ||
} | ||
|
||
[Test] | ||
public void should_substitute_mark() | ||
{ | ||
Assert.That( | ||
new PcreRegex("(*MARK:pear)apple|(*MARK:orange)lemon").Substitute("apple lemon", "${*MARK}", PcreSubstituteOptions.SubstituteGlobal), | ||
Is.EqualTo("pear orange") | ||
); | ||
} | ||
|
||
[Test] | ||
public void should_substitute_extended() | ||
{ | ||
var re = new PcreRegex("(some)?(body)"); | ||
|
||
Assert.That( | ||
re.Substitute("body", @"${1:+\U:\L}HeLLo", PcreSubstituteOptions.SubstituteExtended), | ||
Is.EqualTo("hello") | ||
); | ||
|
||
Assert.That( | ||
re.Substitute("somebody", @"${1:+\U:\L}HeLLo", PcreSubstituteOptions.SubstituteExtended), | ||
Is.EqualTo("HELLO") | ||
); | ||
} | ||
|
||
[Test] | ||
public void should_substitute_from_start_offset() | ||
{ | ||
Assert.That( | ||
new PcreRegex("a(b+)c").Substitute("abc abc abc", "match", PcreSubstituteOptions.SubstituteGlobal, 4), | ||
Is.EqualTo("abc match match") | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.