int StrFormatScanf()

in lib/nxp/utilities/fsl_str.c [1317:1516]


int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr)
{
    uint8_t base;
    int8_t neg;
    /* Identifier for the format string. */
    char *c = format;
    char *buf;
    /* Flag telling the conversion specification. */
    uint32_t flag = 0;
    /* Filed width for the matching input streams. */
    uint32_t field_width;
    /* How many arguments are assigned except the suppress. */
    uint32_t nassigned = 0;
    /* How many characters are read from the input streams. */
    uint32_t n_decode = 0;

    int32_t val;

    uint8_t added;

    uint8_t exitPending = 0;

    const char *s;
    /* Identifier for the input string. */
    const char *p = line_ptr;

#if SCANF_FLOAT_ENABLE
    double fnum = 0.0;
#endif /* SCANF_FLOAT_ENABLE */
    /* Return EOF error before any conversion. */
    if (*p == '\0')
    {
        return -1;
    }

    /* Decode directives. */
    while (('\0' != (*c)) && ('\0' != (*p)))
    {
        /* Ignore all white-spaces in the format strings. */
        if (0U != ScanIgnoreWhiteSpace((const char **)((void *)&c)))
        {
            n_decode += ScanIgnoreWhiteSpace(&p);
        }
        else if (0U == StrFormatScanIsFormatStarting(c))
        {
            /* Ordinary characters. */
            c++;
            if (*p == *c)
            {
                n_decode++;
                p++;
                c++;
            }
            else
            {
                /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream.
                 * However, it is deserted now. */
                break;
            }
        }
        else
        {
            /* convernsion specification */
            c++;
            /* Reset. */
            flag        = 0;
            field_width = MAX_FIELD_WIDTH;
            base        = 0;
            added       = 0U;

            exitPending = StrFormatScanfStringHandling(&c, &flag, &field_width, &base);

            if (1U == exitPending)
            {
                /* Format strings are exhausted. */
                break;
            }

            /* Matching strings in input streams and assign to argument. */
            if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestChar)
            {
                s   = (const char *)p;
                buf = va_arg(args_ptr, char *);
                while ((0U != (field_width--))
#if SCANF_ADVANCED_ENABLE
                       && ('\0' != (*p))
#endif
                )
                {
#if SCANF_ADVANCED_ENABLE
                    if (flag & kSCANF_Suppress)
                    {
                        p++;
                    }
                    else
#endif
                    {
                        *buf++ = *p++;
#if SCANF_ADVANCED_ENABLE
                        added = 1u;
#endif
                    }
                    n_decode++;
                }

#if SCANF_ADVANCED_ENABLE
                if (1u == added)
#endif
                {
                    nassigned++;
                }
            }
            else if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestString)
            {
                n_decode += ScanIgnoreWhiteSpace(&p);
                s   = p;
                buf = va_arg(args_ptr, char *);
                while ((0U != (field_width--)) && (*p != '\0') && (0U == ScanIsWhiteSpace(*p)))
                {
#if SCANF_ADVANCED_ENABLE
                    if (flag & kSCANF_Suppress)
                    {
                        p++;
                    }
                    else
#endif
                    {
                        *buf++ = *p++;
#if SCANF_ADVANCED_ENABLE
                        added = 1u;
#endif
                    }
                    n_decode++;
                }

#if SCANF_ADVANCED_ENABLE
                if (1u == added)
#endif
                {
                    /* Add NULL to end of string. */
                    *buf = '\0';
                    nassigned++;
                }
            }
            else if ((flag & (uint32_t)kSCANF_DestMask) == (uint32_t)kSCANF_DestInt)
            {
                n_decode += ScanIgnoreWhiteSpace(&p);
                s    = p;
                val  = 0;
                base = StrFormatScanGetBase(base, s);

                added = StrFormatScanCheckSymbol(p, &neg);
                n_decode += added;
                p += added;
                field_width -= added;

                s = p;
                if (strlen(p) > field_width)
                {
                    char temp[12];
                    char *tempEnd;
                    (void)memcpy(temp, p, sizeof(temp) - 1U);
                    temp[sizeof(temp) - 1U] = '\0';
                    val                     = (int32_t)strtoul(temp, &tempEnd, (int)base);
                    p                       = p + (tempEnd - temp);
                }
                else
                {
                    char *tempEnd;
                    val = (int32_t)strtoul(p, &tempEnd, (int)base);
                    p   = tempEnd;
                }
                n_decode += (uint32_t)p - (uint32_t)s;

                val *= neg;

                nassigned += StrFormatScanFillInteger(flag, &args_ptr, val);
            }
#if SCANF_FLOAT_ENABLE
            else if ((flag & kSCANF_DestMask) == kSCANF_DestFloat)
            {
                n_decode += ScanIgnoreWhiteSpace(&p);
                fnum = strtod(p, (char **)&s);

                if ((fnum < HUGE_VAL) && (fnum > -HUGE_VAL))
                {
                    n_decode += (int)(s) - (int)(p);
                    p = s;
                    nassigned += StrFormatScanFillFloat(flag, &args_ptr, fnum);
                }
            }
#endif /* SCANF_FLOAT_ENABLE */
            else
            {
                break;
            }
        }
    }
    return (int)nassigned;
}