ENGINE-588: added strnstr for non-bsd systems

ENGINE-602
parent 3f353d1227
commit 07c633b39e

@ -198,6 +198,43 @@ size_t strlcat(char* dst, const char* src, size_t size) {
return retval;
}
char *strnstr(const char *big, const char *little, size_t len) {
if (big == NULL || little == NULL)
return NULL;
if (*little == '\0')
return (char*)big;
const char* curr_big = big;
size_t little_len = strlen(little);
size_t remaining = len;
const char* retval = NULL;
for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
// find first-char match
if (*curr_big != *little) {
continue;
}
retval = curr_big;
const char* inner_big = retval + 1;
const char* curr_little = little + 1;
int j;
for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
if (*inner_big != *curr_little) {
retval = NULL;
break;
}
}
if (retval)
break;
}
return (char*)retval;
}
#ifdef USE_NETPGP
// FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
int regnexec(const regex_t* preg, const char* string,
@ -449,4 +486,3 @@ const char *gpg_agent_conf(int reset)
return NULL;
}
#endif

@ -67,6 +67,7 @@ extern char* SystemDB;
#if !defined(BSD) && !defined(__APPLE__)
size_t strlcpy(char* dst, const char* src, size_t size);
size_t strlcat(char* dst, const char* src, size_t size);
char *strnstr(const char *big, const char *little, size_t len);
// N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
// the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is

@ -283,6 +283,41 @@ size_t strlcat(char* dst, const char* src, size_t size) {
dst[start_len + size_to_copy] = '\0';
return retval;
}
char *strnstr(const char *big, const char *little, size_t len) {
if (big == NULL || little == NULL)
return NULL;
if (*little == '\0')
return (char*)big;
const char* curr_big = big;
size_t little_len = strlen(little);
size_t remaining = len;
const char* retval = NULL;
for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
// find first-char match
if (*curr_big != *little) {
continue;
}
retval = curr_big;
const char* inner_big = retval + 1;
const char* curr_little = little + 1;
int j;
for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
if (*inner_big != *curr_little) {
retval = NULL;
break;
}
}
if (retval)
break;
}
return (char*)retval;
}
int mkstemp(char *templ)
{

@ -74,6 +74,8 @@ char *stpcpy(char *dst, const char *src);
size_t strlcpy(char* dst, const char* src, size_t size);
size_t strlcat(char* dst, const char* src, size_t size);
char *strnstr(const char *big, const char *little, size_t len);
const char *windoze_local_db(void);
const char *windoze_system_db(void);

@ -0,0 +1,35 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifndef STRNSTR_H
#define STRNSTR_H
#include <string>
#include "EngineTestIndividualSuite.h"
using namespace std;
class StrnstrTests : public EngineTestIndividualSuite {
public:
StrnstrTests(string test_suite, string test_home_dir);
private:
void check_strnstr_equal();
void check_strnstr_first_null();
void check_strnstr_second_null();
void check_strnstr_both_null();
void check_strnstr_first_empty();
void check_strnstr_second_empty();
void check_strnstr_both_empty();
void check_strnstr_first_letter_only();
void check_strnstr_first_two_only();
void check_strnstr_all_but_last();
void check_strnstr_same_len_all_but_last();
void check_strnstr_same_len_none();
void check_strnstr_same_big_smaller();
void check_strnstr_shift_one_no_match();
void check_strnstr_shift_to_end();
void check_strnstr_match_after_end();
void check_strnstr_equal_but_size_too_small();
};
#endif

@ -0,0 +1,154 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <stdlib.h>
#include <cstring>
#include <string>
#include <cpptest.h>
#include "test_util.h"
#include "pEpEngine.h"
#include "platform_unix.h"
#include "EngineTestIndividualSuite.h"
#include "StrnstrTests.h"
using namespace std;
StrnstrTests::StrnstrTests(string suitename, string test_home_dir) :
EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal"),
static_cast<Func>(&StrnstrTests::check_strnstr_equal)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_second_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_second_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_both_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_both_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_letter_only"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_letter_only)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_two_only"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_two_only)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_all_but_last"),
static_cast<Func>(&StrnstrTests::check_strnstr_all_but_last)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_all_but_last"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_len_all_but_last)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_none"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_len_none)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_big_smaller"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_big_smaller)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_one_no_match"),
static_cast<Func>(&StrnstrTests::check_strnstr_shift_one_no_match)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_to_end"),
static_cast<Func>(&StrnstrTests::check_strnstr_shift_to_end)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_match_after_end"),
static_cast<Func>(&StrnstrTests::check_strnstr_match_after_end)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal_but_size_too_small"),
static_cast<Func>(&StrnstrTests::check_strnstr_equal_but_size_too_small)));
}
void StrnstrTests::check_strnstr_equal() {
const char* big = "Bob123";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
}
void StrnstrTests::check_strnstr_first_empty() {
const char* big = "";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_second_empty() {
const char* big = "YerMama";
const char* little = "";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_both_empty() {
const char* big = "";
const char* little = "";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_first_letter_only() {
const char* big = "Bob123";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_first_two_only() {
const char* big = "Bob123";
const char* little = "Boof";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_all_but_last() {
const char* big = "BeesBeesBees";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_len_all_but_last() {
const char* big = "Bees";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_len_none() {
const char* big = "1234";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_big_smaller() {
const char* big = "Bee";
const char* little = "Bees";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_shift_one_no_match() {
const char* big = "1Bee";
const char* little = "Bees";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_shift_to_end() {
const char* big = "BigBeeWithExtraBeef";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big + 15, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_match_after_end() {
const char* big = "EatMoreBeef";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size - 1);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_equal_but_size_too_small() {
const char* big = "Bob123";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size - 1);
TEST_ASSERT_MSG(result == NULL, result);
}
Loading…
Cancel
Save