Changes in kernel/generic/src/lib/str.c [aafed15:42e91ae] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/str.c
raafed15 r42e91ae 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2005 Martin Decky 4 * Copyright (c) 2008 Jiri Svoboda 5 * Copyright (c) 2011 Martin Sucha 6 * Copyright (c) 2011 Oleg Romanenko 3 7 * All rights reserved. 4 8 * … … 103 107 104 108 #include <str.h> 105 #include <cpu.h> 106 #include <arch/asm.h> 107 #include <arch.h> 109 110 #include <assert.h> 108 111 #include <errno.h> 112 #include <stdbool.h> 113 #include <stddef.h> 114 #include <stdint.h> 115 #include <stdlib.h> 116 109 117 #include <align.h> 110 #include <assert.h>111 118 #include <macros.h> 112 #include <stdlib.h>113 119 114 120 /** Check the condition if wchar_t is signed */ … … 616 622 } 617 623 624 /** Convert wide string to string. 625 * 626 * Convert wide string @a src to string. The output is written to the buffer 627 * specified by @a dest and @a size. @a size must be non-zero and the string 628 * written will always be well-formed. 629 * 630 * @param dest Destination buffer. 631 * @param size Size of the destination buffer. 632 * @param src Source wide string. 633 */ 634 void wstr_to_str(char *dest, size_t size, const wchar_t *src) 635 { 636 wchar_t ch; 637 size_t src_idx; 638 size_t dest_off; 639 640 /* There must be space for a null terminator in the buffer. */ 641 assert(size > 0); 642 643 src_idx = 0; 644 dest_off = 0; 645 646 while ((ch = src[src_idx++]) != 0) { 647 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 648 break; 649 } 650 651 dest[dest_off] = '\0'; 652 } 653 654 /** Find first occurence of character in string. 655 * 656 * @param str String to search. 657 * @param ch Character to look for. 658 * 659 * @return Pointer to character in @a str or NULL if not found. 660 */ 661 char *str_chr(const char *str, wchar_t ch) 662 { 663 wchar_t acc; 664 size_t off = 0; 665 size_t last = 0; 666 667 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 668 if (acc == ch) 669 return (char *) (str + last); 670 last = off; 671 } 672 673 return NULL; 674 } 675 676 /** Insert a wide character into a wide string. 677 * 678 * Insert a wide character into a wide string at position 679 * @a pos. The characters after the position are shifted. 680 * 681 * @param str String to insert to. 682 * @param ch Character to insert to. 683 * @param pos Character index where to insert. 684 * @param max_pos Characters in the buffer. 685 * 686 * @return True if the insertion was sucessful, false if the position 687 * is out of bounds. 688 * 689 */ 690 bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos) 691 { 692 size_t len = wstr_length(str); 693 694 if ((pos > len) || (pos + 1 > max_pos)) 695 return false; 696 697 size_t i; 698 for (i = len; i + 1 > pos; i--) 699 str[i + 1] = str[i]; 700 701 str[pos] = ch; 702 703 return true; 704 } 705 706 /** Remove a wide character from a wide string. 707 * 708 * Remove a wide character from a wide string at position 709 * @a pos. The characters after the position are shifted. 710 * 711 * @param str String to remove from. 712 * @param pos Character index to remove. 713 * 714 * @return True if the removal was sucessful, false if the position 715 * is out of bounds. 716 * 717 */ 718 bool wstr_remove(wchar_t *str, size_t pos) 719 { 720 size_t len = wstr_length(str); 721 722 if (pos >= len) 723 return false; 724 725 size_t i; 726 for (i = pos + 1; i <= len; i++) 727 str[i - 1] = str[i]; 728 729 return true; 730 } 731 618 732 /** Duplicate string. 619 733 * … … 675 789 str_ncpy(dest, size + 1, src, size); 676 790 return dest; 677 }678 679 /** Convert wide string to string.680 *681 * Convert wide string @a src to string. The output is written to the buffer682 * specified by @a dest and @a size. @a size must be non-zero and the string683 * written will always be well-formed.684 *685 * @param dest Destination buffer.686 * @param size Size of the destination buffer.687 * @param src Source wide string.688 */689 void wstr_to_str(char *dest, size_t size, const wchar_t *src)690 {691 wchar_t ch;692 size_t src_idx;693 size_t dest_off;694 695 /* There must be space for a null terminator in the buffer. */696 assert(size > 0);697 698 src_idx = 0;699 dest_off = 0;700 701 while ((ch = src[src_idx++]) != 0) {702 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)703 break;704 }705 706 dest[dest_off] = '\0';707 }708 709 /** Find first occurence of character in string.710 *711 * @param str String to search.712 * @param ch Character to look for.713 *714 * @return Pointer to character in @a str or NULL if not found.715 *716 */717 char *str_chr(const char *str, wchar_t ch)718 {719 wchar_t acc;720 size_t off = 0;721 size_t last = 0;722 723 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {724 if (acc == ch)725 return (char *) (str + last);726 last = off;727 }728 729 return NULL;730 }731 732 /** Insert a wide character into a wide string.733 *734 * Insert a wide character into a wide string at position735 * @a pos. The characters after the position are shifted.736 *737 * @param str String to insert to.738 * @param ch Character to insert to.739 * @param pos Character index where to insert.740 * @param max_pos Characters in the buffer.741 *742 * @return True if the insertion was sucessful, false if the position743 * is out of bounds.744 *745 */746 bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)747 {748 size_t len = wstr_length(str);749 750 if ((pos > len) || (pos + 1 > max_pos))751 return false;752 753 size_t i;754 for (i = len; i + 1 > pos; i--)755 str[i + 1] = str[i];756 757 str[pos] = ch;758 759 return true;760 }761 762 /** Remove a wide character from a wide string.763 *764 * Remove a wide character from a wide string at position765 * @a pos. The characters after the position are shifted.766 *767 * @param str String to remove from.768 * @param pos Character index to remove.769 *770 * @return True if the removal was sucessful, false if the position771 * is out of bounds.772 *773 */774 bool wstr_remove(wchar_t *str, size_t pos)775 {776 size_t len = wstr_length(str);777 778 if (pos >= len)779 return false;780 781 size_t i;782 for (i = pos + 1; i <= len; i++)783 str[i - 1] = str[i];784 785 return true;786 }787 788 /** Convert string to uint64_t (internal variant).789 *790 * @param nptr Pointer to string.791 * @param endptr Pointer to the first invalid character is stored here.792 * @param base Zero or number between 2 and 36 inclusive.793 * @param neg Indication of unary minus is stored here.794 * @apram result Result of the conversion.795 *796 * @return EOK if conversion was successful.797 *798 */799 static errno_t str_uint(const char *nptr, char **endptr, unsigned int base,800 bool *neg, uint64_t *result)801 {802 assert(endptr != NULL);803 assert(neg != NULL);804 assert(result != NULL);805 806 *neg = false;807 const char *str = nptr;808 809 /* Ignore leading whitespace */810 while (isspace(*str))811 str++;812 813 if (*str == '-') {814 *neg = true;815 str++;816 } else if (*str == '+')817 str++;818 819 if (base == 0) {820 /* Decode base if not specified */821 base = 10;822 823 if (*str == '0') {824 base = 8;825 str++;826 827 switch (*str) {828 case 'b':829 case 'B':830 base = 2;831 str++;832 break;833 case 'o':834 case 'O':835 base = 8;836 str++;837 break;838 case 'd':839 case 'D':840 case 't':841 case 'T':842 base = 10;843 str++;844 break;845 case 'x':846 case 'X':847 base = 16;848 str++;849 break;850 default:851 str--;852 }853 }854 } else {855 /* Check base range */856 if ((base < 2) || (base > 36)) {857 *endptr = (char *) str;858 return EINVAL;859 }860 }861 862 *result = 0;863 const char *startstr = str;864 865 while (*str != 0) {866 unsigned int digit;867 868 if ((*str >= 'a') && (*str <= 'z'))869 digit = *str - 'a' + 10;870 else if ((*str >= 'A') && (*str <= 'Z'))871 digit = *str - 'A' + 10;872 else if ((*str >= '0') && (*str <= '9'))873 digit = *str - '0';874 else875 break;876 877 if (digit >= base)878 break;879 880 uint64_t prev = *result;881 *result = (*result) * base + digit;882 883 if (*result < prev) {884 /* Overflow */885 *endptr = (char *) str;886 return EOVERFLOW;887 }888 889 str++;890 }891 892 if (str == startstr) {893 /*894 * No digits were decoded => first invalid character is895 * the first character of the string.896 */897 str = nptr;898 }899 900 *endptr = (char *) str;901 902 if (str == nptr)903 return EINVAL;904 905 return EOK;906 }907 908 /** Convert string to uint64_t.909 *910 * @param nptr Pointer to string.911 * @param endptr If not NULL, pointer to the first invalid character912 * is stored here.913 * @param base Zero or number between 2 and 36 inclusive.914 * @param strict Do not allow any trailing characters.915 * @param result Result of the conversion.916 *917 * @return EOK if conversion was successful.918 *919 */920 errno_t str_uint64_t(const char *nptr, char **endptr, unsigned int base,921 bool strict, uint64_t *result)922 {923 assert(result != NULL);924 925 bool neg;926 char *lendptr;927 errno_t ret = str_uint(nptr, &lendptr, base, &neg, result);928 929 if (endptr != NULL)930 *endptr = (char *) lendptr;931 932 if (ret != EOK)933 return ret;934 935 /* Do not allow negative values */936 if (neg)937 return EINVAL;938 939 /*940 * Check whether we are at the end of941 * the string in strict mode942 */943 if ((strict) && (*lendptr != 0))944 return EINVAL;945 946 return EOK;947 791 } 948 792
Note:
See TracChangeset
for help on using the changeset viewer.