Changeset 42e91ae in mainline for kernel/generic/src/lib/str.c
- Timestamp:
- 2019-05-27T20:39:31Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b401b33
- Parents:
- 1c9bf292
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/str.c
r1c9bf292 r42e91ae 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 else880 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 is900 * 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 character917 * 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 of946 * the string in strict mode947 */948 if ((strict) && (*lendptr != 0))949 return EINVAL;950 951 return EOK;952 791 } 953 792
Note:
See TracChangeset
for help on using the changeset viewer.