Rev 4263 | Rev 4581 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4263 | Rev 4327 | ||
|---|---|---|---|
| Line 33... | Line 33... | ||
| 33 | /** @file |
33 | /** @file |
| 34 | */ |
34 | */ |
| 35 | 35 | ||
| 36 | #include <string.h> |
36 | #include <string.h> |
| 37 | #include <stdlib.h> |
37 | #include <stdlib.h> |
| - | 38 | #include <assert.h> |
|
| 38 | #include <limits.h> |
39 | #include <limits.h> |
| 39 | #include <ctype.h> |
40 | #include <ctype.h> |
| 40 | #include <malloc.h> |
41 | #include <malloc.h> |
| 41 | #include <errno.h> |
42 | #include <errno.h> |
| 42 | #include <align.h> |
43 | #include <align.h> |
| - | 44 | #include <mem.h> |
|
| 43 | #include <string.h> |
45 | #include <string.h> |
| 44 | 46 | ||
| 45 | /** Byte mask consisting of lowest @n bits (out of 8) */ |
47 | /** Byte mask consisting of lowest @n bits (out of 8) */ |
| 46 | #define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
48 | #define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
| 47 | 49 | ||
| Line 459... | Line 461... | ||
| 459 | 461 | ||
| 460 | return 0; |
462 | return 0; |
| 461 | 463 | ||
| 462 | } |
464 | } |
| 463 | 465 | ||
| 464 | /** Copy NULL-terminated string. |
466 | /** Copy string. |
| 465 | * |
467 | * |
| 466 | * Copy source string @a src to destination buffer @a dst. |
468 | * Copy source string @a src to destination buffer @a dest. |
| 467 | * No more than @a size bytes are written. NULL-terminator is always |
469 | * No more than @a size bytes are written. If the size of the output buffer |
| 468 | * written after the last succesfully copied character (i.e. if the |
470 | * is at least one byte, the output string will always be well-formed, i.e. |
| 469 | * destination buffer is has at least 1 byte, it will be always |
471 | * null-terminated and containing only complete characters. |
| 470 | * NULL-terminated). |
- | |
| 471 | * |
472 | * |
| 472 | * @param src Source string. |
- | |
| 473 | * @param dst Destination buffer. |
473 | * @param dst Destination buffer. |
| 474 | * @param count Size of the destination buffer. |
474 | * @param count Size of the destination buffer (must be > 0). |
| 475 | * |
475 | * @param src Source string. |
| 476 | */ |
476 | */ |
| 477 | void str_ncpy(char *dst, const char *src, size_t size) |
477 | void str_cpy(char *dest, size_t size, const char *src) |
| 478 | { |
478 | { |
| 479 | /* No space for the NULL-terminator in the buffer */ |
- | |
| 480 | if (size == 0) |
- | |
| 481 | return; |
- | |
| 482 | - | ||
| 483 | wchar_t ch; |
479 | wchar_t ch; |
| 484 | size_t str_off = 0; |
480 | size_t src_off; |
| 485 | size_t dst_off = 0; |
481 | size_t dest_off; |
| - | 482 | ||
| - | 483 | /* There must be space for a null terminator in the buffer. */ |
|
| - | 484 | assert(size > 0); |
|
| 486 | 485 | ||
| - | 486 | src_off = 0; |
|
| - | 487 | dest_off = 0; |
|
| - | 488 | ||
| 487 | while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { |
489 | while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { |
| 488 | if (chr_encode(ch, dst, &dst_off, size) != EOK) |
490 | if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
| 489 | break; |
491 | break; |
| 490 | } |
492 | } |
| - | 493 | ||
| - | 494 | dest[dest_off] = '\0'; |
|
| - | 495 | } |
|
| - | 496 | ||
| - | 497 | /** Copy size-limited substring. |
|
| - | 498 | * |
|
| - | 499 | * Copy prefix of string @a src of max. size @a size to destination buffer |
|
| - | 500 | * @a dest. No more than @a size bytes are written. The output string will |
|
| - | 501 | * always be well-formed, i.e. null-terminated and containing only complete |
|
| - | 502 | * characters. |
|
| - | 503 | * |
|
| - | 504 | * No more than @a n bytes are read from the input string, so it does not |
|
| - | 505 | * have to be null-terminated. |
|
| - | 506 | * |
|
| - | 507 | * @param dst Destination buffer. |
|
| - | 508 | * @param count Size of the destination buffer (must be > 0). |
|
| - | 509 | * @param src Source string. |
|
| - | 510 | * @param n Maximum number of bytes to read from @a src. |
|
| - | 511 | */ |
|
| - | 512 | void str_ncpy(char *dest, size_t size, const char *src, size_t n) |
|
| - | 513 | { |
|
| - | 514 | wchar_t ch; |
|
| - | 515 | size_t src_off; |
|
| - | 516 | size_t dest_off; |
|
| - | 517 | ||
| - | 518 | /* There must be space for a null terminator in the buffer. */ |
|
| - | 519 | assert(size > 0); |
|
| 491 | 520 | ||
| 492 | if (dst_off >= size) |
521 | src_off = 0; |
| 493 | dst[size - 1] = 0; |
522 | dest_off = 0; |
| - | 523 | ||
| - | 524 | while ((ch = str_decode(src, &src_off, n)) != 0) { |
|
| - | 525 | if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
|
| - | 526 | break; |
|
| 494 | else |
527 | } |
| - | 528 | ||
| 495 | dst[dst_off] = 0; |
529 | dest[dest_off] = '\0'; |
| - | 530 | } |
|
| - | 531 | ||
| - | 532 | /** Append one string to another. |
|
| - | 533 | * |
|
| - | 534 | * Append source string @a src to string in destination buffer @a dest. |
|
| - | 535 | * Size of the destination buffer is @a dest. If the size of the output buffer |
|
| - | 536 | * is at least one byte, the output string will always be well-formed, i.e. |
|
| - | 537 | * null-terminated and containing only complete characters. |
|
| - | 538 | * |
|
| - | 539 | * @param dst Destination buffer. |
|
| - | 540 | * @param count Size of the destination buffer. |
|
| - | 541 | * @param src Source string. |
|
| - | 542 | */ |
|
| - | 543 | void str_append(char *dest, size_t size, const char *src) |
|
| - | 544 | { |
|
| - | 545 | size_t dstr_size; |
|
| - | 546 | ||
| - | 547 | dstr_size = str_size(dest); |
|
| - | 548 | str_cpy(dest + dstr_size, size - dstr_size, src); |
|
| 496 | } |
549 | } |
| 497 | 550 | ||
| 498 | /** Copy NULL-terminated wide string to string |
551 | /** Copy NULL-terminated wide string to string |
| 499 | * |
552 | * |
| 500 | * Copy source wide string @a src to destination buffer @a dst. |
553 | * Copy source wide string @a src to destination buffer @a dst. |
| Line 533... | Line 586... | ||
| 533 | * |
586 | * |
| 534 | * @param str String to search. |
587 | * @param str String to search. |
| 535 | * @param ch Character to look for. |
588 | * @param ch Character to look for. |
| 536 | * |
589 | * |
| 537 | * @return Pointer to character in @a str or NULL if not found. |
590 | * @return Pointer to character in @a str or NULL if not found. |
| 538 | * |
- | |
| 539 | */ |
591 | */ |
| 540 | const char *str_chr(const char *str, wchar_t ch) |
592 | const char *str_chr(const char *str, wchar_t ch) |
| 541 | { |
593 | { |
| 542 | wchar_t acc; |
594 | wchar_t acc; |
| 543 | size_t off = 0; |
595 | size_t off = 0; |
| - | 596 | size_t last = 0; |
|
| 544 | 597 | ||
| 545 | while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
598 | while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
| 546 | if (acc == ch) |
599 | if (acc == ch) |
| 547 | return (str + off); |
600 | return (str + last); |
| - | 601 | last = off; |
|
| 548 | } |
602 | } |
| 549 | 603 | ||
| 550 | return NULL; |
604 | return NULL; |
| 551 | } |
605 | } |
| 552 | 606 | ||
| - | 607 | /** Find last occurence of character in string. |
|
| - | 608 | * |
|
| - | 609 | * @param str String to search. |
|
| - | 610 | * @param ch Character to look for. |
|
| - | 611 | * |
|
| - | 612 | * @return Pointer to character in @a str or NULL if not found. |
|
| - | 613 | */ |
|
| - | 614 | const char *str_rchr(const char *str, wchar_t ch) |
|
| - | 615 | { |
|
| - | 616 | wchar_t acc; |
|
| - | 617 | size_t off = 0; |
|
| - | 618 | size_t last = 0; |
|
| - | 619 | char *res = NULL; |
|
| - | 620 | ||
| - | 621 | while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
|
| - | 622 | if (acc == ch) |
|
| - | 623 | res = (str + last); |
|
| - | 624 | last = off; |
|
| - | 625 | } |
|
| - | 626 | ||
| - | 627 | return res; |
|
| - | 628 | } |
|
| - | 629 | ||
| 553 | /** Insert a wide character into a wide string. |
630 | /** Insert a wide character into a wide string. |
| 554 | * |
631 | * |
| 555 | * Insert a wide character into a wide string at position |
632 | * Insert a wide character into a wide string at position |
| 556 | * @a pos. The characters after the position are shifted. |
633 | * @a pos. The characters after the position are shifted. |
| 557 | * |
634 | * |
| Line 604... | Line 681... | ||
| 604 | str[i - 1] = str[i]; |
681 | str[i - 1] = str[i]; |
| 605 | 682 | ||
| 606 | return true; |
683 | return true; |
| 607 | } |
684 | } |
| 608 | 685 | ||
| 609 | /** Count the number of characters in the string, not including terminating 0. |
- | |
| 610 | * |
- | |
| 611 | * @param str String. |
- | |
| 612 | * @return Number of characters in string. |
- | |
| 613 | */ |
- | |
| 614 | size_t strlen(const char *str) |
- | |
| 615 | { |
- | |
| 616 | size_t counter = 0; |
- | |
| 617 | - | ||
| 618 | while (str[counter] != 0) |
- | |
| 619 | counter++; |
- | |
| 620 | - | ||
| 621 | return counter; |
- | |
| 622 | } |
- | |
| 623 | - | ||
| 624 | int strcmp(const char *a, const char *b) |
- | |
| 625 | { |
- | |
| 626 | int c = 0; |
- | |
| 627 | - | ||
| 628 | while (a[c] && b[c] && (!(a[c] - b[c]))) |
- | |
| 629 | c++; |
- | |
| 630 | - | ||
| 631 | return (a[c] - b[c]); |
- | |
| 632 | } |
- | |
| 633 | - | ||
| 634 | int strncmp(const char *a, const char *b, size_t n) |
- | |
| 635 | { |
- | |
| 636 | size_t c = 0; |
- | |
| 637 | - | ||
| 638 | while (c < n && a[c] && b[c] && (!(a[c] - b[c]))) |
- | |
| 639 | c++; |
- | |
| 640 | - | ||
| 641 | return ( c < n ? a[c] - b[c] : 0); |
- | |
| 642 | - | ||
| 643 | } |
- | |
| 644 | - | ||
| 645 | int stricmp(const char *a, const char *b) |
686 | int stricmp(const char *a, const char *b) |
| 646 | { |
687 | { |
| 647 | int c = 0; |
688 | int c = 0; |
| 648 | 689 | ||
| 649 | while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
690 | while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
| 650 | c++; |
691 | c++; |
| 651 | 692 | ||
| 652 | return (tolower(a[c]) - tolower(b[c])); |
693 | return (tolower(a[c]) - tolower(b[c])); |
| 653 | } |
694 | } |
| 654 | 695 | ||
| 655 | /** Return pointer to the first occurence of character c in string. |
- | |
| 656 | * |
- | |
| 657 | * @param str Scanned string. |
- | |
| 658 | * @param c Searched character (taken as one byte). |
- | |
| 659 | * @return Pointer to the matched character or NULL if it is not |
- | |
| 660 | * found in given string. |
- | |
| 661 | */ |
- | |
| 662 | char *strchr(const char *str, int c) |
- | |
| 663 | { |
- | |
| 664 | while (*str != '\0') { |
- | |
| 665 | if (*str == (char) c) |
- | |
| 666 | return (char *) str; |
- | |
| 667 | str++; |
- | |
| 668 | } |
- | |
| 669 | - | ||
| 670 | return NULL; |
- | |
| 671 | } |
- | |
| 672 | - | ||
| 673 | /** Return pointer to the last occurence of character c in string. |
- | |
| 674 | * |
- | |
| 675 | * @param str Scanned string. |
- | |
| 676 | * @param c Searched character (taken as one byte). |
- | |
| 677 | * @return Pointer to the matched character or NULL if it is not |
- | |
| 678 | * found in given string. |
- | |
| 679 | */ |
- | |
| 680 | char *strrchr(const char *str, int c) |
- | |
| 681 | { |
- | |
| 682 | char *retval = NULL; |
- | |
| 683 | - | ||
| 684 | while (*str != '\0') { |
- | |
| 685 | if (*str == (char) c) |
- | |
| 686 | retval = (char *) str; |
- | |
| 687 | str++; |
- | |
| 688 | } |
- | |
| 689 | - | ||
| 690 | return (char *) retval; |
- | |
| 691 | } |
- | |
| 692 | - | ||
| 693 | /** Convert string to a number. |
696 | /** Convert string to a number. |
| 694 | * Core of strtol and strtoul functions. |
697 | * Core of strtol and strtoul functions. |
| 695 | * |
698 | * |
| 696 | * @param nptr Pointer to string. |
699 | * @param nptr Pointer to string. |
| 697 | * @param endptr If not NULL, function stores here pointer to the first |
700 | * @param endptr If not NULL, function stores here pointer to the first |
| Line 837... | Line 840... | ||
| 837 | number = _strtoul(nptr, endptr, base, &sgn); |
840 | number = _strtoul(nptr, endptr, base, &sgn); |
| 838 | 841 | ||
| 839 | return (sgn ? -number : number); |
842 | return (sgn ? -number : number); |
| 840 | } |
843 | } |
| 841 | 844 | ||
| 842 | char *strcpy(char *dest, const char *src) |
- | |
| 843 | { |
- | |
| 844 | char *orig = dest; |
- | |
| 845 | - | ||
| 846 | while ((*(dest++) = *(src++))) |
- | |
| 847 | ; |
- | |
| 848 | return orig; |
- | |
| 849 | } |
- | |
| 850 | - | ||
| 851 | char *strncpy(char *dest, const char *src, size_t n) |
- | |
| 852 | { |
- | |
| 853 | char *orig = dest; |
- | |
| 854 | - | ||
| 855 | while ((*(dest++) = *(src++)) && --n) |
- | |
| 856 | ; |
- | |
| 857 | return orig; |
- | |
| 858 | } |
- | |
| 859 | - | ||
| 860 | char *strcat(char *dest, const char *src) |
- | |
| 861 | { |
- | |
| 862 | char *orig = dest; |
- | |
| 863 | while (*dest++) |
- | |
| 864 | ; |
- | |
| 865 | --dest; |
- | |
| 866 | while ((*dest++ = *src++)) |
- | |
| 867 | ; |
- | |
| 868 | return orig; |
- | |
| 869 | } |
- | |
| 870 | - | ||
| 871 | char * strdup(const char *s1) |
845 | char *str_dup(const char *src) |
| 872 | { |
846 | { |
| 873 | size_t len = strlen(s1) + 1; |
847 | size_t size = str_size(src); |
| 874 | void *ret = malloc(len); |
848 | void *dest = malloc(size + 1); |
| 875 | 849 | ||
| 876 | if (ret == NULL) |
850 | if (dest == NULL) |
| 877 | return (char *) NULL; |
851 | return (char *) NULL; |
| 878 | 852 | ||
| 879 | return (char *) memcpy(ret, s1, len); |
853 | return (char *) memcpy(dest, src, size + 1); |
| 880 | } |
854 | } |
| 881 | 855 | ||
| 882 | char *strtok(char *s, const char *delim) |
856 | char *strtok(char *s, const char *delim) |
| 883 | { |
857 | { |
| 884 | static char *next; |
858 | static char *next; |
| Line 892... | Line 866... | ||
| 892 | 866 | ||
| 893 | if (s == NULL) |
867 | if (s == NULL) |
| 894 | s = *next; |
868 | s = *next; |
| 895 | 869 | ||
| 896 | /* Skip over leading delimiters. */ |
870 | /* Skip over leading delimiters. */ |
| 897 | while (*s && (strchr(delim, *s) != NULL)) ++s; |
871 | while (*s && (str_chr(delim, *s) != NULL)) ++s; |
| 898 | start = s; |
872 | start = s; |
| 899 | 873 | ||
| 900 | /* Skip over token characters. */ |
874 | /* Skip over token characters. */ |
| 901 | while (*s && (strchr(delim, *s) == NULL)) ++s; |
875 | while (*s && (str_chr(delim, *s) == NULL)) ++s; |
| 902 | end = s; |
876 | end = s; |
| 903 | *next = (*s ? s + 1 : s); |
877 | *next = (*s ? s + 1 : s); |
| 904 | 878 | ||
| 905 | if (start == end) { |
879 | if (start == end) { |
| 906 | return NULL; /* No more tokens. */ |
880 | return NULL; /* No more tokens. */ |