13d0407baSopenharmony_ci/* 23d0407baSopenharmony_ci * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved. 33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43d0407baSopenharmony_ci * you may not use this file except in compliance with the License. 53d0407baSopenharmony_ci * You may obtain a copy of the License at 63d0407baSopenharmony_ci * 73d0407baSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83d0407baSopenharmony_ci * 93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123d0407baSopenharmony_ci * See the License for the specific language governing permissions and 133d0407baSopenharmony_ci * limitations under the License. 143d0407baSopenharmony_ci */ 153d0407baSopenharmony_ci#include <sys/stat.h> 163d0407baSopenharmony_ci#include <stdarg.h> 173d0407baSopenharmony_ci#include <stddef.h> 183d0407baSopenharmony_ci#include <stdlib.h> 193d0407baSopenharmony_ci#include <limits.h> 203d0407baSopenharmony_ci#include <stdio.h> 213d0407baSopenharmony_ci#include <ctype.h> 223d0407baSopenharmony_ci 233d0407baSopenharmony_ci#define INDEX_0 0 243d0407baSopenharmony_ci#define INDEX_1 1 253d0407baSopenharmony_ci#define INDEX_2 2 263d0407baSopenharmony_ci#define BASE_8 9 273d0407baSopenharmony_ci#define BASE_2 2 283d0407baSopenharmony_ci#define BASE_0 0 293d0407baSopenharmony_ci#define BASE_10 10 303d0407baSopenharmony_ci#define BASE_16 16 313d0407baSopenharmony_ci#define is_digit(c) ((c) >= '0' && (c) <= '9') 323d0407baSopenharmony_ci#define likely(x) __builtin_expect((x), 1) 333d0407baSopenharmony_ci#define unlikely(x) __builtin_expect((x), 0) 343d0407baSopenharmony_ci#define KSTRTOX_OVERFLOW 0 353d0407baSopenharmony_ci 363d0407baSopenharmony_ci/* Convert a character to lower case */ 373d0407baSopenharmony_ciinline static char tolower_re(char char_c) 383d0407baSopenharmony_ci{ 393d0407baSopenharmony_ci char c = char_c; 403d0407baSopenharmony_ci 413d0407baSopenharmony_ci if ((c >= 'A') && (c <= 'Z')) { 423d0407baSopenharmony_ci c = (c - 'A') + 'a'; 433d0407baSopenharmony_ci } 443d0407baSopenharmony_ci return c; 453d0407baSopenharmony_ci} 463d0407baSopenharmony_ci 473d0407baSopenharmony_ci// div_u64_rem 483d0407baSopenharmony_cistatic inline unsigned long long div_u64_rem(unsigned long long dividend, 493d0407baSopenharmony_ci unsigned int divisor, 503d0407baSopenharmony_ci unsigned int *remainder) 513d0407baSopenharmony_ci{ 523d0407baSopenharmony_ci unsigned long long ret = 0; 533d0407baSopenharmony_ci 543d0407baSopenharmony_ci if (divisor == 0) { 553d0407baSopenharmony_ci return ret; 563d0407baSopenharmony_ci } 573d0407baSopenharmony_ci *remainder = dividend % divisor; 583d0407baSopenharmony_ci return dividend / divisor; 593d0407baSopenharmony_ci} 603d0407baSopenharmony_ci 613d0407baSopenharmony_cistatic inline unsigned long long div_u64(unsigned long long dividend, unsigned int divisor) 623d0407baSopenharmony_ci{ 633d0407baSopenharmony_ci unsigned int remainder; 643d0407baSopenharmony_ci return div_u64_rem(dividend, divisor, &remainder); 653d0407baSopenharmony_ci} 663d0407baSopenharmony_ci 673d0407baSopenharmony_ci// lib/kstrtox.c, line 23 683d0407baSopenharmony_ciconst char *_parse_integer_fixup_radix(const char *str, unsigned int *base) 693d0407baSopenharmony_ci{ 703d0407baSopenharmony_ci const char *s = str; 713d0407baSopenharmony_ci 723d0407baSopenharmony_ci if (*base == BASE_0) { 733d0407baSopenharmony_ci if (s[BASE_0] == '0') { 743d0407baSopenharmony_ci if (tolower_re(s[INDEX_1]) == 'x' && isxdigit(s[INDEX_2])) { 753d0407baSopenharmony_ci *base = BASE_16; 763d0407baSopenharmony_ci } else { 773d0407baSopenharmony_ci *base = BASE_8; 783d0407baSopenharmony_ci } 793d0407baSopenharmony_ci } else { 803d0407baSopenharmony_ci *base = BASE_10; 813d0407baSopenharmony_ci } 823d0407baSopenharmony_ci } 833d0407baSopenharmony_ci if (*base == BASE_16 && s[INDEX_0] == '0' && tolower_re(s[INDEX_1]) == 'x') { 843d0407baSopenharmony_ci s += BASE_2; 853d0407baSopenharmony_ci } 863d0407baSopenharmony_ci return s; 873d0407baSopenharmony_ci} 883d0407baSopenharmony_ci 893d0407baSopenharmony_ciunsigned int _parse_integer(const char *str, unsigned int base, unsigned long long *p) 903d0407baSopenharmony_ci{ 913d0407baSopenharmony_ci unsigned long long res; 923d0407baSopenharmony_ci unsigned int rv; 933d0407baSopenharmony_ci int overflow; 943d0407baSopenharmony_ci const char *s = str; 953d0407baSopenharmony_ci 963d0407baSopenharmony_ci res = 0; 973d0407baSopenharmony_ci rv = 0; 983d0407baSopenharmony_ci overflow = 0; 993d0407baSopenharmony_ci while (*s) { 1003d0407baSopenharmony_ci unsigned int val; 1013d0407baSopenharmony_ci 1023d0407baSopenharmony_ci if (*s >= '0' && *s <= '9') { 1033d0407baSopenharmony_ci val = *s - '0'; 1043d0407baSopenharmony_ci } else if (tolower_re(*s) >= 'a' && tolower_re(*s) <= 'f') { 1053d0407baSopenharmony_ci val = tolower_re(*s) - 'a' + BASE_10; 1063d0407baSopenharmony_ci } else { 1073d0407baSopenharmony_ci break; 1083d0407baSopenharmony_ci } 1093d0407baSopenharmony_ci if (val >= base) { 1103d0407baSopenharmony_ci break; 1113d0407baSopenharmony_ci } 1123d0407baSopenharmony_ci /* 1133d0407baSopenharmony_ci * Check for overflow only if we are within range of 1143d0407baSopenharmony_ci * it in the max base we support (16) 1153d0407baSopenharmony_ci */ 1163d0407baSopenharmony_ci if (unlikely(res & (~0ull << 60))) { 1173d0407baSopenharmony_ci if (res > div_u64(ULLONG_MAX - val, base)) { 1183d0407baSopenharmony_ci overflow = 1; 1193d0407baSopenharmony_ci } 1203d0407baSopenharmony_ci } 1213d0407baSopenharmony_ci res = res * base + val; 1223d0407baSopenharmony_ci rv++; 1233d0407baSopenharmony_ci s++; 1243d0407baSopenharmony_ci } 1253d0407baSopenharmony_ci *p = res; 1263d0407baSopenharmony_ci if (overflow) { 1273d0407baSopenharmony_ci rv |= KSTRTOX_OVERFLOW; 1283d0407baSopenharmony_ci } 1293d0407baSopenharmony_ci return rv; 1303d0407baSopenharmony_ci} 1313d0407baSopenharmony_ci 1323d0407baSopenharmony_ciint isspace_re(int x) 1333d0407baSopenharmony_ci{ 1343d0407baSopenharmony_ci if (x == ' ' || x == '/t' || x == '/n' || x == '/f' || x == '/b' || x == '/r') { 1353d0407baSopenharmony_ci return 1; 1363d0407baSopenharmony_ci } else { 1373d0407baSopenharmony_ci return 0; 1383d0407baSopenharmony_ci } 1393d0407baSopenharmony_ci} 1403d0407baSopenharmony_ci 1413d0407baSopenharmony_cichar* skip_spaces(const char * str) 1423d0407baSopenharmony_ci{ 1433d0407baSopenharmony_ci const char* str_temp = str; 1443d0407baSopenharmony_ci 1453d0407baSopenharmony_ci while (isspace_re(*str_temp)) { 1463d0407baSopenharmony_ci ++str_temp; 1473d0407baSopenharmony_ci } 1483d0407baSopenharmony_ci return (char *)str_temp; 1493d0407baSopenharmony_ci} 1503d0407baSopenharmony_ci 1513d0407baSopenharmony_ci// simple_strtoull - convert a string to an unsigned long long 1523d0407baSopenharmony_ciunsigned long long simple_strtoull(const char *cp_temp, char **endp, unsigned int base) 1533d0407baSopenharmony_ci{ 1543d0407baSopenharmony_ci unsigned long long result; 1553d0407baSopenharmony_ci unsigned int rv; 1563d0407baSopenharmony_ci const char *cp = cp_temp; 1573d0407baSopenharmony_ci 1583d0407baSopenharmony_ci cp = _parse_integer_fixup_radix(cp, &base); 1593d0407baSopenharmony_ci rv = _parse_integer(cp, base, &result); 1603d0407baSopenharmony_ci 1613d0407baSopenharmony_ci cp += (rv & ~KSTRTOX_OVERFLOW); 1623d0407baSopenharmony_ci 1633d0407baSopenharmony_ci if (endp) { 1643d0407baSopenharmony_ci *endp = (char *)cp; 1653d0407baSopenharmony_ci } 1663d0407baSopenharmony_ci return result; 1673d0407baSopenharmony_ci} 1683d0407baSopenharmony_ci 1693d0407baSopenharmony_cistatic int skip_atoi(const char **s) 1703d0407baSopenharmony_ci{ 1713d0407baSopenharmony_ci int i = 0; 1723d0407baSopenharmony_ci while (is_digit(**s)) { 1733d0407baSopenharmony_ci i = i * BASE_10 + *((*s)++) - '0'; 1743d0407baSopenharmony_ci } 1753d0407baSopenharmony_ci return i; 1763d0407baSopenharmony_ci} 1773d0407baSopenharmony_ci 1783d0407baSopenharmony_ciunsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) 1793d0407baSopenharmony_ci{ 1803d0407baSopenharmony_ci return simple_strtoull(cp, endp, base); 1813d0407baSopenharmony_ci} 1823d0407baSopenharmony_ci 1833d0407baSopenharmony_ci/** 1843d0407baSopenharmony_ci* simple_strtoll - convert a string to a signed long long 1853d0407baSopenharmony_ci* @cp: The start of the string 1863d0407baSopenharmony_ci* @endp: A pointer to the end of the parsed string will be placed here 1873d0407baSopenharmony_ci* @base: The number base to use 1883d0407baSopenharmony_ci*/ 1893d0407baSopenharmony_cilong long simple_strtoll(const char *cp, char **endp, unsigned int base) 1903d0407baSopenharmony_ci{ 1913d0407baSopenharmony_ci if (*cp == '-') { 1923d0407baSopenharmony_ci return -simple_strtoull(cp + 1, endp, base); 1933d0407baSopenharmony_ci } 1943d0407baSopenharmony_ci return simple_strtoull(cp, endp, base); 1953d0407baSopenharmony_ci} 1963d0407baSopenharmony_ci 1973d0407baSopenharmony_cilong simple_strtol(const char *cp, char **endp, unsigned int base) 1983d0407baSopenharmony_ci{ 1993d0407baSopenharmony_ci if (*cp == '-') { 2003d0407baSopenharmony_ci return -simple_strtoul(cp + 1, endp, base); 2013d0407baSopenharmony_ci } 2023d0407baSopenharmony_ci return simple_strtoul(cp, endp, base); 2033d0407baSopenharmony_ci} 2043d0407baSopenharmony_ci 2053d0407baSopenharmony_ci/** 2063d0407baSopenharmony_ci* vsscanf - Unformat a buffer into a list of arguments 2073d0407baSopenharmony_ci* @buf: input buffer 2083d0407baSopenharmony_ci* @fmt: format of buffer 2093d0407baSopenharmony_ci* @args: arguments 2103d0407baSopenharmony_ci*/ 2113d0407baSopenharmony_ciint pre_vsscanf(const char *__restrict __s, const char *__restrict __format, va_list arg) 2123d0407baSopenharmony_ci{ 2133d0407baSopenharmony_ci const char *str = __s; 2143d0407baSopenharmony_ci char *next; 2153d0407baSopenharmony_ci char digit; 2163d0407baSopenharmony_ci int num = 0; 2173d0407baSopenharmony_ci unsigned char qualifier; 2183d0407baSopenharmony_ci unsigned char base; 2193d0407baSopenharmony_ci short field_width; 2203d0407baSopenharmony_ci char is_sign; 2213d0407baSopenharmony_ci const char *fmt = __format; 2223d0407baSopenharmony_ci 2233d0407baSopenharmony_ci while (*fmt && *str) { 2243d0407baSopenharmony_ci /* skip any white space in format */ 2253d0407baSopenharmony_ci /* white space in format matchs any amount of 2263d0407baSopenharmony_ci * white space, including none, in the input. 2273d0407baSopenharmony_ci */ 2283d0407baSopenharmony_ci if (isspace_re(*fmt)) { 2293d0407baSopenharmony_ci ++fmt; 2303d0407baSopenharmony_ci fmt = skip_spaces(fmt); 2313d0407baSopenharmony_ci str = skip_spaces(str); 2323d0407baSopenharmony_ci } 2333d0407baSopenharmony_ci 2343d0407baSopenharmony_ci /* anything that is not a conversion must match exactly */ 2353d0407baSopenharmony_ci if (*fmt != '%' && *fmt) { 2363d0407baSopenharmony_ci if (*fmt++ != *str++) { 2373d0407baSopenharmony_ci break; 2383d0407baSopenharmony_ci } 2393d0407baSopenharmony_ci continue; 2403d0407baSopenharmony_ci } 2413d0407baSopenharmony_ci 2423d0407baSopenharmony_ci if (!*fmt) { 2433d0407baSopenharmony_ci break; 2443d0407baSopenharmony_ci } 2453d0407baSopenharmony_ci ++fmt; 2463d0407baSopenharmony_ci 2473d0407baSopenharmony_ci /* skip this conversion. 2483d0407baSopenharmony_ci * advance both strings to next white space 2493d0407baSopenharmony_ci */ 2503d0407baSopenharmony_ci if (*fmt == '*') { 2513d0407baSopenharmony_ci while (!isspace_re(*fmt) && *fmt != '%' && *fmt) { 2523d0407baSopenharmony_ci fmt++; 2533d0407baSopenharmony_ci } 2543d0407baSopenharmony_ci while (!isspace_re(*str) && *str) { 2553d0407baSopenharmony_ci str++; 2563d0407baSopenharmony_ci } 2573d0407baSopenharmony_ci continue; 2583d0407baSopenharmony_ci } 2593d0407baSopenharmony_ci 2603d0407baSopenharmony_ci /* get field width */ 2613d0407baSopenharmony_ci field_width = -1; 2623d0407baSopenharmony_ci if (is_digit(*fmt)) { 2633d0407baSopenharmony_ci field_width = skip_atoi(&fmt); 2643d0407baSopenharmony_ci } 2653d0407baSopenharmony_ci 2663d0407baSopenharmony_ci /* get conversion qualifier */ 2673d0407baSopenharmony_ci qualifier = -1; 2683d0407baSopenharmony_ci if (*fmt == 'h' || tolower_re(*fmt) == 'l' || 2693d0407baSopenharmony_ci tolower_re(*fmt) == 'z') { 2703d0407baSopenharmony_ci qualifier = *fmt++; 2713d0407baSopenharmony_ci if (likely(qualifier == *fmt)) { 2723d0407baSopenharmony_ci break; 2733d0407baSopenharmony_ci } 2743d0407baSopenharmony_ci if (qualifier == 'h') { 2753d0407baSopenharmony_ci qualifier = 'H'; 2763d0407baSopenharmony_ci fmt++; 2773d0407baSopenharmony_ci } else if (qualifier == 'l') { 2783d0407baSopenharmony_ci qualifier = 'L'; 2793d0407baSopenharmony_ci fmt++; 2803d0407baSopenharmony_ci } 2813d0407baSopenharmony_ci } 2823d0407baSopenharmony_ci 2833d0407baSopenharmony_ci if (!*fmt || !*str) { 2843d0407baSopenharmony_ci break; 2853d0407baSopenharmony_ci } 2863d0407baSopenharmony_ci 2873d0407baSopenharmony_ci base = BASE_10; 2883d0407baSopenharmony_ci is_sign = 0; 2893d0407baSopenharmony_ci 2903d0407baSopenharmony_ci switch (*fmt++) { 2913d0407baSopenharmony_ci case 'c': 2923d0407baSopenharmony_ci { 2933d0407baSopenharmony_ci char *s = (char *)va_arg(arg, char *); 2943d0407baSopenharmony_ci if (field_width == -1) { 2953d0407baSopenharmony_ci field_width = 1; 2963d0407baSopenharmony_ci } 2973d0407baSopenharmony_ci do { 2983d0407baSopenharmony_ci *s++ = *str++; 2993d0407baSopenharmony_ci } while (--field_width > 0 && *str); 3003d0407baSopenharmony_ci num++; 3013d0407baSopenharmony_ci } 3023d0407baSopenharmony_ci continue; 3033d0407baSopenharmony_ci case 's': 3043d0407baSopenharmony_ci { 3053d0407baSopenharmony_ci char *s = (char *)va_arg(arg, char *); 3063d0407baSopenharmony_ci if (field_width == -1) { 3073d0407baSopenharmony_ci field_width = SHRT_MAX; 3083d0407baSopenharmony_ci } 3093d0407baSopenharmony_ci /* first, skip leading white space in buffer */ 3103d0407baSopenharmony_ci str = skip_spaces(str); 3113d0407baSopenharmony_ci 3123d0407baSopenharmony_ci /* now copy until next white space */ 3133d0407baSopenharmony_ci while (*str && !isspace_re(*str) && field_width--) { 3143d0407baSopenharmony_ci *s++ = *str++; 3153d0407baSopenharmony_ci } 3163d0407baSopenharmony_ci *s = '\0'; 3173d0407baSopenharmony_ci num++; 3183d0407baSopenharmony_ci } 3193d0407baSopenharmony_ci continue; 3203d0407baSopenharmony_ci case 'n': 3213d0407baSopenharmony_ci /* return number of characters read so far */ 3223d0407baSopenharmony_ci { 3233d0407baSopenharmony_ci int *i = (int *)va_arg(arg, int *); 3243d0407baSopenharmony_ci *i = str - __s; 3253d0407baSopenharmony_ci } 3263d0407baSopenharmony_ci continue; 3273d0407baSopenharmony_ci case 'o': 3283d0407baSopenharmony_ci base = BASE_8; 3293d0407baSopenharmony_ci break; 3303d0407baSopenharmony_ci case 'x': 3313d0407baSopenharmony_ci case 'X': 3323d0407baSopenharmony_ci base = BASE_16; 3333d0407baSopenharmony_ci break; 3343d0407baSopenharmony_ci case 'i': 3353d0407baSopenharmony_ci base = 0; 3363d0407baSopenharmony_ci case 'd': 3373d0407baSopenharmony_ci is_sign = 1; 3383d0407baSopenharmony_ci case 'u': 3393d0407baSopenharmony_ci break; 3403d0407baSopenharmony_ci case '%': 3413d0407baSopenharmony_ci /* looking for '%' in str */ 3423d0407baSopenharmony_ci if (*str++ != '%') { 3433d0407baSopenharmony_ci return num; 3443d0407baSopenharmony_ci } 3453d0407baSopenharmony_ci continue; 3463d0407baSopenharmony_ci default: 3473d0407baSopenharmony_ci /* invalid format; stop here */ 3483d0407baSopenharmony_ci return num; 3493d0407baSopenharmony_ci } 3503d0407baSopenharmony_ci 3513d0407baSopenharmony_ci /* have some sort of integer conversion. 3523d0407baSopenharmony_ci * first, skip white space in buffer. 3533d0407baSopenharmony_ci */ 3543d0407baSopenharmony_ci str = skip_spaces(str); 3553d0407baSopenharmony_ci 3563d0407baSopenharmony_ci digit = *str; 3573d0407baSopenharmony_ci if (is_sign && digit == '-') { 3583d0407baSopenharmony_ci digit = *(str + 1); 3593d0407baSopenharmony_ci } 3603d0407baSopenharmony_ci if (!digit 3613d0407baSopenharmony_ci || (base == BASE_16 && !isxdigit(digit)) 3623d0407baSopenharmony_ci || (base == BASE_10 && !isdigit(digit)) 3633d0407baSopenharmony_ci || (base == BASE_8 && (!isdigit(digit) || digit > '7')) 3643d0407baSopenharmony_ci || (base == BASE_0 && !isdigit(digit))) { 3653d0407baSopenharmony_ci break; 3663d0407baSopenharmony_ci } 3673d0407baSopenharmony_ci switch (qualifier) { 3683d0407baSopenharmony_ci case 'H': /* that's 'hh' in format */ 3693d0407baSopenharmony_ci if (is_sign) { 3703d0407baSopenharmony_ci signed char *s = (signed char *)va_arg(arg, signed char *); 3713d0407baSopenharmony_ci *s = (signed char)simple_strtol(str, &next, base); 3723d0407baSopenharmony_ci } else { 3733d0407baSopenharmony_ci unsigned char *s = (unsigned char *)va_arg(arg, unsigned char *); 3743d0407baSopenharmony_ci *s = (unsigned char)simple_strtoul(str, &next, base); 3753d0407baSopenharmony_ci } 3763d0407baSopenharmony_ci break; 3773d0407baSopenharmony_ci case 'h': 3783d0407baSopenharmony_ci if (is_sign) { 3793d0407baSopenharmony_ci short *s = (short *)va_arg(arg, short *); 3803d0407baSopenharmony_ci *s = (short)simple_strtol(str, &next, base); 3813d0407baSopenharmony_ci } else { 3823d0407baSopenharmony_ci unsigned short *s = (unsigned short *)va_arg(arg, unsigned short *); 3833d0407baSopenharmony_ci *s = (unsigned short)simple_strtoul(str, &next, base); 3843d0407baSopenharmony_ci } 3853d0407baSopenharmony_ci break; 3863d0407baSopenharmony_ci case 'l': 3873d0407baSopenharmony_ci if (is_sign) { 3883d0407baSopenharmony_ci long *l = (long *)va_arg(arg, long *); 3893d0407baSopenharmony_ci *l = simple_strtol(str, &next, base); 3903d0407baSopenharmony_ci } else { 3913d0407baSopenharmony_ci unsigned long *l = (unsigned long *)va_arg(arg, unsigned long *); 3923d0407baSopenharmony_ci *l = simple_strtoul(str, &next, base); 3933d0407baSopenharmony_ci } 3943d0407baSopenharmony_ci break; 3953d0407baSopenharmony_ci case 'L': 3963d0407baSopenharmony_ci if (is_sign) { 3973d0407baSopenharmony_ci long long *l = (long long *)va_arg(arg, long long *); 3983d0407baSopenharmony_ci *l = simple_strtoll(str, &next, base); 3993d0407baSopenharmony_ci } else { 4003d0407baSopenharmony_ci unsigned long long *l = (unsigned long long *)va_arg(arg, unsigned long long *); 4013d0407baSopenharmony_ci *l = simple_strtoull(str, &next, base); 4023d0407baSopenharmony_ci } 4033d0407baSopenharmony_ci break; 4043d0407baSopenharmony_ci case 'Z': 4053d0407baSopenharmony_ci case 'z': 4063d0407baSopenharmony_ci { 4073d0407baSopenharmony_ci size_t *s = (size_t *)va_arg(arg, size_t *); 4083d0407baSopenharmony_ci *s = (size_t)simple_strtoul(str, &next, base); 4093d0407baSopenharmony_ci } 4103d0407baSopenharmony_ci break; 4113d0407baSopenharmony_ci default: 4123d0407baSopenharmony_ci if (is_sign) { 4133d0407baSopenharmony_ci int *i = (int *)va_arg(arg, int *); 4143d0407baSopenharmony_ci *i = (int)simple_strtol(str, &next, base); 4153d0407baSopenharmony_ci } else { 4163d0407baSopenharmony_ci unsigned int *i = (unsigned int *)va_arg(arg, unsigned int*); 4173d0407baSopenharmony_ci *i = (unsigned int)simple_strtoul(str, &next, base); 4183d0407baSopenharmony_ci } 4193d0407baSopenharmony_ci break; 4203d0407baSopenharmony_ci } 4213d0407baSopenharmony_ci num++; 4223d0407baSopenharmony_ci 4233d0407baSopenharmony_ci if (!next) { 4243d0407baSopenharmony_ci break; 4253d0407baSopenharmony_ci } 4263d0407baSopenharmony_ci str = next; 4273d0407baSopenharmony_ci } 4283d0407baSopenharmony_ci 4293d0407baSopenharmony_ci /* 4303d0407baSopenharmony_ci * Now we've come all the way through so either the input string or the 4313d0407baSopenharmony_ci * format ended. In the former case, there can be a %n at the current 4323d0407baSopenharmony_ci * position in the format that needs to be filled. 4333d0407baSopenharmony_ci */ 4343d0407baSopenharmony_ci if (*fmt == '%' && *(fmt + 1) == 'n') { 4353d0407baSopenharmony_ci int *p = (int *)va_arg(arg, int *); 4363d0407baSopenharmony_ci *p = str - __s; 4373d0407baSopenharmony_ci } 4383d0407baSopenharmony_ci 4393d0407baSopenharmony_ci return num; 4403d0407baSopenharmony_ci} 4413d0407baSopenharmony_ci/** 4423d0407baSopenharmony_ci* sscanf - Unformat a buffer into a list of arguments 4433d0407baSopenharmony_ci* @__s: input buffer 4443d0407baSopenharmony_ci* @__format: formatting of buffer 4453d0407baSopenharmony_ci* @...: resulting arguments 4463d0407baSopenharmony_ci*/ 4473d0407baSopenharmony_ciint sscanf(const char *__restrict __s, const char *__restrict __format, ...) 4483d0407baSopenharmony_ci{ 4493d0407baSopenharmony_ci va_list args; 4503d0407baSopenharmony_ci int i; 4513d0407baSopenharmony_ci 4523d0407baSopenharmony_ci va_start(args, __format); 4533d0407baSopenharmony_ci i = pre_vsscanf(__s, __format, args); 4543d0407baSopenharmony_ci va_end(args); 4553d0407baSopenharmony_ci 4563d0407baSopenharmony_ci return i; 4573d0407baSopenharmony_ci}