@@ -130,19 +130,24 @@ static void init_serial()
130
130
#error unsupported architecture
131
131
#endif
132
132
133
+ /**
134
+ * Precision defines
135
+ */
136
+ #define PRECISION_DEFAULT (INT_MAX)
137
+
133
138
/**
134
139
* Enum for storing width modifier.
135
140
*/
136
141
typedef enum {
137
- LENGTH_NONE ,
138
- LENGTH_HH ,
139
- LENGTH_H ,
140
- LENGTH_L ,
141
- LENGTH_LL ,
142
- LENGTH_J ,
143
- LENGTH_Z ,
144
- LENGTH_T ,
145
- LENGTH_CAPITAL_L
142
+ LENGTH_NONE = 0x00 ,
143
+ LENGTH_H = 0x11 ,
144
+ LENGTH_L = 0x21 ,
145
+ LENGTH_J = 0x31 ,
146
+ LENGTH_Z = 0x41 ,
147
+ LENGTH_T = 0x51 ,
148
+ LENGTH_CAPITAL_L = 0x61 ,
149
+ LENGTH_HH = 0x72 ,
150
+ LENGTH_LL = 0x82
146
151
} length_t ;
147
152
148
153
/**
@@ -153,7 +158,7 @@ static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length,
153
158
static void mbed_minimal_formatted_string_hexadecimal (char * buffer , size_t length , int * result , MBED_UNSIGNED_STORAGE value );
154
159
static void mbed_minimal_formatted_string_void_pointer (char * buffer , size_t length , int * result , const void * value );
155
160
static void mbed_minimal_formatted_string_character (char * buffer , size_t length , int * result , char character );
156
- static void mbed_minimal_formatted_string_string (char * buffer , size_t length , int * result , const char * string );
161
+ static void mbed_minimal_formatted_string_string (char * buffer , size_t length , int * result , const char * string , size_t precision );
157
162
158
163
/**
159
164
* @brief Print a single character, checking for buffer and size overflows.
@@ -399,19 +404,21 @@ static void mbed_minimal_formatted_string_character(char* buffer, size_t length,
399
404
}
400
405
401
406
/**
402
- * @brief Print string.
407
+ * @brief Print string with precision .
403
408
*
404
- * @param buffer The buffer to store output (NULL for stdout).
405
- * @param[in] length The length of the buffer.
406
- * @param result The current output location.
407
- * @param[in] value The string to be printed.
409
+ * @param buffer The buffer to store output (NULL for stdout).
410
+ * @param[in] length The length of the buffer.
411
+ * @param result The current output location.
412
+ * @param[in] value The string to be printed.
413
+ * @param[in] precision The maximum number of characters to be printed.
408
414
*/
409
- static void mbed_minimal_formatted_string_string (char * buffer , size_t length , int * result , const char * string )
415
+ static void mbed_minimal_formatted_string_string (char * buffer , size_t length , int * result , const char * string , size_t precision )
410
416
{
411
- while (* string != '\0' )
417
+ while (( * string != '\0' ) && ( precision ) )
412
418
{
413
419
mbed_minimal_putchar (buffer , length , result , * string );
414
- string ++ ;
420
+ string ++ ;
421
+ precision -- ;
415
422
}
416
423
}
417
424
@@ -456,85 +463,129 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
456
463
{
457
464
size_t next_index = index + 1 ;
458
465
459
- /* while format string is not empty */
460
- while (( format [ next_index ] != '\0' ) &&
461
- /* skip all flags and precision modifiers */
462
- ((( format [next_index ] >= '0' ) && ( format [ next_index ] < = '9' ) ) ||
463
- (format [next_index ] == '- ' ) ||
464
- (format [next_index ] == '+ ' ) ||
465
- (format [next_index ] == '#' ) ||
466
- (format [next_index ] == '.' ) ))
466
+ /**************************************************************
467
+ * skip and ignore flags [-+(space)#0]
468
+ ************************************************************ */
469
+ if (( format [next_index ] = = '-' ) ||
470
+ (format [next_index ] == '+ ' ) ||
471
+ (format [next_index ] == ' ' ) ||
472
+ (format [next_index ] == '#' ) ||
473
+ (format [next_index ] == '0' ))
467
474
{
468
475
/* skip to next character */
469
476
next_index ++ ;
470
477
}
471
478
472
- /* look for length modifier, default to NONE */
473
- length_t length_modifier = LENGTH_NONE ;
479
+ /**************************************************************
480
+ * skip and ignore width [(number)*]
481
+ *************************************************************/
482
+ if (format [next_index ] == '*' )
483
+ {
484
+ /* skip to next character */
485
+ next_index ++ ;
474
486
475
- /* look for two character length modifier */
476
- if (format [next_index + 1 ] != '\0' )
487
+ /* discard argument */
488
+ va_arg (arguments , MBED_SIGNED_NATIVE_TYPE );
489
+ }
490
+ else
477
491
{
478
- if ((format [next_index ] == 'h' ) && (format [next_index + 1 ] == 'h' ))
479
- {
480
- length_modifier = LENGTH_HH ;
481
- }
482
- else if ((format [next_index ] == 'l' ) && (format [next_index + 1 ] == 'l' ))
492
+ while ((format [next_index ] >= '0' ) &&
493
+ (format [next_index ] <= '9' ))
483
494
{
484
- length_modifier = LENGTH_LL ;
495
+ /* skip to next character */
496
+ next_index ++ ;
485
497
}
498
+ }
499
+
500
+ /**************************************************************
501
+ * look for precision modifier
502
+ *************************************************************/
503
+ int precision = PRECISION_DEFAULT ;
504
+
505
+ if ((format [next_index ] == '.' ) &&
506
+ (format [next_index + 1 ] == '*' ))
507
+ {
508
+ next_index += 2 ;
509
+
510
+ /* read precision from argument list */
511
+ precision = va_arg (arguments , MBED_SIGNED_NATIVE_TYPE );
512
+ }
513
+ else if (format [next_index ] == '.' )
514
+ {
515
+ /* precision modifier found, reset default to 0 and increment index */
516
+ next_index ++ ;
517
+ precision = 0 ;
518
+
519
+ /* parse precision until not a decimal */
520
+ size_t inner_index = 0 ;
486
521
487
- /* increment next_index if length modifier was found */
488
- if ( length_modifier != LENGTH_NONE )
522
+ while (( format [ next_index + inner_index ] >= '0' ) &&
523
+ ( format [ next_index + inner_index ] <= '9' ) )
489
524
{
490
- next_index += 2 ;
525
+ precision = precision * 10 + (format [next_index + inner_index ] - '0' );
526
+
527
+ inner_index ++ ;
491
528
}
529
+
530
+ /* move index forward to point at next character */
531
+ next_index += inner_index ;
492
532
}
493
533
534
+ /**************************************************************
535
+ * look for length modifier, default to NONE
536
+ *************************************************************/
537
+ length_t length_modifier = LENGTH_NONE ;
538
+
539
+ /* look for two character length modifier */
540
+ if ((format [next_index ] == 'h' ) && (format [next_index + 1 ] == 'h' ))
541
+ {
542
+ length_modifier = LENGTH_HH ;
543
+ }
544
+ else if ((format [next_index ] == 'l' ) && (format [next_index + 1 ] == 'l' ))
545
+ {
546
+ length_modifier = LENGTH_LL ;
547
+ }
494
548
/* look for one character length modifier if two character search failed */
495
- if (( length_modifier == LENGTH_NONE ) && ( format [next_index ] != '\0' ) )
549
+ else if (format [next_index ] == 'h' )
496
550
{
497
- if (format [next_index ] == 'h' )
498
- {
499
- length_modifier = LENGTH_H ;
500
- }
501
- else if (format [next_index ] == 'l' )
502
- {
503
- length_modifier = LENGTH_L ;
504
- }
505
- else if (format [next_index ] == 'j' )
506
- {
507
- length_modifier = LENGTH_J ;
508
- }
509
- else if (format [next_index ] == 'z' )
510
- {
511
- length_modifier = LENGTH_Z ;
512
- }
513
- else if (format [next_index ] == 't' )
514
- {
515
- length_modifier = LENGTH_T ;
516
- }
517
- else if (format [next_index ] == 'L' )
518
- {
519
- length_modifier = LENGTH_CAPITAL_L ;
520
- }
521
-
522
- /* increment next_index if length modifier was found */
523
- if (length_modifier != LENGTH_NONE )
524
- {
525
- next_index ++ ;
526
- }
551
+ length_modifier = LENGTH_H ;
527
552
}
553
+ else if (format [next_index ] == 'l' )
554
+ {
555
+ length_modifier = LENGTH_L ;
556
+ }
557
+ else if (format [next_index ] == 'j' )
558
+ {
559
+ length_modifier = LENGTH_J ;
560
+ }
561
+ else if (format [next_index ] == 'z' )
562
+ {
563
+ length_modifier = LENGTH_Z ;
564
+ }
565
+ else if (format [next_index ] == 't' )
566
+ {
567
+ length_modifier = LENGTH_T ;
568
+ }
569
+ else if (format [next_index ] == 'L' )
570
+ {
571
+ length_modifier = LENGTH_CAPITAL_L ;
572
+ }
573
+
574
+ /* increment index, length is encoded in modifier enum */
575
+ next_index += (length_modifier & 0x0F );
528
576
529
- /* read out character - this is a supported format character, '\0', or a not suported character */
577
+ /**************************************************************
578
+ * read out character - this is a supported format character,
579
+ * '\0', or a not suported character
580
+ *************************************************************/
530
581
char next = format [next_index ];
531
582
532
583
/* signed integer */
533
584
if ((next == 'd' ) || (next == 'i' ))
534
585
{
535
586
MBED_SIGNED_STORAGE value = 0 ;
536
587
537
- #if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
588
+ #if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
538
589
/* if 64 bit is enabled and the integer types are larger than the native type */
539
590
if (((length_modifier == LENGTH_LL ) && (sizeof (long long int ) > sizeof (MBED_SIGNED_NATIVE_TYPE ))) ||
540
591
((length_modifier == LENGTH_L ) && (sizeof (long int ) > sizeof (MBED_SIGNED_NATIVE_TYPE ))) ||
@@ -544,7 +595,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
544
595
value = va_arg (arguments , MBED_SIGNED_STORAGE );
545
596
}
546
597
else
547
- #endif
598
+ #endif
548
599
{
549
600
/* use native storage type (which can be 32 or 64 bit) */
550
601
value = va_arg (arguments , MBED_SIGNED_NATIVE_TYPE );
@@ -587,7 +638,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
587
638
{
588
639
MBED_UNSIGNED_STORAGE value = 0 ;
589
640
590
- #if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
641
+ #if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
591
642
/* if 64 bit is enabled and the integer types are larger than the native type */
592
643
if (((length_modifier == LENGTH_LL ) && (sizeof (unsigned long long int ) > sizeof (MBED_UNSIGNED_NATIVE_TYPE ))) ||
593
644
((length_modifier == LENGTH_L ) && (sizeof (unsigned long int ) > sizeof (MBED_UNSIGNED_NATIVE_TYPE ))) ||
@@ -597,7 +648,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
597
648
value = va_arg (arguments , MBED_UNSIGNED_STORAGE );
598
649
}
599
650
else
600
- #endif
651
+ #endif
601
652
{
602
653
/* use native storage type (which can be 32 or 64 bit) */
603
654
value = va_arg (arguments , MBED_UNSIGNED_NATIVE_TYPE );
@@ -646,7 +697,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
646
697
mbed_minimal_formatted_string_hexadecimal (buffer , length , & result , value );
647
698
}
648
699
}
649
- #if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
700
+ #if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
650
701
/* treat all floating points the same */
651
702
else if ((next == 'f' ) || (next == 'F' ) || (next == 'g' ) || (next == 'G' ))
652
703
{
@@ -655,7 +706,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
655
706
656
707
mbed_minimal_formatted_string_double (buffer , length , & result , value );
657
708
}
658
- #endif
709
+ #endif
659
710
/* character */
660
711
else if (next == 'c' )
661
712
{
@@ -670,7 +721,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
670
721
char * value = va_arg (arguments , char * );
671
722
index = next_index ;
672
723
673
- mbed_minimal_formatted_string_string (buffer , length , & result , value );
724
+ mbed_minimal_formatted_string_string (buffer , length , & result , value , precision );
674
725
}
675
726
/* pointer */
676
727
else if (next == 'p' )
0 commit comments