Skip to content

Commit b0e56ba

Browse files
Merge pull request ARMmbed#20 from marcuschangarm/conform
Improve conformity
2 parents 89e76fc + e0653fc commit b0e56ba

File tree

2 files changed

+137
-86
lines changed

2 files changed

+137
-86
lines changed

mbed_lib.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
{
22
"name": "minimal-printf",
33
"config": {
4+
"console-output": {
5+
"help": "Console output. Options: UART, SWO",
6+
"value": "UART"
7+
},
8+
"enable-64-bit": {
9+
"help": "Enable printing 64 bit integers",
10+
"value": true
11+
},
412
"enable-floating-point": {
513
"help": "Enable floating point printing",
614
"value": false
715
},
816
"set-floating-point-max-decimals": {
917
"help": "Maximum number of decimals to be printed",
1018
"value": 6
11-
},
12-
"enable-64-bit": {
13-
"help": "Enable printing 64 bit integers",
14-
"value": true
15-
},
16-
"console-output": {
17-
"help": "Console output. Options: UART, SWO",
18-
"value": "UART"
1919
}
2020
}
2121
}

mbed_printf_implementation.c

Lines changed: 129 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,24 @@ static void init_serial()
130130
#error unsupported architecture
131131
#endif
132132

133+
/**
134+
* Precision defines
135+
*/
136+
#define PRECISION_DEFAULT (INT_MAX)
137+
133138
/**
134139
* Enum for storing width modifier.
135140
*/
136141
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
146151
} length_t;
147152

148153
/**
@@ -153,7 +158,7 @@ static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length,
153158
static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value);
154159
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value);
155160
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);
157162

158163
/**
159164
* @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,
399404
}
400405

401406
/**
402-
* @brief Print string.
407+
* @brief Print string with precision.
403408
*
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.
408414
*/
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)
410416
{
411-
while (*string != '\0')
417+
while ((*string != '\0') && (precision))
412418
{
413419
mbed_minimal_putchar(buffer, length, result, *string);
414-
string ++;
420+
string++;
421+
precision--;
415422
}
416423
}
417424

@@ -456,85 +463,129 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
456463
{
457464
size_t next_index = index + 1;
458465

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'))
467474
{
468475
/* skip to next character */
469476
next_index++;
470477
}
471478

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++;
474486

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
477491
{
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'))
483494
{
484-
length_modifier = LENGTH_LL;
495+
/* skip to next character */
496+
next_index++;
485497
}
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;
486521

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'))
489524
{
490-
next_index += 2;
525+
precision = precision * 10 + (format[next_index + inner_index] - '0');
526+
527+
inner_index++;
491528
}
529+
530+
/* move index forward to point at next character */
531+
next_index += inner_index;
492532
}
493533

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+
}
494548
/* 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')
496550
{
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;
527552
}
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);
528576

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+
*************************************************************/
530581
char next = format[next_index];
531582

532583
/* signed integer */
533584
if ((next == 'd') || (next == 'i'))
534585
{
535586
MBED_SIGNED_STORAGE value = 0;
536587

537-
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
588+
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
538589
/* if 64 bit is enabled and the integer types are larger than the native type */
539590
if (((length_modifier == LENGTH_LL) && (sizeof(long long int) > sizeof(MBED_SIGNED_NATIVE_TYPE))) ||
540591
((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
544595
value = va_arg(arguments, MBED_SIGNED_STORAGE);
545596
}
546597
else
547-
#endif
598+
#endif
548599
{
549600
/* use native storage type (which can be 32 or 64 bit) */
550601
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
587638
{
588639
MBED_UNSIGNED_STORAGE value = 0;
589640

590-
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
641+
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
591642
/* if 64 bit is enabled and the integer types are larger than the native type */
592643
if (((length_modifier == LENGTH_LL) && (sizeof(unsigned long long int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))) ||
593644
((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
597648
value = va_arg(arguments, MBED_UNSIGNED_STORAGE);
598649
}
599650
else
600-
#endif
651+
#endif
601652
{
602653
/* use native storage type (which can be 32 or 64 bit) */
603654
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
646697
mbed_minimal_formatted_string_hexadecimal(buffer, length, &result, value);
647698
}
648699
}
649-
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
700+
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
650701
/* treat all floating points the same */
651702
else if ((next == 'f') || (next == 'F') || (next == 'g') || (next == 'G'))
652703
{
@@ -655,7 +706,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
655706

656707
mbed_minimal_formatted_string_double(buffer, length, &result, value);
657708
}
658-
#endif
709+
#endif
659710
/* character */
660711
else if (next == 'c')
661712
{
@@ -670,7 +721,7 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
670721
char* value = va_arg(arguments, char*);
671722
index = next_index;
672723

673-
mbed_minimal_formatted_string_string(buffer, length, &result, value);
724+
mbed_minimal_formatted_string_string(buffer, length, &result, value, precision);
674725
}
675726
/* pointer */
676727
else if (next == 'p')

0 commit comments

Comments
 (0)