Changeset 99d3123 in mainline


Ignore:
Timestamp:
2018-07-12T15:18:55Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9912f49
Parents:
2eadda9
Message:

libc needs a string.h (for the outside users, at least).

Location:
uspace/lib
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r2eadda9 r99d3123  
    7979        generic/mem.c \
    8080        generic/str.c \
     81        generic/string.c \
    8182        generic/str_error.c \
    8283        generic/strtol.c \
     
    203204        test/stdio.c \
    204205        test/stdlib.c \
    205         test/str.c
     206        test/str.c \
     207        test/string.c
    206208
    207209include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/c/test/main.c

    r2eadda9 r99d3123  
    4242PCUT_IMPORT(stdlib);
    4343PCUT_IMPORT(str);
     44PCUT_IMPORT(string);
    4445PCUT_IMPORT(table);
    4546
  • uspace/lib/posix/include/posix/string.h

    r2eadda9 r99d3123  
    4848
    4949#include "libc/mem.h"
     50#undef _HELENOS_SOURCE
     51#include "libc/string.h"
    5052
    5153/* Copying and Concatenation */
    52 extern char *strcpy(char *__restrict__ dest, const char *__restrict__ src);
    53 extern char *strncpy(char *__restrict__ dest, const char *__restrict__ src, size_t n);
    5454extern char *stpcpy(char *__restrict__ dest, const char *__restrict__ src);
    5555extern char *stpncpy(char *__restrict__ dest, const char *__restrict__ src, size_t n);
    56 extern char *strcat(char *__restrict__ dest, const char *__restrict__ src);
    57 extern char *strncat(char *__restrict__ dest, const char *__restrict__ src, size_t n);
    5856extern void *memccpy(void *__restrict__ dest, const void *__restrict__ src, int c, size_t n);
    5957extern char *strdup(const char *s);
    6058extern char *strndup(const char *s, size_t n);
    6159
    62 /* String Comparison */
    63 extern int strcmp(const char *s1, const char *s2);
    64 extern int strncmp(const char *s1, const char *s2, size_t n);
    65 
    6660/* Search Functions */
    67 extern char *strchr(const char *s, int c);
    68 extern char *strrchr(const char *s, int c);
    6961extern char *gnu_strchrnul(const char *s, int c);
    70 extern char *strpbrk(const char *s1, const char *s2);
    71 extern size_t strcspn(const char *s1, const char *s2);
    72 extern size_t strspn(const char *s1, const char *s2);
    73 extern char *strstr(const char *haystack, const char *needle);
    7462
    7563/* Tokenization functions. */
    7664extern char *strtok_r(char *, const char *, char **);
    77 extern char *strtok(char *, const char *);
    78 
    79 
    80 /* Collation Functions */
    81 extern int strcoll(const char *s1, const char *s2);
    82 extern size_t strxfrm(char *__restrict__ s1, const char *__restrict__ s2, size_t n);
    8365
    8466/* Error Messages */
    85 extern char *strerror(int errnum);
    8667extern int strerror_r(int errnum, char *buf, size_t bufsz);
    8768
    8869/* String Length */
    89 extern size_t strlen(const char *s);
    9070extern size_t strnlen(const char *s, size_t n);
    9171
  • uspace/lib/posix/src/string.c

    r2eadda9 r99d3123  
    22 * Copyright (c) 2011 Petr Koupy
    33 * Copyright (c) 2011 Jiri Zarevucky
     4 * Copyright (c) 2018 Jiri Svoboda
    45 * All rights reserved.
    56 *
     
    4950
    5051/**
    51  * The same as strpbrk, except it returns pointer to the nul terminator
    52  * if no occurence is found.
    53  *
    54  * @param s1 String in which to look for the bytes.
    55  * @param s2 String of bytes to look for.
    56  * @return Pointer to the found byte on success, pointer to the
    57  *     string terminator otherwise.
    58  */
    59 static char *strpbrk_null(const char *s1, const char *s2)
    60 {
    61         while (!strchr(s2, *s1)) {
    62                 ++s1;
    63         }
    64 
    65         return (char *) s1;
    66 }
    67 
    68 /**
    69  * Copy a string.
    70  *
    71  * @param dest Destination pre-allocated buffer.
    72  * @param src Source string to be copied.
    73  * @return Pointer to the destination buffer.
    74  */
    75 char *strcpy(char *restrict dest, const char *restrict src)
    76 {
    77         stpcpy(dest, src);
    78         return dest;
    79 }
    80 
    81 /**
    82  * Copy fixed length string.
    83  *
    84  * @param dest Destination pre-allocated buffer.
    85  * @param src Source string to be copied.
    86  * @param n Number of bytes to be stored into destination buffer.
    87  * @return Pointer to the destination buffer.
    88  */
    89 char *strncpy(char *restrict dest, const char *restrict src, size_t n)
    90 {
    91         stpncpy(dest, src, n);
    92         return dest;
    93 }
    94 
    95 /**
    9652 * Copy a string.
    9753 *
     
    151107
    152108/**
    153  * Concatenate two strings.
    154  *
    155  * @param dest String to which src shall be appended.
    156  * @param src String to be appended after dest.
    157  * @return Pointer to destination buffer.
    158  */
    159 char *strcat(char *restrict dest, const char *restrict src)
    160 {
    161         assert(dest != NULL);
    162         assert(src != NULL);
    163 
    164         strcpy(strchr(dest, '\0'), src);
    165         return dest;
    166 }
    167 
    168 /**
    169  * Concatenate a string with part of another.
    170  *
    171  * @param dest String to which part of src shall be appended.
    172  * @param src String whose part shall be appended after dest.
    173  * @param n Number of bytes to append after dest.
    174  * @return Pointer to destination buffer.
    175  */
    176 char *strncat(char *restrict dest, const char *restrict src, size_t n)
    177 {
    178         assert(dest != NULL);
    179         assert(src != NULL);
    180 
    181         char *zeroptr = strncpy(strchr(dest, '\0'), src, n);
    182         /* strncpy doesn't append the nul terminator, so we do it here */
    183         zeroptr[n] = '\0';
    184         return dest;
    185 }
    186 
    187 /**
    188109 * Copy limited number of bytes in memory.
    189110 *
     
    249170
    250171/**
    251  * Compare two strings.
    252  *
    253  * @param s1 First string to be compared.
    254  * @param s2 Second string to be compared.
    255  * @return Difference of the first pair of inequal characters,
    256  *     or 0 if strings have the same content.
    257  */
    258 int strcmp(const char *s1, const char *s2)
    259 {
    260         assert(s1 != NULL);
    261         assert(s2 != NULL);
    262 
    263         return strncmp(s1, s2, STR_NO_LIMIT);
    264 }
    265 
    266 /**
    267  * Compare part of two strings.
    268  *
    269  * @param s1 First string to be compared.
    270  * @param s2 Second string to be compared.
    271  * @param n Maximum number of characters to be compared.
    272  * @return Difference of the first pair of inequal characters,
    273  *     or 0 if strings have the same content.
    274  */
    275 int strncmp(const char *s1, const char *s2, size_t n)
    276 {
    277         assert(s1 != NULL);
    278         assert(s2 != NULL);
    279 
    280         for (size_t i = 0; i < n; ++i) {
    281                 if (s1[i] != s2[i]) {
    282                         return s1[i] - s2[i];
    283                 }
    284                 if (s1[i] == '\0') {
    285                         break;
    286                 }
    287         }
    288 
    289         return 0;
    290 }
    291 
    292 /**
    293  * Scan string for a first occurence of a character.
    294  *
    295  * @param s String in which to look for the character.
    296  * @param c Character to look for.
    297  * @return Pointer to the specified character on success,
    298  *     NULL pointer otherwise.
    299  */
    300 char *strchr(const char *s, int c)
    301 {
    302         assert(s != NULL);
    303 
    304         char *res = gnu_strchrnul(s, c);
    305         return (*res == c) ? res : NULL;
    306 }
    307 
    308 /**
    309  * Scan string for a last occurence of a character.
    310  *
    311  * @param s String in which to look for the character.
    312  * @param c Character to look for.
    313  * @return Pointer to the specified character on success,
    314  *     NULL pointer otherwise.
    315  */
    316 char *strrchr(const char *s, int c)
    317 {
    318         assert(s != NULL);
    319 
    320         const char *ptr = strchr(s, '\0');
    321 
    322         /* the same as in strchr, except it loops in reverse direction */
    323         while (*ptr != (char) c) {
    324                 if (ptr == s) {
    325                         return NULL;
    326                 }
    327 
    328                 ptr--;
    329         }
    330 
    331         return (char *) ptr;
    332 }
    333 
    334 /**
    335172 * Scan string for a first occurence of a character.
    336173 *
     
    350187        return (char *) s;
    351188}
    352 
    353 /**
    354  * Scan a string for a first occurence of one of provided bytes.
    355  *
    356  * @param s1 String in which to look for the bytes.
    357  * @param s2 String of bytes to look for.
    358  * @return Pointer to the found byte on success,
    359  *     NULL pointer otherwise.
    360  */
    361 char *strpbrk(const char *s1, const char *s2)
    362 {
    363         assert(s1 != NULL);
    364         assert(s2 != NULL);
    365 
    366         char *ptr = strpbrk_null(s1, s2);
    367         return (*ptr == '\0') ? NULL : ptr;
    368 }
    369 
    370 /**
    371  * Get the length of a complementary substring.
    372  *
    373  * @param s1 String that shall be searched for complementary prefix.
    374  * @param s2 String of bytes that shall not occur in the prefix.
    375  * @return Length of the prefix.
    376  */
    377 size_t strcspn(const char *s1, const char *s2)
    378 {
    379         assert(s1 != NULL);
    380         assert(s2 != NULL);
    381 
    382         char *ptr = strpbrk_null(s1, s2);
    383         return (size_t) (ptr - s1);
    384 }
    385 
    386 /**
    387  * Get length of a substring.
    388  *
    389  * @param s1 String that shall be searched for prefix.
    390  * @param s2 String of bytes that the prefix must consist of.
    391  * @return Length of the prefix.
    392  */
    393 size_t strspn(const char *s1, const char *s2)
    394 {
    395         assert(s1 != NULL);
    396         assert(s2 != NULL);
    397 
    398         const char *ptr;
    399         for (ptr = s1; *ptr != '\0'; ++ptr) {
    400                 if (!strchr(s2, *ptr)) {
    401                         break;
    402                 }
    403         }
    404         return ptr - s1;
    405 }
    406 
    407 /**
    408  * Find a substring. Uses Knuth-Morris-Pratt algorithm.
    409  *
    410  * @param s1 String in which to look for a substring.
    411  * @param s2 Substring to look for.
    412  * @return Pointer to the first character of the substring in s1, or NULL if
    413  *     not found.
    414  */
    415 char *strstr(const char *haystack, const char *needle)
    416 {
    417         assert(haystack != NULL);
    418         assert(needle != NULL);
    419 
    420         /* Special case - needle is an empty string. */
    421         if (needle[0] == '\0') {
    422                 return (char *) haystack;
    423         }
    424 
    425         /* Preprocess needle. */
    426         size_t nlen = strlen(needle);
    427         size_t prefix_table[nlen + 1];
    428 
    429         size_t i = 0;
    430         ssize_t j = -1;
    431 
    432         prefix_table[i] = j;
    433 
    434         while (i < nlen) {
    435                 while (j >= 0 && needle[i] != needle[j]) {
    436                         j = prefix_table[j];
    437                 }
    438                 i++;
    439                 j++;
    440                 prefix_table[i] = j;
    441         }
    442 
    443         /* Search needle using the precomputed table. */
    444         size_t npos = 0;
    445 
    446         for (size_t hpos = 0; haystack[hpos] != '\0'; ++hpos) {
    447                 while (npos != 0 && haystack[hpos] != needle[npos]) {
    448                         npos = prefix_table[npos];
    449                 }
    450 
    451                 if (haystack[hpos] == needle[npos]) {
    452                         npos++;
    453 
    454                         if (npos == nlen) {
    455                                 return (char *) (haystack + hpos - nlen + 1);
    456                         }
    457                 }
    458         }
    459 
    460         return NULL;
    461 }
    462 
    463 /** Split string by delimiters.
    464  *
    465  * @param s             String to be tokenized. May not be NULL.
    466  * @param delim         String with the delimiters.
    467  * @return              Pointer to the prefix of @a s before the first
    468  *                      delimiter character. NULL if no such prefix
    469  *                      exists.
    470  */
    471 char *strtok(char *s, const char *delim)
    472 {
    473         static char *next;
    474 
    475         return strtok_r(s, delim, &next);
    476 }
    477 
    478189
    479190/** Split string by delimiters.
     
    491202char *strtok_r(char *s, const char *delim, char **next)
    492203{
    493         char *start, *end;
    494 
    495         if (s == NULL)
    496                 s = *next;
    497 
    498         /* Skip over leading delimiters. */
    499         while (*s && (strchr(delim, *s) != NULL))
    500                 ++s;
    501         start = s;
    502 
    503         /* Skip over token characters. */
    504         while (*s && (strchr(delim, *s) == NULL))
    505                 ++s;
    506         end = s;
    507         *next = (*s ? s + 1 : s);
    508 
    509         if (start == end) {
    510                 return NULL;    /* No more tokens. */
    511         }
    512 
    513         /* Overwrite delimiter with NULL terminator. */
    514         *end = '\0';
    515         return start;
    516 }
    517 
    518 /**
    519  * String comparison using collating information.
    520  *
    521  * Currently ignores locale and just calls strcmp.
    522  *
    523  * @param s1 First string to be compared.
    524  * @param s2 Second string to be compared.
    525  * @return Difference of the first pair of inequal characters,
    526  *     or 0 if strings have the same content.
    527  */
    528 int strcoll(const char *s1, const char *s2)
    529 {
    530         assert(s1 != NULL);
    531         assert(s2 != NULL);
    532 
    533         return strcmp(s1, s2);
    534 }
    535 
    536 /**
    537  * Transform a string in such a way that the resulting string yields the same
    538  * results when passed to the strcmp as if the original string is passed to
    539  * the strcoll.
    540  *
    541  * Since strcoll is equal to strcmp here, this just makes a copy.
    542  *
    543  * @param s1 Transformed string.
    544  * @param s2 Original string.
    545  * @param n Maximum length of the transformed string.
    546  * @return Length of the transformed string.
    547  */
    548 size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n)
    549 {
    550         assert(s1 != NULL || n == 0);
    551         assert(s2 != NULL);
    552 
    553         size_t len = strlen(s2);
    554 
    555         if (n > len) {
    556                 strcpy(s1, s2);
    557         }
    558 
    559         return len;
    560 }
    561 
    562 /**
    563  * Get error message string.
    564  *
    565  * @param errnum Error code for which to obtain human readable string.
    566  * @return Error message.
    567  */
    568 char *strerror(int errnum)
    569 {
    570         // FIXME: move strerror() and strerror_r() to libc.
    571         return (char *) str_error(errnum);
     204        return __strtok_r(s, delim, next);
    572205}
    573206
     
    593226
    594227        return EOK;
    595 }
    596 
    597 /**
    598  * Get length of the string.
    599  *
    600  * @param s String which length shall be determined.
    601  * @return Length of the string.
    602  */
    603 size_t strlen(const char *s)
    604 {
    605         assert(s != NULL);
    606 
    607         return (size_t) (strchr(s, '\0') - s);
    608228}
    609229
Note: See TracChangeset for help on using the changeset viewer.