Changes in kernel/generic/src/lib/str.c [42e91ae:d066259] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/str.c
r42e91ae rd066259 789 789 str_ncpy(dest, size + 1, src, size); 790 790 return dest; 791 } 792 793 /** Convert string to uint64_t (internal variant). 794 * 795 * @param nptr Pointer to string. 796 * @param endptr Pointer to the first invalid character is stored here. 797 * @param base Zero or number between 2 and 36 inclusive. 798 * @param neg Indication of unary minus is stored here. 799 * @apram result Result of the conversion. 800 * 801 * @return EOK if conversion was successful. 802 * 803 */ 804 static errno_t str_uint(const char *nptr, char **endptr, unsigned int base, 805 bool *neg, uint64_t *result) 806 { 807 assert(endptr != NULL); 808 assert(neg != NULL); 809 assert(result != NULL); 810 811 *neg = false; 812 const char *str = nptr; 813 814 /* Ignore leading whitespace */ 815 while (isspace(*str)) 816 str++; 817 818 if (*str == '-') { 819 *neg = true; 820 str++; 821 } else if (*str == '+') 822 str++; 823 824 if (base == 0) { 825 /* Decode base if not specified */ 826 base = 10; 827 828 if (*str == '0') { 829 base = 8; 830 str++; 831 832 switch (*str) { 833 case 'b': 834 case 'B': 835 base = 2; 836 str++; 837 break; 838 case 'o': 839 case 'O': 840 base = 8; 841 str++; 842 break; 843 case 'd': 844 case 'D': 845 case 't': 846 case 'T': 847 base = 10; 848 str++; 849 break; 850 case 'x': 851 case 'X': 852 base = 16; 853 str++; 854 break; 855 default: 856 str--; 857 } 858 } 859 } else { 860 /* Check base range */ 861 if ((base < 2) || (base > 36)) { 862 *endptr = (char *) str; 863 return EINVAL; 864 } 865 } 866 867 *result = 0; 868 const char *startstr = str; 869 870 while (*str != 0) { 871 unsigned int digit; 872 873 if ((*str >= 'a') && (*str <= 'z')) 874 digit = *str - 'a' + 10; 875 else if ((*str >= 'A') && (*str <= 'Z')) 876 digit = *str - 'A' + 10; 877 else if ((*str >= '0') && (*str <= '9')) 878 digit = *str - '0'; 879 else 880 break; 881 882 if (digit >= base) 883 break; 884 885 uint64_t prev = *result; 886 *result = (*result) * base + digit; 887 888 if (*result < prev) { 889 /* Overflow */ 890 *endptr = (char *) str; 891 return EOVERFLOW; 892 } 893 894 str++; 895 } 896 897 if (str == startstr) { 898 /* 899 * No digits were decoded => first invalid character is 900 * the first character of the string. 901 */ 902 str = nptr; 903 } 904 905 *endptr = (char *) str; 906 907 if (str == nptr) 908 return EINVAL; 909 910 return EOK; 911 } 912 913 /** Convert string to uint64_t. 914 * 915 * @param nptr Pointer to string. 916 * @param endptr If not NULL, pointer to the first invalid character 917 * is stored here. 918 * @param base Zero or number between 2 and 36 inclusive. 919 * @param strict Do not allow any trailing characters. 920 * @param result Result of the conversion. 921 * 922 * @return EOK if conversion was successful. 923 * 924 */ 925 errno_t str_uint64_t(const char *nptr, char **endptr, unsigned int base, 926 bool strict, uint64_t *result) 927 { 928 assert(result != NULL); 929 930 bool neg; 931 char *lendptr; 932 errno_t ret = str_uint(nptr, &lendptr, base, &neg, result); 933 934 if (endptr != NULL) 935 *endptr = (char *) lendptr; 936 937 if (ret != EOK) 938 return ret; 939 940 /* Do not allow negative values */ 941 if (neg) 942 return EINVAL; 943 944 /* 945 * Check whether we are at the end of 946 * the string in strict mode 947 */ 948 if ((strict) && (*lendptr != 0)) 949 return EINVAL; 950 951 return EOK; 791 952 } 792 953
Note:
See TracChangeset
for help on using the changeset viewer.