aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/external/fprintf/nrf_fprintf_format.c
diff options
context:
space:
mode:
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.c510
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)
+