Skip to content

Commit

Permalink
Add functions to get the substring found by regExpMatch().
Browse files Browse the repository at this point in the history
For now this is only used in testing but there are places where it could be useful in the core code.

Even if that turns out not to be true, it doesn't seem worth implementing a new version in testing just to capture a few values that we already have.
  • Loading branch information
dwsteele committed Dec 5, 2019
1 parent 053af2f commit b2d82bd
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
59 changes: 57 additions & 2 deletions src/common/regExp.c
Expand Up @@ -18,6 +18,8 @@ struct RegExp
{
MemContext *memContext;
regex_t regExp;
const char *matchPtr;
size_t matchSize;
};

OBJECT_DEFINE_FREE(REGEXP);
Expand Down Expand Up @@ -73,7 +75,7 @@ regExpNew(const String *expression)
// Compile the regexp and process errors
int result = 0;

if ((result = regcomp(&this->regExp, strPtr(expression), REG_NOSUB | REG_EXTENDED)) != 0)
if ((result = regcomp(&this->regExp, strPtr(expression), REG_EXTENDED)) != 0)
{
memFree(this);
regExpError(result);
Expand Down Expand Up @@ -102,14 +104,67 @@ regExpMatch(RegExp *this, const String *string)
ASSERT(string != NULL);

// Test for a match
int result = regexec(&this->regExp, strPtr(string), 0, NULL, 0);
regmatch_t matchPtr;
int result = regexec(&this->regExp, strPtr(string), 1, &matchPtr, 0);

// Check for an error
regExpError(result);

// Store match results
if (result == 0)
{
this->matchPtr = strPtr(string) + matchPtr.rm_so;
this->matchSize = (size_t)(matchPtr.rm_eo - matchPtr.rm_so);
}
// Else reset match results
else
{
this->matchPtr = NULL;
this->matchSize = 0;
}

FUNCTION_TEST_RETURN(result == 0);
}

/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
const char *
regExpMatchPtr(RegExp *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(REGEXP, this);
FUNCTION_TEST_END();

ASSERT(this != NULL);

FUNCTION_TEST_RETURN(this->matchPtr);
}

size_t
regExpMatchSize(RegExp *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(REGEXP, this);
FUNCTION_TEST_END();

ASSERT(this != NULL);

FUNCTION_TEST_RETURN(this->matchSize);
}

String *
regExpMatchStr(RegExp *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(REGEXP, this);
FUNCTION_TEST_END();

ASSERT(this != NULL);

FUNCTION_TEST_RETURN(this->matchPtr == NULL ? NULL : strNewN(regExpMatchPtr(this), regExpMatchSize(this)));
}

/***********************************************************************************************************************************
Match a regular expression in one call for brevity
***********************************************************************************************************************************/
Expand Down
12 changes: 12 additions & 0 deletions src/common/regExp.h
Expand Up @@ -24,6 +24,18 @@ void regExpFree(RegExp *this);
bool regExpMatchOne(const String *expression, const String *string);
String *regExpPrefix(const String *expression);

/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
// Get pointer to the last match. NULL if there was no match.
const char *regExpMatchPtr(RegExp *this);

// Get size of the last match. 0 if there was no match.
size_t regExpMatchSize(RegExp *this);

// Get the last match as a String. NULL if there was no match.
String *regExpMatchStr(RegExp *this);

/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
Expand Down
23 changes: 22 additions & 1 deletion test/src/module/common/regExpTest.c
Expand Up @@ -24,10 +24,31 @@ testRun(void)
}
TRY_END();

// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("new regexp");

RegExp *regExp = NULL;
TEST_ASSIGN(regExp, regExpNew(strNew("^abc")), "new regexp");
TEST_RESULT_BOOL(regExpMatch(regExp, strNew("abcdef")), true, "match regexp");

// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("regexp match");

const String *string = STRDEF("abcdef");
TEST_RESULT_BOOL(regExpMatch(regExp, string), true, "match regexp");
TEST_RESULT_PTR(regExpMatchPtr(regExp), strPtr(string), "check ptr");
TEST_RESULT_SIZE(regExpMatchSize(regExp), 3, "check size");
TEST_RESULT_STR_Z(regExpMatchStr(regExp), "abc", "check str");

// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("no regexp match");

TEST_RESULT_BOOL(regExpMatch(regExp, strNew("bcdef")), false, "no match regexp");
TEST_RESULT_PTR(regExpMatchPtr(regExp), NULL, "check ptr");
TEST_RESULT_SIZE(regExpMatchSize(regExp), 0, "check size");
TEST_RESULT_PTR(regExpMatchStr(regExp), NULL, "check str");

// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("free regexp");

TEST_RESULT_VOID(regExpFree(regExp), "free regexp");
}
Expand Down

0 comments on commit b2d82bd

Please sign in to comment.