Changeset ea4910b in mainline for uspace/lib/c


Ignore:
Timestamp:
2018-11-30T10:04:57Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
26f5bdf, 4aba581
Parents:
c483fca
git-author:
Jiri Svoboda <jiri@…> (2018-11-29 18:02:24)
git-committer:
Jiri Svoboda <jiri@…> (2018-11-30 10:04:57)
Message:

strdup(), strndup(), strnlen() are commonly used extensions so move them to libc (native ports can use these).

Location:
uspace/lib/c
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    rc483fca rea4910b  
    3434
    3535EXTRA_OUTPUT = $(START_FILES)
    36 EXTRA_CFLAGS += -fno-builtin
     36EXTRA_CFLAGS += -fno-builtin -D_LIBC_SOURCE
    3737LIBRARY = libc
    3838SOVERSION = 0.0
  • uspace/lib/c/generic/string.c

    rc483fca rea4910b  
    3333 */
    3434
    35 /* Prevent an error from being generated */
    36 #undef _HELENOS_SOURCE
     35#include <errno.h>
     36#include <stddef.h>
     37#include <stdlib.h>
     38#include <str_error.h>
    3739#include <string.h>
    38 #define _HELENOS_SOURCE
    39 
    40 #include <stddef.h>
    41 #include <str_error.h>
    4240
    4341/** Copy string.
     
    504502}
    505503
     504/** Return number of characters in string with length limit.
     505 *
     506 * @param s String
     507 * @param maxlen Maximum number of characters to read
     508 * @return Number of characters preceding the null character, at most @a maxlen.
     509 */
     510size_t strnlen(const char *s, size_t maxlen)
     511{
     512        size_t n;
     513
     514        n = 0;
     515        while (n < maxlen && *s != '\0') {
     516                ++s;
     517                ++n;
     518        }
     519
     520        return n;
     521}
     522
     523/** Allocate a new duplicate of string.
     524 *
     525 * @param s String to duplicate
     526 * @return New string or @c NULL on failure (in which case @c errno is set
     527 *         to ENOMEM).
     528 */
     529char *strdup(const char *s)
     530{
     531        size_t sz;
     532        char *dup;
     533
     534        sz = strlen(s);
     535        dup = malloc(sz + 1);
     536        if (dup == NULL) {
     537                errno = ENOMEM;
     538                return NULL;
     539        }
     540
     541        strcpy(dup, s);
     542        return dup;
     543}
     544
     545/** Allocate a new duplicate of string with length limit.
     546 *
     547 * Creates a new duplicate of @a s. If @a s is longer than @a n characters,
     548 * only @a n characters are copied and a null character is appended.
     549 *
     550 * @param s String to duplicate
     551 * @param n Maximum number of characters to copy
     552 * @return New string or @c NULL on failure (in which case @c errno is set
     553 *         to ENOMEM).
     554 */
     555char *strndup(const char *s, size_t n)
     556{
     557        size_t sz;
     558        char *dup;
     559
     560        sz = strnlen(s, n);
     561        dup = malloc(sz + 1);
     562        if (dup == NULL) {
     563                errno = ENOMEM;
     564                return NULL;
     565        }
     566
     567        strcpy(dup, s);
     568        return dup;
     569}
     570
    506571/** @}
    507572 */
  • uspace/lib/c/include/string.h

    rc483fca rea4910b  
    3636#define LIBC_STRING_H_
    3737
    38 #if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H)
     38#if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H) && \
     39    !defined(_LIBC_SOURCE)
    3940#error Please use str.h and mem.h instead
    4041#endif
     
    6364extern size_t strlen(const char *);
    6465
     66#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_LIBC_SOURCE)
     67extern size_t strnlen(const char *, size_t);
     68extern char *strdup(const char *);
     69extern char *strndup(const char *, size_t);
     70#endif
     71
    6572#endif
    6673
  • uspace/lib/c/test/string.c

    rc483fca rea4910b  
    722722}
    723723
     724/** strlen function with empty string and non-zero limit */
     725PCUT_TEST(strnlen_empty_short)
     726{
     727        PCUT_ASSERT_INT_EQUALS(0, strnlen("", 1));
     728}
     729
     730/** strlen function with empty string and zero limit */
     731PCUT_TEST(strnlen_empty_eq)
     732{
     733        PCUT_ASSERT_INT_EQUALS(0, strnlen("", 0));
     734}
     735
     736/** strlen function with non empty string below limit */
     737PCUT_TEST(strnlen_nonempty_short)
     738{
     739        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 5));
     740}
     741
     742/** strlen function with non empty string just below limit */
     743PCUT_TEST(strnlen_nonempty_just_short)
     744{
     745        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 4));
     746}
     747
     748/** strlen function with non empty string of length equal to limit */
     749PCUT_TEST(strnlen_nonempty_eq)
     750{
     751        PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 3));
     752}
     753
     754/** strlen function with non empty string of length above limit */
     755PCUT_TEST(strnlen_nonempty_long)
     756{
     757        PCUT_ASSERT_INT_EQUALS(2, strnlen("abc", 2));
     758}
     759
     760/** strdup function with empty string */
     761PCUT_TEST(strdup_empty)
     762{
     763        char *d = strdup("");
     764        PCUT_ASSERT_NOT_NULL(d);
     765        PCUT_ASSERT_TRUE(d[0] == '\0');
     766        free(d);
     767}
     768
     769/** strdup function with non-empty string */
     770PCUT_TEST(strdup_nonempty)
     771{
     772        char *d = strdup("abc");
     773        PCUT_ASSERT_NOT_NULL(d);
     774        PCUT_ASSERT_TRUE(d[0] == 'a');
     775        PCUT_ASSERT_TRUE(d[1] == 'b');
     776        PCUT_ASSERT_TRUE(d[2] == 'c');
     777        PCUT_ASSERT_TRUE(d[3] == '\0');
     778        free(d);
     779}
     780
     781/** strndup function with empty string and non-zero limit */
     782PCUT_TEST(strndup_empty_short)
     783{
     784        char *d = strndup("", 1);
     785        PCUT_ASSERT_NOT_NULL(d);
     786        PCUT_ASSERT_TRUE(d[0] == '\0');
     787        free(d);
     788}
     789
     790/** strndup function with empty string and zero limit */
     791PCUT_TEST(strndup_empty_eq)
     792{
     793        char *d = strndup("", 0);
     794        PCUT_ASSERT_NOT_NULL(d);
     795        PCUT_ASSERT_TRUE(d[0] == '\0');
     796        free(d);
     797}
     798
     799/** strndup function with non-empty string of length below limit */
     800PCUT_TEST(strndup_nonempty_short)
     801{
     802        char *d = strndup("abc", 5);
     803        PCUT_ASSERT_NOT_NULL(d);
     804        PCUT_ASSERT_TRUE(d[0] == 'a');
     805        PCUT_ASSERT_TRUE(d[1] == 'b');
     806        PCUT_ASSERT_TRUE(d[2] == 'c');
     807        PCUT_ASSERT_TRUE(d[3] == '\0');
     808        free(d);
     809}
     810
     811/** strndup function with non-empty string of length equal to limit */
     812PCUT_TEST(strndup_nonempty_eq)
     813{
     814        char *d = strndup("abc", 3);
     815        PCUT_ASSERT_NOT_NULL(d);
     816        PCUT_ASSERT_TRUE(d[0] == 'a');
     817        PCUT_ASSERT_TRUE(d[1] == 'b');
     818        PCUT_ASSERT_TRUE(d[2] == 'c');
     819        PCUT_ASSERT_TRUE(d[3] == '\0');
     820        free(d);
     821}
     822
     823/** strndup function with non-empty string of length above limit */
     824PCUT_TEST(strndup_nonempty_long)
     825{
     826        char *d = strndup("abc", 2);
     827        PCUT_ASSERT_NOT_NULL(d);
     828        PCUT_ASSERT_TRUE(d[0] == 'a');
     829        PCUT_ASSERT_TRUE(d[1] == 'b');
     830        PCUT_ASSERT_TRUE(d[2] == '\0');
     831        free(d);
     832}
     833
    724834PCUT_EXPORT(string);
Note: See TracChangeset for help on using the changeset viewer.