diff options
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c')
-rw-r--r-- | thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c | 510 |
1 files changed, 510 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c new file mode 100644 index 0000000..a1a2ee9 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c @@ -0,0 +1,510 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* The Embedded Experts * +********************************************************************** +* * +* (c) 2014 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH & Co. KG * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.14d * +* * +*********************************************************************/ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_FPRINTF) + +#include <stdarg.h> + +#include "nrf_assert.h" +#include "nrf_fprintf.h" +#include "nrf_fprintf_format.h" + +#define NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define NRF_CLI_FORMAT_FLAG_PAD_ZERO (1u << 1) +#define NRF_CLI_FORMAT_FLAG_PRINT_SIGN (1u << 2) + +static void buffer_add(nrf_fprintf_ctx_t * const p_ctx, char c) +{ + p_ctx->p_io_buffer[p_ctx->io_buffer_cnt++] = c; + + if (p_ctx->io_buffer_cnt >= p_ctx->io_buffer_size) + { + nrf_fprintf_buffer_flush(p_ctx); + } +} + +static void string_print(nrf_fprintf_ctx_t * const p_ctx, + char const * p_str, + uint32_t FieldWidth, + uint32_t FormatFlags) +{ + uint32_t Width = 0; + char c; + + if ((FormatFlags & NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) == NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) + { + while ((c = *p_str) != '\0') + { + p_str++; + Width++; + buffer_add(p_ctx, c); + } + + while ((FieldWidth > Width) && (FieldWidth > 0)) + { + FieldWidth--; + buffer_add(p_ctx, ' '); + } + } + else + { + if (p_str != 0) + { + Width = strlen(p_str); + } + + while ((FieldWidth > Width) && (FieldWidth > 0)) + { + FieldWidth--; + buffer_add(p_ctx, ' '); + } + + while ((c = *p_str) != '\0') + { + p_str++; + Width++; + buffer_add(p_ctx, c); + } + } +} + +static void unsigned_print(nrf_fprintf_ctx_t * const p_ctx, + uint32_t v, + uint32_t Base, + uint32_t NumDigits, + uint32_t FieldWidth, + uint32_t FormatFlags) +{ + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' }; + uint32_t Div; + uint32_t Value; + uint32_t Width; + char c; + + Value = v; + // + // Get actual field width + // + Width = 1u; + while (Value >= Base) + { + Value = (Value / Base); + Width++; + } + if (NumDigits > Width) + { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) == 0u) + { + if (FieldWidth != 0u) + { + if (((FormatFlags & NRF_CLI_FORMAT_FLAG_PAD_ZERO) == NRF_CLI_FORMAT_FLAG_PAD_ZERO) && + (NumDigits == 0u)) + { + c = '0'; + } + else + { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) + { + FieldWidth--; + buffer_add(p_ctx, c); + } + } + } + + Value = 1; + /* + * Compute Digit. + * Loop until Digit has the value of the highest digit required. + * Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + */ + while (1) + { + /* User specified a min number of digits to print? => Make sure we loop at least that + * often, before checking anything else (> 1 check avoids problems with NumDigits + * being signed / unsigned) + */ + if (NumDigits > 1u) + { + NumDigits--; + } + else + { + Div = v / Value; + // Is our divider big enough to extract the highest digit from value? => Done + if (Div < Base) + { + break; + } + } + Value *= Base; + } + // + // Output digits + // + do + { + Div = v / Value; + v -= Div * Value; + buffer_add(p_ctx, _aV2C[Div]); + Value /= Base; + } while (Value); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) == NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) + { + if (FieldWidth != 0u) + { + while ((FieldWidth != 0u) && (Width < FieldWidth)) + { + FieldWidth--; + buffer_add(p_ctx, ' '); + } + } + } +} + +static void int_print(nrf_fprintf_ctx_t * const p_ctx, + int32_t v, + uint32_t Base, + uint32_t NumDigits, + uint32_t FieldWidth, + uint32_t FormatFlags) +{ + uint32_t Width; + int32_t Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int32_t)Base) + { + Number = (Number / (int32_t)Base); + Width++; + } + if (NumDigits > Width) + { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || + ((FormatFlags & NRF_CLI_FORMAT_FLAG_PRINT_SIGN) == NRF_CLI_FORMAT_FLAG_PRINT_SIGN))) + { + FieldWidth--; + } + // + // Print leading spaces if necessary + // + if ((((FormatFlags & NRF_CLI_FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && + ((FormatFlags & NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) + { + if (FieldWidth != 0u) + { + while ((FieldWidth != 0u) && (Width < FieldWidth)) + { + FieldWidth--; + buffer_add(p_ctx, ' '); + } + } + } + // + // Print sign if necessary + // + if (v < 0) + { + v = -v; + buffer_add(p_ctx, '-'); + } + else if ((FormatFlags & NRF_CLI_FORMAT_FLAG_PRINT_SIGN) == NRF_CLI_FORMAT_FLAG_PRINT_SIGN) + { + buffer_add(p_ctx, '+'); + } + else + { + /* do nothing */ + } + // + // Print leading zeros if necessary + // + if (((FormatFlags & NRF_CLI_FORMAT_FLAG_PAD_ZERO) == NRF_CLI_FORMAT_FLAG_PAD_ZERO) && + ((FormatFlags & NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) + { + if (FieldWidth != 0u) + { + while ((FieldWidth != 0u) && (Width < FieldWidth)) + { + FieldWidth--; + buffer_add(p_ctx, '0'); + } + } + } + // + // Print number without sign + // + unsigned_print(p_ctx, (uint32_t)v, Base, NumDigits, FieldWidth, FormatFlags); +} + +void nrf_fprintf_fmt(nrf_fprintf_ctx_t * const p_ctx, + char const * p_fmt, + va_list * p_args) +{ + ASSERT(p_ctx != NULL); + + ASSERT(p_ctx->fwrite != NULL); + ASSERT(p_ctx->p_io_buffer != NULL); + ASSERT(p_ctx->io_buffer_size > 0); + + if (p_fmt == NULL) + { + return; + } + + char c; + int32_t v; + uint32_t NumDigits; + uint32_t FormatFlags; + uint32_t FieldWidth; + + do + { + c = *p_fmt; + p_fmt++; + + if (c == 0u) + { + break; + } + if (c == '%') + { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + + do + { + c = *p_fmt; + switch (c) + { + case '-': + FormatFlags |= NRF_CLI_FORMAT_FLAG_LEFT_JUSTIFY; + p_fmt++; + break; + case '0': + FormatFlags |= NRF_CLI_FORMAT_FLAG_PAD_ZERO; + p_fmt++; + break; + case '+': + FormatFlags |= NRF_CLI_FORMAT_FLAG_PRINT_SIGN; + p_fmt++; + break; + default: + v = 0; + break; + } + } while (v); + + // + // filter out field width + // + FieldWidth = 0u; + do + { + if (c == '*') + { + /*lint -save -e64 -e56*/ + FieldWidth += va_arg(*p_args, unsigned); + /*lint -restore*/ + p_fmt++; + break; + } + c = *p_fmt; + if ((c < '0') || (c > '9')) + { + break; + } + p_fmt++; + FieldWidth = (FieldWidth * 10u) + (c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *p_fmt; + if (c == '.') + { + p_fmt++; + do + { + c = *p_fmt; + if ((c < '0') || (c > '9')) + { + break; + } + p_fmt++; + NumDigits = NumDigits * 10u + (c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *p_fmt; + do + { + if ((c == 'l') || (c == 'h')) + { + p_fmt++; + c = *p_fmt; + } + else + { + break; + } + } while (1); + // + // Handle specifiers + // + /*lint -save -e64*/ + switch (c) + { + case 'c': + { + char c0; + v = va_arg(*p_args, int32_t); + c0 = (char)v; + buffer_add(p_ctx, c0); + break; + } + case 'd': + case 'i': + v = va_arg(*p_args, int32_t); + int_print(p_ctx, + v, + 10u, + NumDigits, + FieldWidth, + FormatFlags); + break; + case 'u': + v = va_arg(*p_args, int32_t); + unsigned_print(p_ctx, + (uint32_t)v, + 10u, + NumDigits, + FieldWidth, + FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*p_args, int32_t); + unsigned_print(p_ctx, + (uint32_t)v, + 16u, + NumDigits, + FieldWidth, + FormatFlags); + break; + case 's': + { + char const * p_s = va_arg(*p_args, const char *); + string_print(p_ctx, p_s, FieldWidth, FormatFlags); + break; + } + case 'p': + v = va_arg(*p_args, int32_t); + buffer_add(p_ctx, '0'); + buffer_add(p_ctx, 'x'); + unsigned_print(p_ctx, (uint32_t)v, 16u, 8u, 8u, 0); + break; + case '%': + buffer_add(p_ctx, '%'); + break; + default: + break; + } + /*lint -restore*/ + p_fmt++; + } + else + { + buffer_add(p_ctx, c); + } + } while (*p_fmt != '\0'); + + if (p_ctx->auto_flush) + { + nrf_fprintf_buffer_flush(p_ctx); + } +} + +#endif // NRF_MODULE_ENABLED(NRF_FPRINTF) + |