Changeset 30a5470 in mainline
- Timestamp:
- 2010-04-18T00:19:51Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c39a103
- Parents:
- 88dea9d
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/str.h
r88dea9d r30a5470 97 97 extern bool wstr_remove(wchar_t *str, size_t pos); 98 98 99 extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *); 100 99 101 #endif 100 102 -
kernel/generic/src/lib/str.c
r88dea9d r30a5470 110 110 #include <align.h> 111 111 #include <debug.h> 112 #include <macros.h> 112 113 113 114 /** Byte mask consisting of lowest @n bits (out of 8) */ … … 760 761 } 761 762 763 /** Convert string to uint64_t (internal variant). 764 * 765 * @param nptr Pointer to string. 766 * @param endptr Pointer to the first invalid character is stored here. 767 * @param base Zero or number between 2 and 36 inclusive. 768 * @param neg Indication of unary minus is stored here. 769 * @apram result Result of the conversion. 770 * 771 * @return EOK if conversion was successful. 772 * 773 */ 774 static int str_uint(const char *nptr, char **endptr, unsigned int base, 775 bool *neg, uint64_t *result) 776 { 777 ASSERT(endptr != NULL); 778 ASSERT(neg != NULL); 779 ASSERT(result != NULL); 780 781 *neg = false; 782 const char *str = nptr; 783 784 /* Ignore leading whitespace */ 785 while (isspace(*str)) 786 str++; 787 788 if (*str == '-') { 789 *neg = true; 790 str++; 791 } else if (*str == '+') 792 str++; 793 794 if (base == 0) { 795 /* Decode base if not specified */ 796 base = 10; 797 798 if (*str == '0') { 799 base = 8; 800 str++; 801 802 switch (*str) { 803 case 'b': 804 case 'B': 805 base = 2; 806 str++; 807 break; 808 case 'o': 809 case 'O': 810 base = 8; 811 str++; 812 break; 813 case 'd': 814 case 'D': 815 case 't': 816 case 'T': 817 base = 10; 818 str++; 819 break; 820 case 'x': 821 case 'X': 822 base = 16; 823 str++; 824 break; 825 } 826 } 827 } else { 828 /* Check base range */ 829 if ((base < 2) || (base > 36)) { 830 *endptr = (char *) str; 831 return EINVAL; 832 } 833 } 834 835 *result = 0; 836 const char *startstr = str; 837 838 while (*str != 0) { 839 unsigned int digit; 840 841 if ((*str >= 'a') && (*str <= 'z')) 842 digit = *str - 'a' + 10; 843 else if ((*str >= 'A') && (*str <= 'Z')) 844 digit = *str - 'A' + 10; 845 else if ((*str >= '0') && (*str <= '9')) 846 digit = *str - '0'; 847 else 848 break; 849 850 if (digit >= base) 851 break; 852 853 uint64_t prev = *result; 854 *result = (*result) * base + digit; 855 856 if (*result < prev) { 857 /* Overflow */ 858 *endptr = (char *) str; 859 return EOVERFLOW; 860 } 861 862 str++; 863 } 864 865 if (str == startstr) { 866 /* 867 * No digits were decoded => first invalid character is 868 * the first character of the string. 869 */ 870 str = nptr; 871 } 872 873 *endptr = (char *) str; 874 875 if (str == nptr) 876 return EINVAL; 877 878 return EOK; 879 } 880 881 /** Convert string to uint64_t. 882 * 883 * @param nptr Pointer to string. 884 * @param endptr If not NULL, pointer to the first invalid character 885 * is stored here. 886 * @param base Zero or number between 2 and 36 inclusive. 887 * @param strict Do not allow any trailing characters. 888 * @apram result Result of the conversion. 889 * 890 * @return EOK if conversion was successful. 891 * 892 */ 893 int str_uint64(const char *nptr, char **endptr, unsigned int base, 894 bool strict, uint64_t *result) 895 { 896 ASSERT(result != NULL); 897 898 bool neg; 899 char *lendptr; 900 int ret = str_uint(nptr, &lendptr, base, &neg, result); 901 902 if (endptr != NULL) 903 *endptr = (char *) lendptr; 904 905 if (ret != EOK) 906 return ret; 907 908 /* Do not allow negative values */ 909 if (neg) 910 return EINVAL; 911 912 /* Check whether we are at the end of 913 the string in strict mode */ 914 if ((strict) && (*lendptr != 0)) 915 return EINVAL; 916 917 return EOK; 918 } 919 762 920 /** @} 763 921 */
Note:
See TracChangeset
for help on using the changeset viewer.