Bugfix/indtext-find-string-among-similar (#1173)
* Enhanced string comparison functions and update indtext API usage - Added library specific case-sensitive and case-insensitive string comparison functions that mimic strcmp. - Updated indtext_by_string and indtext_by_istring to use the new comparison functions. - Improved documentation for return values in indtext functions. - Expanded test data in main.c for comprehensive testing when beginning of string matches another string.
This commit is contained in:
@@ -43,6 +43,7 @@ The git repositories are hosted at the following sites:
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
* Fixed library specific strcmp/stricmp functions match standard strcmp. (#1173)
|
||||||
* Fixed compiler macro redefined warning when optional datatypes are defined
|
* Fixed compiler macro redefined warning when optional datatypes are defined
|
||||||
globally. (#1172)
|
globally. (#1172)
|
||||||
* Fixed copy and compare API of BACnetObjectPropertyReference structure. (#1171)
|
* Fixed copy and compare API of BACnetObjectPropertyReference structure. (#1171)
|
||||||
|
|||||||
+78
-2
@@ -1299,6 +1299,25 @@ bool octetstring_value_same(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compare two strings, case sensitive or insensitive, with length limit
|
||||||
|
* @details The strncmp() function compares, at most, the first n characters
|
||||||
|
* of string1 and string2.
|
||||||
|
* The function operates on null terminated strings.
|
||||||
|
* The string arguments to the function are expected to contain
|
||||||
|
* a null character (\0) marking the end of the string.
|
||||||
|
* @param a - first string
|
||||||
|
* @param b - second string
|
||||||
|
* @param length - maximum length to compare, or zero for full length of the
|
||||||
|
* first string argument.
|
||||||
|
* @param case_insensitive - true for case insensitive comparison
|
||||||
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
|
*/
|
||||||
static int bacnet_strnicmp_internal(
|
static int bacnet_strnicmp_internal(
|
||||||
const char *a, const char *b, size_t length, bool case_insensitive)
|
const char *a, const char *b, size_t length, bool case_insensitive)
|
||||||
{
|
{
|
||||||
@@ -1328,15 +1347,57 @@ static int bacnet_strnicmp_internal(
|
|||||||
return twin_a - twin_b;
|
return twin_a - twin_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compare two strings, case sensitive or insensitive
|
||||||
|
* @param a - first string
|
||||||
|
* @param b - second string
|
||||||
|
* @param case_insensitive - true for case insensitive comparison
|
||||||
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
bacnet_stricmp_internal(const char *a, const char *b, bool case_insensitive)
|
||||||
|
{
|
||||||
|
int twin_a, twin_b;
|
||||||
|
|
||||||
|
if (a == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (b == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
twin_a = *(const unsigned char *)a;
|
||||||
|
twin_b = *(const unsigned char *)b;
|
||||||
|
if (case_insensitive) {
|
||||||
|
twin_a = tolower(toupper(twin_a));
|
||||||
|
twin_b = tolower(toupper(twin_b));
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
} while ((twin_a == twin_b) && (twin_a != '\0'));
|
||||||
|
|
||||||
|
return twin_a - twin_b;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compare two strings, case sensitive
|
* @brief Compare two strings, case sensitive
|
||||||
* @param a - first string
|
* @param a - first string
|
||||||
* @param b - second string
|
* @param b - second string
|
||||||
* @return 0 if the strings are equal, non-zero if not
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
*/
|
*/
|
||||||
int bacnet_strcmp(const char *a, const char *b)
|
int bacnet_strcmp(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
return bacnet_strnicmp_internal(a, b, 0, false);
|
return bacnet_stricmp_internal(a, b, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1344,11 +1405,16 @@ int bacnet_strcmp(const char *a, const char *b)
|
|||||||
* @param a - first string
|
* @param a - first string
|
||||||
* @param b - second string
|
* @param b - second string
|
||||||
* @return 0 if the strings are equal, non-zero if not
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
* @note The stricmp() function is not included in the C standard.
|
* @note The stricmp() function is not included in the C standard.
|
||||||
*/
|
*/
|
||||||
int bacnet_stricmp(const char *a, const char *b)
|
int bacnet_stricmp(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
return bacnet_strnicmp_internal(a, b, 0, true);
|
return bacnet_stricmp_internal(a, b, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1364,6 +1430,11 @@ int bacnet_stricmp(const char *a, const char *b)
|
|||||||
* @param b - second string
|
* @param b - second string
|
||||||
* @param length - maximum length to compare
|
* @param length - maximum length to compare
|
||||||
* @return 0 if the strings are equal, non-zero if not
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
*/
|
*/
|
||||||
int bacnet_strncmp(const char *a, const char *b, size_t length)
|
int bacnet_strncmp(const char *a, const char *b, size_t length)
|
||||||
{
|
{
|
||||||
@@ -1383,6 +1454,11 @@ int bacnet_strncmp(const char *a, const char *b, size_t length)
|
|||||||
* @param b - second string
|
* @param b - second string
|
||||||
* @param length - maximum length to compare
|
* @param length - maximum length to compare
|
||||||
* @return 0 if the strings are equal, non-zero if not
|
* @return 0 if the strings are equal, non-zero if not
|
||||||
|
* The sign of a nonzero value returned by the comparison functions
|
||||||
|
* memcmp, strcmp, and strncmp is determined by the sign of the
|
||||||
|
* difference between the values of the first pair of characters
|
||||||
|
* (both interpreted as unsigned char) that differ in the objects
|
||||||
|
* being compared.
|
||||||
* @note The strnicmp() function is not included in the C standard.
|
* @note The strnicmp() function is not included in the C standard.
|
||||||
*/
|
*/
|
||||||
int bacnet_strnicmp(const char *a, const char *b, size_t length)
|
int bacnet_strnicmp(const char *a, const char *b, size_t length)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* @param data_list - list of strings and indices
|
* @param data_list - list of strings and indices
|
||||||
* @param search_name - string to search for
|
* @param search_name - string to search for
|
||||||
* @param found_index - index of the string found
|
* @param found_index - index of the string found
|
||||||
* @return true if the string is found
|
* @return true if the matching string is found
|
||||||
*/
|
*/
|
||||||
bool indtext_by_string(
|
bool indtext_by_string(
|
||||||
INDTEXT_DATA *data_list, const char *search_name, uint32_t *found_index)
|
INDTEXT_DATA *data_list, const char *search_name, uint32_t *found_index)
|
||||||
@@ -27,7 +27,7 @@ bool indtext_by_string(
|
|||||||
|
|
||||||
if (data_list && search_name) {
|
if (data_list && search_name) {
|
||||||
while (data_list->pString) {
|
while (data_list->pString) {
|
||||||
if (strcmp(data_list->pString, search_name) == 0) {
|
if (bacnet_strcmp(data_list->pString, search_name) == 0) {
|
||||||
index = data_list->index;
|
index = data_list->index;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -48,7 +48,7 @@ bool indtext_by_string(
|
|||||||
* @param data_list - list of strings and indices
|
* @param data_list - list of strings and indices
|
||||||
* @param search_name - string to search for
|
* @param search_name - string to search for
|
||||||
* @param found_index - index of the string found
|
* @param found_index - index of the string found
|
||||||
* @return true if the string is found
|
* @return true if the matching string is found
|
||||||
*/
|
*/
|
||||||
bool indtext_by_istring(
|
bool indtext_by_istring(
|
||||||
INDTEXT_DATA *data_list, const char *search_name, uint32_t *found_index)
|
INDTEXT_DATA *data_list, const char *search_name, uint32_t *found_index)
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Test
|
* @brief Test
|
||||||
*/
|
*/
|
||||||
static INDTEXT_DATA data_list[] = { { 1, "Joshua" }, { 2, "Mary" },
|
static INDTEXT_DATA data_list[] = {
|
||||||
{ 3, "Anna" }, { 4, "Christopher" },
|
{ 1, "Joshua" }, { 2, "Mary" },
|
||||||
{ 5, "Patricia" }, { 0, NULL } };
|
{ 3, "Anna" }, { 4, "Christopher" },
|
||||||
|
{ 5, "Patricia" }, { 6, "JoshuaMaryAnnaChristopherPatricia" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
ZTEST(indtext_tests, testIndexText)
|
ZTEST(indtext_tests, testIndexText)
|
||||||
@@ -26,11 +29,11 @@ ZTEST(indtext_tests, testIndexText)
|
|||||||
static void testIndexText(void)
|
static void testIndexText(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
unsigned i; /*counter */
|
uint32_t i; /*counter */
|
||||||
const char *pString;
|
const char *pString;
|
||||||
unsigned index;
|
uint32_t index;
|
||||||
bool valid;
|
bool valid;
|
||||||
unsigned count = 0;
|
uint32_t count = 0;
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
pString = indtext_by_index(data_list, i);
|
pString = indtext_by_index(data_list, i);
|
||||||
@@ -38,7 +41,7 @@ static void testIndexText(void)
|
|||||||
count++;
|
count++;
|
||||||
valid = indtext_by_string(data_list, pString, &index);
|
valid = indtext_by_string(data_list, pString, &index);
|
||||||
zassert_true(valid, NULL);
|
zassert_true(valid, NULL);
|
||||||
zassert_equal(index, i, NULL);
|
zassert_equal(index, i, "index=%u i=%u", index, i);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
index, indtext_by_string_default(data_list, pString, index),
|
index, indtext_by_string_default(data_list, pString, index),
|
||||||
NULL);
|
NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user