Changeset 99d3123 in mainline
- Timestamp:
- 2018-07-12T15:18:55Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9912f49
- Parents:
- 2eadda9
- Location:
- uspace/lib
- Files:
-
- 3 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/Makefile
r2eadda9 r99d3123 79 79 generic/mem.c \ 80 80 generic/str.c \ 81 generic/string.c \ 81 82 generic/str_error.c \ 82 83 generic/strtol.c \ … … 203 204 test/stdio.c \ 204 205 test/stdlib.c \ 205 test/str.c 206 test/str.c \ 207 test/string.c 206 208 207 209 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/c/test/main.c
r2eadda9 r99d3123 42 42 PCUT_IMPORT(stdlib); 43 43 PCUT_IMPORT(str); 44 PCUT_IMPORT(string); 44 45 PCUT_IMPORT(table); 45 46 -
uspace/lib/posix/include/posix/string.h
r2eadda9 r99d3123 48 48 49 49 #include "libc/mem.h" 50 #undef _HELENOS_SOURCE 51 #include "libc/string.h" 50 52 51 53 /* 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);54 54 extern char *stpcpy(char *__restrict__ dest, const char *__restrict__ src); 55 55 extern 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);58 56 extern void *memccpy(void *__restrict__ dest, const void *__restrict__ src, int c, size_t n); 59 57 extern char *strdup(const char *s); 60 58 extern char *strndup(const char *s, size_t n); 61 59 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 66 60 /* Search Functions */ 67 extern char *strchr(const char *s, int c);68 extern char *strrchr(const char *s, int c);69 61 extern 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);74 62 75 63 /* Tokenization functions. */ 76 64 extern 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);83 65 84 66 /* Error Messages */ 85 extern char *strerror(int errnum);86 67 extern int strerror_r(int errnum, char *buf, size_t bufsz); 87 68 88 69 /* String Length */ 89 extern size_t strlen(const char *s);90 70 extern size_t strnlen(const char *s, size_t n); 91 71 -
uspace/lib/posix/src/string.c
r2eadda9 r99d3123 2 2 * Copyright (c) 2011 Petr Koupy 3 3 * Copyright (c) 2011 Jiri Zarevucky 4 * Copyright (c) 2018 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 49 50 50 51 /** 51 * The same as strpbrk, except it returns pointer to the nul terminator52 * 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 the57 * 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 /**96 52 * Copy a string. 97 53 * … … 151 107 152 108 /** 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 /**188 109 * Copy limited number of bytes in memory. 189 110 * … … 249 170 250 171 /** 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 /**335 172 * Scan string for a first occurence of a character. 336 173 * … … 350 187 return (char *) s; 351 188 } 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 if413 * 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 first468 * delimiter character. NULL if no such prefix469 * 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 478 189 479 190 /** Split string by delimiters. … … 491 202 char *strtok_r(char *s, const char *delim, char **next) 492 203 { 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); 572 205 } 573 206 … … 593 226 594 227 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);608 228 } 609 229
Note:
See TracChangeset
for help on using the changeset viewer.