Changes in kernel/generic/src/lib/str.c [42e91ae:aafed15] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/str.c
r42e91ae raafed15 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2005 Martin Decky4 * Copyright (c) 2008 Jiri Svoboda5 * Copyright (c) 2011 Martin Sucha6 * Copyright (c) 2011 Oleg Romanenko7 3 * All rights reserved. 8 4 * … … 107 103 108 104 #include <str.h> 109 105 #include <cpu.h> 106 #include <arch/asm.h> 107 #include <arch.h> 108 #include <errno.h> 109 #include <align.h> 110 110 #include <assert.h> 111 #include <errno.h> 112 #include <stdbool.h> 113 #include <stddef.h> 114 #include <stdint.h> 111 #include <macros.h> 115 112 #include <stdlib.h> 116 117 #include <align.h>118 #include <macros.h>119 113 120 114 /** Check the condition if wchar_t is signed */ … … 622 616 } 623 617 624 /** Convert wide string to string.625 *626 * Convert wide string @a src to string. The output is written to the buffer627 * specified by @a dest and @a size. @a size must be non-zero and the string628 * 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 position679 * @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 position687 * 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 position709 * @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 position715 * 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 732 618 /** Duplicate string. 733 619 * … … 789 675 str_ncpy(dest, size + 1, src, size); 790 676 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 buffer 682 * specified by @a dest and @a size. @a size must be non-zero and the string 683 * 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 position 735 * @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 position 743 * 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 position 765 * @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 position 771 * 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 else 875 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 is 895 * 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 character 912 * 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 of 941 * the string in strict mode 942 */ 943 if ((strict) && (*lendptr != 0)) 944 return EINVAL; 945 946 return EOK; 791 947 } 792 948
Note:
See TracChangeset
for help on using the changeset viewer.