@@ -276,12 +276,141 @@ static char *print_number(char *buf,
276276 return buf ;
277277}
278278
279- #if (defined(__GNUC__ ) && !defined(__ARMCC_VERSION ) /* GCC */ ) && (__GNUC__ >= 7 )
280- /* Disable "-Wimplicit-fallthrough" below GNUC V7 */
279+ #ifdef RT_USING_F_KPRINTF
280+ #define SZB_OUTPUT 32
281+ #define XF_DPC '.' /* Decimal separator for floating point */
282+ #ifndef isinf
283+ #define isinf (d ) (isnan((d - d)) && !isnan(d))
284+ #endif
285+ #ifndef isnan
286+ #define isnan (d ) (d != d)
287+ #endif
288+ // #include <math.h>
289+ static int ilog10 (double n ) /* Calculate log10(n) in integer output */
290+ {
291+ int rv = 0 ;
292+
293+ while (n >= 10 ) { /* Decimate digit in right shift */
294+ if (n >= 100000 ) {
295+ n /= 100000 ; rv += 5 ;
296+ } else {
297+ n /= 10 ; rv ++ ;
298+ }
299+ }
300+ while (n < 1 ) { /* Decimate digit in left shift */
301+ if (n < 0.00001 ) {
302+ n *= 100000 ; rv -= 5 ;
303+ } else {
304+ n *= 10 ; rv -- ;
305+ }
306+ }
307+ return rv ;
308+ }
309+
310+ static double i10x (int n ) /* Calculate 10^n */
311+ {
312+ double rv = 1 ;
313+
314+ while (n > 0 ) { /* Left shift */
315+ if (n >= 5 ) {
316+ rv *= 100000 ; n -= 5 ;
317+ } else {
318+ rv *= 10 ; n -- ;
319+ }
320+ }
321+ while (n < 0 ) { /* Right shift */
322+ if (n <= -5 ) {
323+ rv /= 100000 ; n += 5 ;
324+ } else {
325+ rv /= 10 ; n ++ ;
326+ }
327+ }
328+ return rv ;
329+ }
330+ static void ftoa (
331+ char * buf , /* Buffer to output the generated string */
332+ double val , /* Real number to output */
333+ int prec , /* Number of fractinal digits */
334+ char fmt /* Notation */
335+ )
336+ {
337+ int d ;
338+ int e = 0 , m = 0 ;
339+ char sign = 0 ;
340+ double w ;
341+ const char * er = 0 ;
342+
343+
344+ if (isnan (val )) { /* Not a number? */
345+ er = "NaN" ;
346+ } else {
347+ if (prec < 0 ) prec = 6 ; /* Default precision (6 fractional digits) */
348+ if (val < 0 ) { /* Nagative value? */
349+ val = - val ; sign = '-' ;
350+ } else {
351+ sign = '+' ;
352+ }
353+ if (isinf (val )) { /* Infinite? */
354+ er = "INF" ;
355+ } else {
356+ if (fmt == 'f' ) { /* Decimal notation? */
357+ val += i10x (- prec ) / 2 ; /* Round (nearest) */
358+ m = ilog10 (val );
359+ if (m < 0 ) m = 0 ;
360+ if (m + prec + 3 >= SZB_OUTPUT ) er = "OV" ; /* Buffer overflow? */
361+ } else { /* E notation */
362+ if (val != 0 ) { /* Not a true zero? */
363+ val += i10x (ilog10 (val ) - prec ) / 2 ; /* Round (nearest) */
364+ e = ilog10 (val );
365+ if (e > 99 || prec + 6 >= SZB_OUTPUT ) { /* Buffer overflow or E > +99? */
366+ er = "OV" ;
367+ } else {
368+ if (e < -99 ) e = -99 ;
369+ val /= i10x (e ); /* Normalize */
370+ }
371+ }
372+ }
373+ }
374+ if (!er ) { /* Not error condition */
375+ if (sign == '-' ) * buf ++ = sign ; /* Add a - if negative value */
376+ do { /* Put decimal number */
377+ w = i10x (m ); /* Snip the highest digit d */
378+ d = val / w ; val -= d * w ;
379+ if (m == -1 ) * buf ++ = XF_DPC ; /* Insert a decimal separarot if get into fractional part */
380+ * buf ++ = '0' + d ; /* Put the digit */
381+ } while (-- m >= - prec ); /* Output all digits specified by prec */
382+ if (fmt != 'f' ) { /* Put exponent if needed */
383+ * buf ++ = fmt ;
384+ if (e < 0 ) {
385+ e = - e ; * buf ++ = '-' ;
386+ } else {
387+ * buf ++ = '+' ;
388+ }
389+ * buf ++ = '0' + e / 10 ;
390+ * buf ++ = '0' + e % 10 ;
391+ }
392+ }
393+ }
394+ if (er ) { /* Error condition? */
395+ if (sign ) * buf ++ = sign ; /* Add sign if needed */
396+ do * buf ++ = * er ++ ; while (* er ); /* Put error symbol */
397+ }
398+ * buf = 0 ; /* Term */
399+ }
400+
401+ char * print_float (double value )
402+ {
403+ static char buff [26 ] = {0 };
404+ ftoa (buff , value , 6 , 'f' );
405+ return buff ;
406+ }
407+ #endif
408+
409+ #if defined(__GNUC__ ) && !defined(__ARMCC_VERSION ) /* GCC */
281410#pragma GCC diagnostic push
282411/* ignore warning: this statement may fall through */
283412#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
284- #endif /* ( defined(__GNUC__) && !defined(__ARMCC_VERSION)) && (__GNUC__ >= 7 */
413+ #endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */
285414/**
286415 * @brief This function will fill a formatted string to buffer.
287416 *
@@ -295,13 +424,13 @@ static char *print_number(char *buf,
295424 *
296425 * @return The number of characters actually written to buffer.
297426 */
298- int rt_vsnprintf (char * buf , rt_size_t size , const char * fmt , va_list args )
427+ rt_weak int rt_vsnprintf (char * buf , rt_size_t size , const char * fmt , va_list args )
299428{
300- #ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG
429+ #ifdef RT_KPRINTF_USING_LONGLONG
301430 unsigned long long num = 0 ;
302431#else
303432 unsigned long num = 0 ;
304- #endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */
433+ #endif /* RT_KPRINTF_USING_LONGLONG */
305434 int i = 0 , len = 0 ;
306435 char * str = RT_NULL , * end = RT_NULL , c = 0 ;
307436 const char * s = RT_NULL ;
@@ -392,20 +521,20 @@ int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
392521 qualifier = 0 ; /* get the conversion qualifier */
393522
394523 if (* fmt == 'h' || * fmt == 'l' ||
395- #ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG
524+ #ifdef RT_KPRINTF_USING_LONGLONG
396525 * fmt == 'L' ||
397- #endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */
526+ #endif /* RT_KPRINTF_USING_LONGLONG */
398527 * fmt == 'z' )
399528 {
400529 qualifier = * fmt ;
401530 ++ fmt ;
402- #ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG
531+ #ifdef RT_KPRINTF_USING_LONGLONG
403532 if (qualifier == 'l' && * fmt == 'l' )
404533 {
405534 qualifier = 'L' ;
406535 ++ fmt ;
407536 }
408- #endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */
537+ #endif /* RT_KPRINTF_USING_LONGLONG */
409538 if (qualifier == 'h' && * fmt == 'h' )
410539 {
411540 qualifier = 'H' ;
@@ -448,7 +577,7 @@ int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
448577 s = va_arg (args , char * );
449578 if (!s )
450579 {
451- s = "(null )" ;
580+ s = "(NULL )" ;
452581 }
453582
454583 for (len = 0 ; (len != field_width ) && (s [len ] != '\0' ); len ++ );
@@ -527,7 +656,46 @@ int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
527656 case 'g' :
528657 case 'f' :
529658 case 'F' :
659+ #ifndef RT_USING_F_KPRINTF
530660 va_arg (args , double );
661+ #else
662+ s = print_float (va_arg (args , double ));
663+ field_width = rt_strlen (s );
664+ if (!s )
665+ {
666+ s = "(NULL)" ;
667+ }
668+
669+ for (len = 0 ; (len != field_width ) && (s [len ] != '\0' ); len ++ );
670+
671+ if (precision > 0 && len > precision )
672+ {
673+ len = precision ;
674+ }
675+
676+ if (!(flags & LEFT ))
677+ {
678+ while (len < field_width -- )
679+ {
680+ if (str < end ) * str = ' ' ;
681+ ++ str ;
682+ }
683+ }
684+
685+ for (i = 0 ; i < len ; ++ i )
686+ {
687+ if (str < end ) * str = * s ;
688+ ++ str ;
689+ ++ s ;
690+ }
691+
692+ while (len < field_width -- )
693+ {
694+ if (str < end ) * str = ' ' ;
695+ ++ str ;
696+ }
697+ continue ;
698+ #endif
531699 default :
532700 if (str < end )
533701 {
@@ -606,6 +774,7 @@ int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
606774 */
607775 return str - buf ;
608776}
609- #if (defined(__GNUC__ ) && !defined(__ARMCC_VERSION ) /* GCC */ ) && (__GNUC__ >= 7 )
777+ RTM_EXPORT (rt_vsnprintf );
778+ #if defined(__GNUC__ ) && !defined(__ARMCC_VERSION ) /* GCC */
610779#pragma GCC diagnostic pop /* ignored "-Wimplicit-fallthrough" */
611- #endif /* ( defined(__GNUC__) && !defined(__ARMCC_VERSION)) && (__GNUC__ >= 7 */
780+ #endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */
0 commit comments