int StrFormatPrintf()

in lib/nxp/utilities/fsl_str.c [737:974]


int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb)
{
    /* va_list ap; */
    const char *p;
    char c;

    char vstr[33];
    char *vstrp  = NULL;
    int32_t vlen = 0;

    int32_t count = 0;

    uint32_t field_width;
    uint32_t precision_width;
    char *sval;
    int32_t cval;
    bool use_caps;
    uint8_t radix = 0;

#if PRINTF_ADVANCED_ENABLE
    uint32_t flags_used;
    char schar;
    int64_t ival;
    uint64_t uval = 0;
    bool valid_precision_width;
#else
    int32_t ival;
    uint32_t uval = 0;
#endif /* PRINTF_ADVANCED_ENABLE */

#if PRINTF_FLOAT_ENABLE
    double fval;
#endif /* PRINTF_FLOAT_ENABLE */

    /* Start parsing apart the format string and display appropriate formats and data. */
    p = fmt;
    while (true)
    {
        if ('\0' == *p)
        {
            break;
        }
        c = *p;
        /*
         * All formats begin with a '%' marker.  Special chars like
         * '\n' or '\t' are normally converted to the appropriate
         * character by the __compiler__.  Thus, no need for this
         * routine to account for the '\' character.
         */
        if (c != '%')
        {
            cb(buf, &count, c, 1);
            p++;
            /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */
            continue;
        }

        use_caps = true;

#if PRINTF_ADVANCED_ENABLE
        /* First check for specification modifier flags. */
        flags_used = PrintCheckFlags(&p);
#endif /* PRINTF_ADVANCED_ENABLE */

        /* Next check for minimum field width. */
        field_width = PrintGetWidth(&p, &ap);

        /* Next check for the width and precision field separator. */
#if PRINTF_ADVANCED_ENABLE
        precision_width = PrintGetPrecision(&p, &ap, &valid_precision_width);
#else
        precision_width = PrintGetPrecision(&p, &ap, NULL);
        (void)precision_width;
#endif

#if PRINTF_ADVANCED_ENABLE
        /* Check for the length modifier. */
        flags_used |= PrintGetLengthFlag(&p);
#endif /* PRINTF_ADVANCED_ENABLE */

        /* Now we're ready to examine the format. */
        c = *++p;
        {
            if (1U == PrintIsdi(c))
            {
#if PRINTF_ADVANCED_ENABLE
                if (flags_used & kPRINTF_LengthLongLongInt)
                {
                    ival = (int64_t)va_arg(ap, int64_t);
                }
                else
#endif /* PRINTF_ADVANCED_ENABLE */
                {
                    ival = (int32_t)va_arg(ap, int32_t);
                }
                vlen  = ConvertRadixNumToString(vstr, (void *)&ival, 1, 10, use_caps);
                vstrp = &vstr[vlen];
#if PRINTF_ADVANCED_ENABLE
                vlen += PrintGetSignChar(ival, flags_used, &schar);
                PrintOutputdifFobpu(flags_used, field_width, vlen, schar, vstrp, cb, buf, &count);
#else
                PrintOutputdifFobpu(0U, field_width, (uint32_t)vlen, '\0', vstrp, cb, buf, &count);
#endif
            }
            else if (1U == PrintIsfF(c))
            {
#if PRINTF_FLOAT_ENABLE
                fval  = (double)va_arg(ap, double);
                vlen  = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width);
                vstrp = &vstr[vlen];

#if PRINTF_ADVANCED_ENABLE
                vlen += PrintGetSignChar((int32_t)fval, flags_used, &schar);
                PrintOutputdifFobpu(flags_used, field_width, vlen, schar, vstrp, cb, buf, &count);
#else
                PrintOutputdifFobpu(0, field_width, vlen, '\0', vstrp, cb, buf, &count);
#endif

#else
                (void)va_arg(ap, double);
#endif /* PRINTF_FLOAT_ENABLE */
            }
            else if (1U == PrintIsxX(c))
            {
                if (c == 'x')
                {
                    use_caps = false;
                }
#if PRINTF_ADVANCED_ENABLE
                if (flags_used & kPRINTF_LengthLongLongInt)
                {
                    uval = (uint64_t)va_arg(ap, uint64_t);
                }
                else
#endif /* PRINTF_ADVANCED_ENABLE */
                {
                    uval = (uint32_t)va_arg(ap, uint32_t);
                }
                vlen  = ConvertRadixNumToString(vstr, &uval, 0, 16, use_caps);
                vstrp = &vstr[vlen];
#if PRINTF_ADVANCED_ENABLE
                PrintOutputxX(flags_used, field_width, vlen, use_caps, vstrp, cb, buf, &count);
#else
                PrintOutputxX(0U, field_width, (uint32_t)vlen, use_caps, vstrp, cb, buf, &count);
#endif
            }
            else if (1U == PrintIsobpu(c))
            {
#if PRINTF_ADVANCED_ENABLE
                if (flags_used & kPRINTF_LengthLongLongInt)
                {
                    uval = (uint64_t)va_arg(ap, uint64_t);
                }
                else
#endif /* PRINTF_ADVANCED_ENABLE */
                {
                    uval = (uint32_t)va_arg(ap, uint32_t);
                }

                radix = PrintGetRadixFromobpu(c);

                vlen  = ConvertRadixNumToString(vstr, &uval, 0, (int32_t)radix, use_caps);
                vstrp = &vstr[vlen];
#if PRINTF_ADVANCED_ENABLE
                PrintOutputdifFobpu(flags_used, field_width, vlen, '\0', vstrp, cb, buf, &count);
#else
                PrintOutputdifFobpu(0U, field_width, (uint32_t)vlen, '\0', vstrp, cb, buf, &count);
#endif
            }
            else if (c == 'c')
            {
                cval = (int32_t)va_arg(ap, uint32_t);
                cb(buf, &count, cval, 1);
            }
            else if (c == 's')
            {
                sval = (char *)va_arg(ap, char *);
                if (NULL != sval)
                {
#if PRINTF_ADVANCED_ENABLE
                    if (valid_precision_width)
                    {
                        vlen = precision_width;
                    }
                    else
                    {
                        vlen = strlen(sval);
                    }
#else
                    vlen = (int32_t)strlen(sval);
#endif /* PRINTF_ADVANCED_ENABLE */
#if PRINTF_ADVANCED_ENABLE
                    if (!(flags_used & kPRINTF_Minus))
#endif /* PRINTF_ADVANCED_ENABLE */
                    {
                        cb(buf, &count, ' ', (int)field_width - (int)vlen);
                    }

#if PRINTF_ADVANCED_ENABLE
                    if (valid_precision_width)
                    {
                        while ((*sval) && (vlen > 0))
                        {
                            cb(buf, &count, *sval++, 1);
                            vlen--;
                        }
                        /* In case that vlen sval is shorter than vlen */
                        vlen = precision_width - vlen;
                    }
                    else
                    {
#endif /* PRINTF_ADVANCED_ENABLE */
                        while ('\0' != (*sval))
                        {
                            cb(buf, &count, *sval++, 1);
                        }
#if PRINTF_ADVANCED_ENABLE
                    }
#endif /* PRINTF_ADVANCED_ENABLE */

#if PRINTF_ADVANCED_ENABLE
                    if (flags_used & kPRINTF_Minus)
                    {
                        cb(buf, &count, ' ', field_width - vlen);
                    }
#endif /* PRINTF_ADVANCED_ENABLE */
                }
            }
            else
            {
                cb(buf, &count, c, 1);
            }
        }
        p++;
    }

    return count;
}