Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ea4910b in mainline


Ignore:
Timestamp:
2018-11-30T10:04:57Z (20 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
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
Files:
7 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);
  • uspace/lib/posix/Makefile

    rc483fca rea4910b  
    3131LIBRARY = libposix
    3232
    33 EXTRA_CFLAGS = -Iinclude/posix
     33EXTRA_CFLAGS = -Iinclude/posix -D_XOPEN_SOURCE
    3434
    3535EXPORT_FILES = \
  • uspace/lib/posix/include/posix/string.h

    rc483fca rea4910b  
    5959extern char *stpncpy(char *__restrict__ dest, const char *__restrict__ src, size_t n);
    6060extern void *memccpy(void *__restrict__ dest, const void *__restrict__ src, int c, size_t n);
    61 extern char *strdup(const char *s);
    62 extern char *strndup(const char *s, size_t n);
    6361
    6462/* Search Functions */
     
    7068/* Error Messages */
    7169extern int strerror_r(int errnum, char *buf, size_t bufsz);
    72 
    73 /* String Length */
    74 extern size_t strnlen(const char *s, size_t n);
    7570
    7671/* Signal Messages */
  • uspace/lib/posix/src/string.c

    rc483fca rea4910b  
    135135
    136136/**
    137  * Duplicate a string.
    138  *
    139  * @param s String to be duplicated.
    140  * @return Newly allocated copy of the string.
    141  */
    142 char *strdup(const char *s)
    143 {
    144         return strndup(s, SIZE_MAX);
    145 }
    146 
    147 /**
    148  * Duplicate a specific number of bytes from a string.
    149  *
    150  * @param s String to be duplicated.
    151  * @param n Maximum length of the resulting string..
    152  * @return Newly allocated string copy of length at most n.
    153  */
    154 char *strndup(const char *s, size_t n)
    155 {
    156         assert(s != NULL);
    157 
    158         size_t len = strnlen(s, n);
    159         char *dup = malloc(len + 1);
    160         if (dup == NULL) {
    161                 return NULL;
    162         }
    163 
    164         memcpy(dup, s, len);
    165         dup[len] = '\0';
    166 
    167         return dup;
    168 }
    169 
    170 /**
    171137 * Scan string for a first occurence of a character.
    172138 *
     
    225191
    226192        return EOK;
    227 }
    228 
    229 /**
    230  * Get limited length of the string.
    231  *
    232  * @param s String which length shall be determined.
    233  * @param n Maximum number of bytes that can be examined to determine length.
    234  * @return The lower of either string length or n limit.
    235  */
    236 size_t strnlen(const char *s, size_t n)
    237 {
    238         assert(s != NULL);
    239 
    240         for (size_t sz = 0; sz < n; ++sz) {
    241 
    242                 if (s[sz] == '\0') {
    243                         return sz;
    244                 }
    245         }
    246 
    247         return n;
    248193}
    249194
Note: See TracChangeset for help on using the changeset viewer.