HelenOS sources

root/uspace/lib/c/test/string.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PCUT_TEST
  2. PCUT_TEST
  3. PCUT_TEST
  4. PCUT_TEST
  5. PCUT_TEST
  6. PCUT_TEST
  7. PCUT_TEST
  8. PCUT_TEST
  9. PCUT_TEST
  10. PCUT_TEST
  11. PCUT_TEST
  12. PCUT_TEST
  13. PCUT_TEST
  14. PCUT_TEST
  15. PCUT_TEST
  16. PCUT_TEST
  17. PCUT_TEST
  18. PCUT_TEST
  19. PCUT_TEST
  20. PCUT_TEST
  21. PCUT_TEST
  22. PCUT_TEST
  23. PCUT_TEST
  24. PCUT_TEST
  25. PCUT_TEST
  26. PCUT_TEST
  27. PCUT_TEST
  28. PCUT_TEST
  29. PCUT_TEST
  30. PCUT_TEST
  31. PCUT_TEST
  32. PCUT_TEST
  33. PCUT_TEST
  34. PCUT_TEST
  35. PCUT_TEST
  36. PCUT_TEST
  37. PCUT_TEST
  38. PCUT_TEST
  39. PCUT_TEST
  40. PCUT_TEST
  41. PCUT_TEST
  42. PCUT_TEST
  43. PCUT_TEST
  44. PCUT_TEST
  45. PCUT_TEST
  46. PCUT_TEST
  47. PCUT_TEST
  48. PCUT_TEST
  49. PCUT_TEST
  50. PCUT_TEST
  51. PCUT_TEST
  52. PCUT_TEST
  53. PCUT_TEST
  54. PCUT_TEST
  55. PCUT_TEST
  56. PCUT_TEST
  57. PCUT_TEST
  58. PCUT_TEST
  59. PCUT_TEST
  60. PCUT_TEST
  61. PCUT_TEST
  62. PCUT_TEST
  63. PCUT_TEST

/*
 * Copyright (c) 2018 Jiri Svoboda
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Prevent an error from being generated */
#define _REALLY_WANT_STRING_H
#include <string.h>
#include <pcut/pcut.h>

#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Wstringop-overread"
#endif

PCUT_INIT;

PCUT_TEST_SUITE(string);

/** strcpy function */
PCUT_TEST(strcpy)
{
        const char *s = "hello";
        char buf[7];
        size_t i;
        char *p;

        for (i = 0; i < 7; i++)
                buf[i] = 'X';

        p = strcpy(buf, s);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strncpy function with n == 0 */
PCUT_TEST(strncpy_zero)
{
        const char *s = "hello";
        char buf[1];
        char *p;

        buf[0] = 'X';

        p = strncpy(buf, s, 0);

        /* No characters are copied */
        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'X');
}

/** strncpy function with string longer than n argument */
PCUT_TEST(strncpy_long)
{
        const char *s = "hello";
        char buf[5];
        size_t i;
        char *p;

        for (i = 0; i < 5; i++)
                buf[i] = 'X';

        p = strncpy(buf, s, 4);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'X');
}

/** strncpy function with string containing exactly n characters */
PCUT_TEST(strncpy_just)
{
        const char *s = "hello";
        char buf[6];
        size_t i;
        char *p;

        for (i = 0; i < 6; i++)
                buf[i] = 'X';

        p = strncpy(buf, s, 5);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == 'X');
}

/** strncpy function with string containing exactly n - 1 characters */
PCUT_TEST(strncpy_just_over)
{
        const char *s = "hello";
        char buf[7];
        size_t i;
        char *p;

        for (i = 0; i < 7; i++)
                buf[i] = 'X';

        p = strncpy(buf, s, 6);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strncpy function with string containing less than n - 1 characters */
PCUT_TEST(strncpy_over)
{
        const char *s = "hello";
        char buf[8];
        size_t i;
        char *p;

        for (i = 0; i < 8; i++)
                buf[i] = 'X';

        p = strncpy(buf, s, 7);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == '\0');
        PCUT_ASSERT_TRUE(buf[7] == 'X');
}

/** strcat function */
PCUT_TEST(strcat)
{
        char buf[7];
        const char *s = "cde";
        size_t i;
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';

        for (i = 3; i < 7; i++)
                buf[i] = 'X';

        p = strcat(buf, s);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == 'c');
        PCUT_ASSERT_TRUE(buf[3] == 'd');
        PCUT_ASSERT_TRUE(buf[4] == 'e');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strncat function with n == 0 */
PCUT_TEST(strncat_zero)
{
        const char *s = "cde";
        char buf[4];
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';
        buf[3] = 'X';

        p = strncat(buf, s, 0);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == '\0');
        PCUT_ASSERT_TRUE(buf[3] == 'X');
}

/** strncat function with string longer than n argument */
PCUT_TEST(strncat_long)
{
        const char *s = "cde";
        char buf[6];
        size_t i;
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';

        for (i = 3; i < 6; i++)
                buf[i] = 'X';

        p = strncat(buf, s, 2);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == 'c');
        PCUT_ASSERT_TRUE(buf[3] == 'd');
        PCUT_ASSERT_TRUE(buf[4] == '\0');
        PCUT_ASSERT_TRUE(buf[5] == 'X');
}

/** strncat function with string containing exactly n characters */
PCUT_TEST(strncat_just)
{
        const char *s = "cde";
        char buf[7];
        size_t i;
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';

        for (i = 3; i < 7; i++)
                buf[i] = 'X';

        p = strncat(buf, s, 3);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == 'c');
        PCUT_ASSERT_TRUE(buf[3] == 'd');
        PCUT_ASSERT_TRUE(buf[4] == 'e');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strncat function with string containing exactly n - 1 characters */
PCUT_TEST(strncat_just_over)
{
        const char *s = "cde";
        char buf[7];
        size_t i;
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';

        for (i = 3; i < 7; i++)
                buf[i] = 'X';

        p = strncat(buf, s, 4);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == 'c');
        PCUT_ASSERT_TRUE(buf[3] == 'd');
        PCUT_ASSERT_TRUE(buf[4] == 'e');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strncat function with string containing less than n - 1 characters */
PCUT_TEST(strncat_over)
{
        const char *s = "cde";
        char buf[7];
        size_t i;
        char *p;

        buf[0] = 'a';
        buf[1] = 'b';
        buf[2] = '\0';

        for (i = 3; i < 7; i++)
                buf[i] = 'X';

        p = strncat(buf, s, 5);

        PCUT_ASSERT_TRUE(p == buf);
        PCUT_ASSERT_TRUE(buf[0] == 'a');
        PCUT_ASSERT_TRUE(buf[1] == 'b');
        PCUT_ASSERT_TRUE(buf[2] == 'c');
        PCUT_ASSERT_TRUE(buf[3] == 'd');
        PCUT_ASSERT_TRUE(buf[4] == 'e');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strcmp function with different characters after terminating null */
PCUT_TEST(strcmp_same)
{
        PCUT_ASSERT_TRUE(strcmp("apples\0#", "apples\0$") == 0);
}

/** strcmp function with first string less than second */
PCUT_TEST(strcmp_less_than)
{
        PCUT_ASSERT_TRUE(strcmp("apples", "oranges") < 0);
}

/** strcmp function with first string greater than second */
PCUT_TEST(strcmp_greater_than)
{
        PCUT_ASSERT_TRUE(strcmp("oranges", "apples") > 0);
}

/* strcmp function with first string a prefix of second string */
PCUT_TEST(strcmp_prefix)
{
        PCUT_ASSERT_TRUE(strcmp("apple", "apples") < 0);
}

/** strcoll function */
PCUT_TEST(strcoll)
{
        /* Same string with different characters after terminating null */
        PCUT_ASSERT_TRUE(strcoll("apples\0#", "apples\0$") == 0);

        /* First string less than second */
        PCUT_ASSERT_TRUE(strcoll("apples", "oranges") < 0);

        /* First string greater than second */
        PCUT_ASSERT_TRUE(strcoll("oranges", "apples") > 0);

        /* First string is prefix of second */
        PCUT_ASSERT_TRUE(strcoll("apple", "apples") < 0);
}

/** strncmp function with n == 0 */
PCUT_TEST(strncmp_zero)
{
        PCUT_ASSERT_TRUE(strncmp("apple", "orange", 0) == 0);
}

/** strncmp function with strings differing after n characters */
PCUT_TEST(strncmp_long)
{
        PCUT_ASSERT_TRUE(strncmp("apple", "apricot", 2) == 0);
}

/** strncmp function with strings differing in (n-1)th character */
PCUT_TEST(strncmp_just)
{
        PCUT_ASSERT_TRUE(strncmp("apple", "apricot", 3) < 0);
}

/** strncmp function with strings differing before (n-1)th character */
PCUT_TEST(strncmp_over)
{
        PCUT_ASSERT_TRUE(strncmp("dart", "tart", 3) < 0);
}

/** strxfrm function with null destination to determine size needed */
PCUT_TEST(strxfrm_null)
{
        size_t n;

        n = strxfrm(NULL, "hello", 0);
        PCUT_ASSERT_INT_EQUALS(5, n);
}

/** strxfrm function with string longer than n argument */
PCUT_TEST(strxfrm_long)
{
        const char *s = "hello";
        char buf[5];
        size_t i;
        size_t n;

        for (i = 0; i < 5; i++)
                buf[i] = 'X';

        n = strxfrm(buf, s, 4);

        PCUT_ASSERT_INT_EQUALS(5, n);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'X');
}

/** strxfrm function with string containing exactly n characters */
PCUT_TEST(strxfrm_just)
{
        const char *s = "hello";
        char buf[6];
        size_t i;
        size_t n;

        for (i = 0; i < 6; i++)
                buf[i] = 'X';

        n = strxfrm(buf, s, 5);

        PCUT_ASSERT_INT_EQUALS(5, n);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == 'X');
}

/** strxfrm function with string containing exactly n - 1 characters */
PCUT_TEST(strxfrm_just_over)
{
        const char *s = "hello";
        char buf[7];
        size_t i;
        size_t n;

        for (i = 0; i < 7; i++)
                buf[i] = 'X';

        n = strxfrm(buf, s, 6);

        PCUT_ASSERT_INT_EQUALS(5, n);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
}

/** strxfrm function with string containing less than n - 1 characters */
PCUT_TEST(strxfrm_over)
{
        const char *s = "hello";
        char buf[8];
        size_t i;
        size_t n;

        for (i = 0; i < 8; i++)
                buf[i] = 'X';

        n = strxfrm(buf, s, 7);

        PCUT_ASSERT_INT_EQUALS(5, n);
        PCUT_ASSERT_TRUE(buf[0] == 'h');
        PCUT_ASSERT_TRUE(buf[1] == 'e');
        PCUT_ASSERT_TRUE(buf[2] == 'l');
        PCUT_ASSERT_TRUE(buf[3] == 'l');
        PCUT_ASSERT_TRUE(buf[4] == 'o');
        PCUT_ASSERT_TRUE(buf[5] == '\0');
        PCUT_ASSERT_TRUE(buf[6] == 'X');
        PCUT_ASSERT_TRUE(buf[7] == 'X');
}

/** strchr function searching for null character */
PCUT_TEST(strchr_nullchar)
{
        const char *s = "abcabc";
        char *p;

        p = strchr(s, '\0');
        PCUT_ASSERT_TRUE((const char *)p == &s[6]);
}

/** strchr function with character occurring in string */
PCUT_TEST(strchr_found)
{
        const char *s = "abcabc";
        char *p;

        p = strchr(s, 'b');
        PCUT_ASSERT_TRUE((const char *)p == &s[1]);
}

/** strchr function with character not occurring in string */
PCUT_TEST(strchr_not_found)
{
        const char *s = "abcabc";
        char *p;

        p = strchr(s, 'd');
        PCUT_ASSERT_TRUE(p == NULL);
}

/** strcspn function with empty search string */
PCUT_TEST(strcspn_empty_str)
{
        size_t n;

        n = strcspn("", "abc");
        PCUT_ASSERT_INT_EQUALS(0, n);
}

/** strcspn function with empty character set */
PCUT_TEST(strcspn_empty_set)
{
        size_t n;

        n = strcspn("abc", "");
        PCUT_ASSERT_INT_EQUALS(3, n);
}

/** strcspn function with regular arguments */
PCUT_TEST(strcspn_regular)
{
        size_t n;

        n = strcspn("baBAba", "AB");
        PCUT_ASSERT_INT_EQUALS(2, n);
}

/** strpbrk function with empty search string */
PCUT_TEST(strpbrk_empty_string)
{
        const char *p;

        p = strpbrk("", "abc");
        PCUT_ASSERT_NULL(p);
}

/** strpbrk function with empty character set */
PCUT_TEST(strpbrk_empty_set)
{
        const char *p;

        p = strpbrk("abc", "");
        PCUT_ASSERT_NULL(p);
}

/** strpbrk function with regular parameters */
PCUT_TEST(strpbrk_regular)
{
        const char *s = "baBAba";
        char *p;

        p = strpbrk(s, "ab");
        PCUT_ASSERT_TRUE((const char *)p == s);
}

/** strrchr function searching for null character */
PCUT_TEST(strrchr_nullchar)
{
        const char *s = "abcabc";
        char *p;

        p = strrchr(s, '\0');
        PCUT_ASSERT_TRUE((const char *)p == &s[6]);
}

/** strrchr function with character occurring in string */
PCUT_TEST(strrchr_found)
{
        const char *s = "abcabc";
        char *p;

        p = strrchr(s, 'b');
        PCUT_ASSERT_TRUE((const char *)p == &s[4]);
}

/** strrchr function with character not occurring in string */
PCUT_TEST(strrchr_not_found)
{
        const char *s = "abcabc";
        char *p;

        p = strrchr(s, 'd');
        PCUT_ASSERT_TRUE(p == NULL);
}

/** strspn function with empty search string */
PCUT_TEST(strspn_empty_str)
{
        size_t n;

        n = strspn("", "abc");
        PCUT_ASSERT_INT_EQUALS(0, n);
}

/** strspn function with empty character set */
PCUT_TEST(strspn_empty_set)
{
        size_t n;

        n = strspn("abc", "");
        PCUT_ASSERT_INT_EQUALS(0, n);
}

/** strspn function with regular arguments */
PCUT_TEST(strspn_regular)
{
        size_t n;

        n = strspn("baBAba", "ab");
        PCUT_ASSERT_INT_EQUALS(2, n);
}

/** strstr function looking for empty substring */
PCUT_TEST(strstr_empty)
{
        const char *str = "abcabcabcdabc";
        char *p;

        p = strstr(str, "");
        PCUT_ASSERT_TRUE((const char *) p == str);
}

/** strstr function looking for substring with success */
PCUT_TEST(strstr_found)
{
        const char *str = "abcabcabcdabc";
        char *p;

        p = strstr(str, "abcd");
        PCUT_ASSERT_TRUE((const char *) p == &str[6]);
}

/** strstr function looking for substring with failure */
PCUT_TEST(strstr_notfound)
{
        const char *str = "abcabcabcdabc";
        char *p;

        p = strstr(str, "abcde");
        PCUT_ASSERT_NULL(p);
}

/** strtok function */
PCUT_TEST(strtok)
{
        char str[] = ":a::b;;;$c";
        char *t;

        t = strtok(str, ":");
        PCUT_ASSERT_TRUE(t == &str[1]);
        PCUT_ASSERT_INT_EQUALS(0, strcmp(t, "a"));

        t = strtok(NULL, ";");
        PCUT_ASSERT_TRUE(t == &str[3]);
        PCUT_ASSERT_INT_EQUALS(0, strcmp(t, ":b"));

        t = strtok(NULL, "$;");
        PCUT_ASSERT_TRUE(t == &str[9]);
        PCUT_ASSERT_INT_EQUALS(0, strcmp(t, "c"));

        t = strtok(NULL, "$");
        PCUT_ASSERT_NULL(t);
}

/** strerror function with zero argument */
PCUT_TEST(strerror_zero)
{
        char *p;

        p = strerror(0);
        PCUT_ASSERT_NOT_NULL(p);
}

/** strerror function with errno value argument */
PCUT_TEST(strerror_errno)
{
        char *p;

        p = strerror(EINVAL);
        PCUT_ASSERT_NOT_NULL(p);
}

/** strerror function with negative argument */
PCUT_TEST(strerror_negative)
{
        char *p;

        p = strerror(-1);
        PCUT_ASSERT_NOT_NULL(p);
}

/** strlen function with empty string */
PCUT_TEST(strlen_empty)
{
        PCUT_ASSERT_INT_EQUALS(0, strlen(""));
}

/** strlen function with non-empty string */
PCUT_TEST(strlen_nonempty)
{
        PCUT_ASSERT_INT_EQUALS(3, strlen("abc"));
}

/** strlen function with empty string and non-zero limit */
PCUT_TEST(strnlen_empty_short)
{
        PCUT_ASSERT_INT_EQUALS(0, strnlen("", 1));
}

/** strlen function with empty string and zero limit */
PCUT_TEST(strnlen_empty_eq)
{
        PCUT_ASSERT_INT_EQUALS(0, strnlen("", 0));
}

/** strlen function with non empty string below limit */
PCUT_TEST(strnlen_nonempty_short)
{
        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 5));
}

/** strlen function with non empty string just below limit */
PCUT_TEST(strnlen_nonempty_just_short)
{
        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 4));
}

/** strlen function with non empty string of length equal to limit */
PCUT_TEST(strnlen_nonempty_eq)
{
        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 3));
}

/** strlen function with non empty string of length above limit */
PCUT_TEST(strnlen_nonempty_long)
{
        PCUT_ASSERT_INT_EQUALS(2, strnlen("abc", 2));
}

/** strdup function with empty string */
PCUT_TEST(strdup_empty)
{
        char *d = strdup("");
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == '\0');
        free(d);
}

/** strdup function with non-empty string */
PCUT_TEST(strdup_nonempty)
{
        char *d = strdup("abc");
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == 'a');
        PCUT_ASSERT_TRUE(d[1] == 'b');
        PCUT_ASSERT_TRUE(d[2] == 'c');
        PCUT_ASSERT_TRUE(d[3] == '\0');
        free(d);
}

/** strndup function with empty string and non-zero limit */
PCUT_TEST(strndup_empty_short)
{
        char *d = strndup("", 1);
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == '\0');
        free(d);
}

/** strndup function with empty string and zero limit */
PCUT_TEST(strndup_empty_eq)
{
        char *d = strndup("", 0);
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == '\0');
        free(d);
}

/** strndup function with non-empty string of length below limit */
PCUT_TEST(strndup_nonempty_short)
{
#pragma GCC diagnostic push
        // Intentionally checking it works with _longer_ size than actual
#if defined(__GNUC__) && (__GNUC__ >= 11)
#pragma GCC diagnostic ignored "-Wstringop-overread"
#endif
        char *d = strndup("abc", 5);
#pragma GCC diagnostic pop
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == 'a');
        PCUT_ASSERT_TRUE(d[1] == 'b');
        PCUT_ASSERT_TRUE(d[2] == 'c');
        PCUT_ASSERT_TRUE(d[3] == '\0');
        free(d);
}

/** strndup function with non-empty string of length equal to limit */
PCUT_TEST(strndup_nonempty_eq)
{
        char *d = strndup("abc", 3);
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == 'a');
        PCUT_ASSERT_TRUE(d[1] == 'b');
        PCUT_ASSERT_TRUE(d[2] == 'c');
        PCUT_ASSERT_TRUE(d[3] == '\0');
        free(d);
}

/** strndup function with non-empty string of length above limit */
PCUT_TEST(strndup_nonempty_long)
{
        char *d = strndup("abc", 2);
        PCUT_ASSERT_NOT_NULL(d);
        PCUT_ASSERT_TRUE(d[0] == 'a');
        PCUT_ASSERT_TRUE(d[1] == 'b');
        PCUT_ASSERT_TRUE(d[2] == '\0');
        free(d);
}

PCUT_EXPORT(string);

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub