Merge branch 'master-minimal-printf' into minimal-printf

pull/11051/head
Evelyne Donnaes 2019-07-15 16:19:33 +01:00
commit 4018753837
14 changed files with 2841 additions and 0 deletions

118
features/minimal-printf/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,118 @@
// Jenkins configuration.
properties ([
buildDiscarder(
logRotator(artifactDaysToKeepStr: '',
artifactNumToKeepStr: '',
daysToKeepStr: '30',
numToKeepStr: '100'
)
)
])
// RaaS credentials and settings.
raas_username = "ci"
raas_password = "ci"
raas_timeout = 1200
// Test combinations, for each listed target, each toolchain is build and tested on RaaS instance.
targets = [
"K64F": ["toolchains": [ "ARM", "IAR", "GCC_ARM"], "raas": "https://eeva.mbedcloudtesting.com"],
"NUCLEO_F429ZI": ["toolchains": [ "ARM", "IAR", "GCC_ARM"], "raas": "https://ruka.mbedcloudtesting.com"],
]
// Map toolchains to compiler labels to find suitable node on Jenkins.
def nodes = [
ARM: "armcc",
IAR: "iar_arm",
GCC_ARM: "arm-none-eabi-gcc",
SXOS: "linux"
]
// Initial maps for parallel build steps
def buildStepsForParallel = [:]
def testStepsForParallel = [:]
for (target in targets.keySet()) {
for (toolchain_key in targets[target]["toolchains"]) {
echo "Include for build: ${target} ${toolchain_key}"
def stepName = "${target} ${toolchain_key}"
buildStepsForParallel[stepName] = buildStep(target, nodes[toolchain_key], toolchain_key)
}
}
for (target in targets.keySet()) {
for (toolchain_key in targets[target]["toolchains"]) {
echo "Include for test: ${target} ${toolchain_key}"
def stepName = "${target} ${toolchain_key}"
testStepsForParallel[stepName] = testStep(target, nodes[toolchain_key], toolchain_key)
}
}
// Actually run the steps in parallel - parallel takes a map as an argument, hence the above.
timestamps {
parallel buildStepsForParallel
parallel testStepsForParallel
}
// Create build steps for parallel execution.
def buildStep(target, compilerLabel, toolchain) {
return {
stage("Build_${target}_${toolchain}") {
node("${compilerLabel}") {
deleteDir()
echo "buildStep: ${target} ${compilerLabel} ${toolchain}"
dir("test") {
// checkout PR.
checkout scm
// remove wrapper file so we don't compare minimal-printf with itself.
sh "rm ./mbed_printf_wrapper.c"
// checkout newest Mbed OS release.
sh "mbed new ."
// use default release profile for ARM and IAR.
sh "mbed test -vv --compile -m ${target} -t ${toolchain} -n '*minimal-printf*' --build ci --stats-depth 10 --app-config ./TESTS/minimal-printf/compliance/test_app.json"
// stash build directory for testins step.
stash name: "minimal-printf-greentea-${target}-${toolchain}", includes: "ci/**"
}
step([$class: 'WsCleanup'])
}
}
}
}
def testStep(target, compilerLabel, toolchain) {
return {
stage("Light suite ${target}_${toolchain}") {
node("${compilerLabel}") {
deleteDir()
echo "testStep: ${target} ${toolchain}"
// unstash build directory containing greentea tests.
unstash "minimal-printf-greentea-${target}-${toolchain}"
// setup RaaS environment.
env.RAAS_USERNAME = raas_username
env.RAAS_PASSWORD = raas_password
env.RAAS_PYCLIENT_FORCE_REMOTE_ALLOCATION = 1
env.RAAS_PYCLIENT_ALLOCATION_QUEUE_TIMEOUT = raas_timeout
raas = targets[target]["raas"]
// execute greentea on RaaS.
execute("mbedgt -g ${target}:raas_client:${raas}:443 -vV --test-spec ./ci/test_spec.json --polling-timeout 240")
// Clean up workarea.
step([$class: 'WsCleanup'])
}
}
}
}

View File

@ -0,0 +1,117 @@
# Minimal printf and snprintf
Library supports both printf and snprintf in 1252 bytes of flash.
Prints directly to stdio/UART without using malloc. All flags and precision modifiers are ignored.
Floating point is disabled by default.
Printing to a FILE stream is enabled by default.
Supports:
* %d: signed integer [h, hh, (none), l, ll, z, j, t].
* %i: signed integer [h, hh, (none), l, ll, z, j, t].
* %u: unsigned integer [h, hh, (none), l, ll, z, j, t].
* %x: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., ff).
* %X: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., FF).
* %f: floating point (disabled by default).
* %F: floating point (disabled by default, treated as %f).
* %g: floating point (disabled by default, treated as %f).
* %G: floating point (disabled by default, treated as %f).
* %c: character.
* %s: string.
* %p: pointer (e.g. 0x00123456).
Unrecognized format specifiers are treated as ordinary characters.
Floating point support:
* Floating point is disabled by default.
* All floating points are treated as %f.
* No support for inf, infinity or nan
To replace the standard implementations of the printf functions with the ones in this library:
* Add the library to your project.
* Compile with mbed-cli using one of the custom profiles in the `profiles/` subdirectory. For
example, to compile in release mode:
```
$ mbed compile -t <toolchain> -m <target> --profile mbed-printf/profiles/release.json
```
## Enabling floating point, FILE stream, 64 bit integers, new line conversion, and setting baud rate
In mbed_app.json:
```
"target_overrides": {
"*": {
"platform.stdio-baud-rate": 115200,
"platform.stdio-convert-newlines": false,
"minimal-printf.enable-file-stream": true,
"minimal-printf.enable-floating-point": true,
"minimal-printf.set-floating-point-max-decimals": 6,
"minimal-printf.enable-64-bit": true
}
}
```
## Size comparison
Example application compiled with minimal mbed OS (no RTOS) using this .mbedignore:
```
mbed-os/rtos/*
mbed-os/features/FEATURE_LWIP/*
mbed-os/features/FEATURE_CLIENT/*
mbed-os/features/FEATURE_COMMON_PAL/*
mbed-os/features/FEATURE_UVISOR/*
mbed-os/features/frameworks/*
mbed-os/features/net/*
mbed-os/features/netsocket/*
mbed-os/features/storage/*
mbed-os/events/*
```
### Example application
```
#include "mbed.h"
#include "mbed_printf.h"
#include <limits.h>
int main()
{
char buffer[1000];
int result;
double pi = 3.14159265359;
#if 0
result = printf("hello world %d %u %X %p %s %2.5f %% %\r\n", LONG_MAX, ULONG_MAX, UCHAR_MAX, buffer, "muh", pi);
printf("results: %d\r\n", result);
result = snprintf(buffer, 1000, "hello world %d %u %X %p %s %2.5f %% %\r\n", LONG_MIN, 0, 0, buffer, "muh", -1*pi);
printf("%s\r\n", buffer);
printf("results: %d\r\n", result);
#else
result = mbed_printf("hello world %ld %llu %02X %p %s %2.5f %% %\r\n", LONG_MAX, ULONG_MAX, UCHAR_MAX, buffer, "muh", pi);
mbed_printf("results: %d\r\n", result);
result = mbed_snprintf(buffer, 1000, "hello world %d %u %X %p %s %2.5f %% %\r\n", LONG_MIN, 0, 0, buffer, "muh", -1*pi);
mbed_printf("%s\r\n", buffer);
mbed_printf("results: %d\r\n", result);
#endif
}
```
### Full application size on K64F/GCC
| | Floating point | 64 bit integers | Flash | RAM |
| - | - | - | - | - |
| mbed-printf | | | 7772 | 2752 |
| mbed-printf | | X | 8708 | 2752 |
| mbed-printf | X | | 10368 | 2752 |
| mbed-printf | X | X | 11360 | 2752 |
| std printf | X | X | 37354 | 5364 |

View File

@ -0,0 +1,925 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef TARGET_LIKE_MBED
#include "mbed.h"
#endif
#include "mbed_printf.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <inttypes.h>
#ifndef ULLONG_MAX
#define ULLONG_MAX UINT64_MAX
#endif
#ifndef LLONG_MAX
#define LLONG_MAX INT64_MAX
#endif
#ifndef LLONG_MIN
#define LLONG_MIN INT64_MIN
#endif
using namespace utest::v1;
static control_t test_printf_d(const size_t call_count)
{
int result_baseline;
int result_minimal;
int result_file;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_printf("hhd: %hhd\r\n", SCHAR_MIN);
result_file = mbed_fprintf(stderr, "hhd: %hhd\r\n", SCHAR_MIN);
result_baseline = printf("hhd: %hhd\r\n", SCHAR_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hhd: %hhd\r\n", SCHAR_MAX);
result_file = mbed_fprintf(stderr, "hhd: %hhd\r\n", SCHAR_MAX);
result_baseline = printf("hhd: %hhd\r\n", SCHAR_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hd: %hd\r\n", SHRT_MIN);
result_file = mbed_fprintf(stderr, "hd: %hd\r\n", SHRT_MIN);
result_baseline = printf("hd: %hd\r\n", SHRT_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hd: %hd\r\n", SHRT_MAX);
result_file = mbed_fprintf(stderr, "hd: %hd\r\n", SHRT_MAX);
result_baseline = printf("hd: %hd\r\n", SHRT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("d: %d\r\n", INT_MIN);
result_file = mbed_fprintf(stderr, "d: %d\r\n", INT_MIN);
result_baseline = printf("d: %d\r\n", INT_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("d: %d\r\n", INT_MAX);
result_file = mbed_fprintf(stderr, "d: %d\r\n", INT_MAX);
result_baseline = printf("d: %d\r\n", INT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("ld: %ld\r\n", LONG_MIN);
result_file = mbed_fprintf(stderr, "ld: %ld\r\n", LONG_MIN);
result_baseline = printf("ld: %ld\r\n", LONG_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("ld: %ld\r\n", LONG_MAX);
result_file = mbed_fprintf(stderr, "ld: %ld\r\n", LONG_MAX);
result_baseline = printf("ld: %ld\r\n", LONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lld: %lld\r\n", LLONG_MIN);
result_file = mbed_fprintf(stderr, "lld: %lld\r\n", LLONG_MIN);
result_baseline = printf("lld: %lld\r\n", LLONG_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lld: %lld\r\n", LLONG_MAX);
result_file = mbed_fprintf(stderr, "lld: %lld\r\n", LLONG_MAX);
result_baseline = printf("lld: %lld\r\n", LLONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#ifdef TARGET_LIKE_MBED
printf("%%jd not supported by mbed\r\n");
#else
result_minimal = mbed_printf("jd: %jd\r\n", INT32_MIN);
result_file = mbed_fprintf(stderr, "jd: %jd\r\n", INT32_MIN);
result_baseline = printf("jd: %jd\r\n", (intmax_t) INT32_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("jd: %jd\r\n", INT32_MAX);
result_file = mbed_fprintf(stderr, "jd: %jd\r\n", INT32_MAX);
result_baseline = printf("jd: %jd\r\n", (intmax_t) INT32_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%zd not supported by mbed\r\n");
#else
result_minimal = mbed_printf("zd: %zd\r\n", INT32_MIN);
result_file = mbed_fprintf(stderr, "zd: %zd\r\n", INT32_MIN);
result_baseline = printf("zd: %zd\r\n", (ssize_t) INT32_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("zd: %zd\r\n", INT32_MAX);
result_file = mbed_fprintf(stderr, "zd: %zd\r\n", INT32_MAX);
result_baseline = printf("zd: %zd\r\n", (ssize_t) INT32_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%td not supported by mbed\r\n");
#else
result_minimal = mbed_printf("td: %td\r\n", PTRDIFF_MIN);
result_file = mbed_fprintf(stderr, "td: %td\r\n", PTRDIFF_MIN);
result_baseline = printf("td: %td\r\n", PTRDIFF_MIN);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("td: %td\r\n", PTRDIFF_MAX);
result_file = mbed_fprintf(stderr, "td: %td\r\n", PTRDIFF_MAX);
result_baseline = printf("td: %td\r\n", PTRDIFF_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
return CaseNext;
}
static control_t test_printf_u(const size_t call_count)
{
int result_baseline;
int result_minimal;
int result_file;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_printf("hhu: %hhu\r\n", 0);
result_file = mbed_fprintf(stderr, "hhu: %hhu\r\n", 0);
result_baseline = printf("hhu: %hhu\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hhu: %hhu\r\n", UCHAR_MAX);
result_file = mbed_fprintf(stderr, "hhu: %hhu\r\n", UCHAR_MAX);
result_baseline = printf("hhu: %hhu\r\n", UCHAR_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hu: %hu\r\n", 0);
result_file = mbed_fprintf(stderr, "hu: %hu\r\n", 0);
result_baseline = printf("hu: %hu\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hu: %hu\r\n", USHRT_MAX);
result_file = mbed_fprintf(stderr, "hu: %hu\r\n", USHRT_MAX);
result_baseline = printf("hu: %hu\r\n", USHRT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("u: %u\r\n", 0);
result_file = mbed_fprintf(stderr, "u: %u\r\n", 0);
result_baseline = printf("u: %u\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("u: %u\r\n", UINT_MAX);
result_file = mbed_fprintf(stderr, "u: %u\r\n", UINT_MAX);
result_baseline = printf("u: %u\r\n", UINT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lu: %lu\r\n", 0UL);
result_file = mbed_fprintf(stderr, "lu: %lu\r\n", 0UL);
result_baseline = printf("lu: %lu\r\n", 0UL);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lu: %lu\r\n", ULONG_MAX);
result_file = mbed_fprintf(stderr, "lu: %lu\r\n", ULONG_MAX);
result_baseline = printf("lu: %lu\r\n", ULONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("llu: %llu\r\n", 0ULL);
result_file = mbed_fprintf(stderr, "llu: %llu\r\n", 0ULL);
result_baseline = printf("llu: %llu\r\n", 0ULL);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("llu: %llu\r\n", ULLONG_MAX);
result_file = mbed_fprintf(stderr, "llu: %llu\r\n", ULLONG_MAX);
result_baseline = printf("llu: %llu\r\n", ULLONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#ifdef TARGET_LIKE_MBED
printf("%%ju not supported by mbed\r\n");
#else
result_minimal = mbed_printf("ju: %ju\r\n", (uintmax_t) 0);
result_file = mbed_fprintf(stderr, "ju: %ju\r\n", (uintmax_t) 0);
result_baseline = printf("ju: %ju\r\n", (uintmax_t) 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("ju: %ju\r\n", UINTMAX_MAX);
result_file = mbed_fprintf(stderr, "ju: %ju\r\n", UINTMAX_MAX);
result_baseline = printf("ju: %ju\r\n", UINTMAX_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%zu not supported by mbed\r\n");
#else
result_minimal = mbed_printf("zu: %zu\r\n", 0);
result_file = mbed_fprintf(stderr, "zu: %zu\r\n", 0);
result_baseline = printf("zu: %zu\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("zu: %zu\r\n", SIZE_MAX);
result_file = mbed_fprintf(stderr, "zu: %zu\r\n", SIZE_MAX);
result_baseline = printf("zu: %zu\r\n", SIZE_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%tu not supported by mbed\r\n");
#else
result_minimal = mbed_printf("tu: %tu\r\n", 0);
result_file = mbed_fprintf(stderr, "tu: %tu\r\n", 0);
result_baseline = printf("tu: %tu\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("tu: %tu\r\n", UINTPTR_MAX);
result_file = mbed_fprintf(stderr, "tu: %tu\r\n", UINTPTR_MAX);
result_baseline = printf("tu: %tu\r\n", UINTPTR_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
return CaseNext;
}
static control_t test_printf_x(const size_t call_count)
{
int result_baseline;
int result_minimal;
int result_file;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_printf("hhX: %hhX\r\n", 0);
result_file = mbed_fprintf(stderr, "hhX: %hhX\r\n", 0);
result_baseline = printf("hhX: %hhX\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hhX: %hhX\r\n", UCHAR_MAX);
result_file = mbed_fprintf(stderr, "hhX: %hhX\r\n", UCHAR_MAX);
result_baseline = printf("hhX: %hhX\r\n", UCHAR_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hX: %hX\r\n", 0);
result_file = mbed_fprintf(stderr, "hX: %hX\r\n", 0);
result_baseline = printf("hX: %hX\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("hX: %hX\r\n", USHRT_MAX);
result_file = mbed_fprintf(stderr, "hX: %hX\r\n", USHRT_MAX);
result_baseline = printf("hX: %hX\r\n", USHRT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("X: %X\r\n", 0);
result_file = mbed_fprintf(stderr, "X: %X\r\n", 0);
result_baseline = printf("X: %X\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("X: %X\r\n", UINT_MAX);
result_file = mbed_fprintf(stderr, "X: %X\r\n", UINT_MAX);
result_baseline = printf("X: %X\r\n", UINT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lX: %lX\r\n", 0UL);
result_file = mbed_fprintf(stderr, "lX: %lX\r\n", 0UL);
result_baseline = printf("lX: %lX\r\n", 0UL);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("lX: %lX\r\n", ULONG_MAX);
result_file = mbed_fprintf(stderr, "lX: %lX\r\n", ULONG_MAX);
result_baseline = printf("lX: %lX\r\n", ULONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("llX: %llX\r\n", 0ULL);
result_file = mbed_fprintf(stderr, "llX: %llX\r\n", 0ULL);
result_baseline = printf("llX: %llX\r\n", 0ULL);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("llX: %llX\r\n", ULLONG_MAX);
result_file = mbed_fprintf(stderr, "llX: %llX\r\n", ULLONG_MAX);
result_baseline = printf("llX: %llX\r\n", ULLONG_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#ifdef TARGET_LIKE_MBED
printf("%%jX not supported by mbed\r\n");
#else
result_minimal = mbed_printf("jX: %jX\r\n", (uintmax_t) 0);
result_file = mbed_fprintf(stderr, "jX: %jX\r\n", (uintmax_t) 0);
result_baseline = printf("jX: %jX\r\n", (uintmax_t) 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("jX: %jX\r\n", UINTMAX_MAX);
result_file = mbed_fprintf(stderr, "jX: %jX\r\n", UINTMAX_MAX);
result_baseline = printf("jX: %jX\r\n", UINTMAX_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%zX not supported by mbed\r\n");
#else
result_minimal = mbed_printf("zX: %zX\r\n", 0);
result_file = mbed_fprintf(stderr, "zX: %zX\r\n", 0);
result_baseline = printf("zX: %zX\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("zX: %zX\r\n", SIZE_MAX);
result_file = mbed_fprintf(stderr, "zX: %zX\r\n", SIZE_MAX);
result_baseline = printf("zX: %zX\r\n", SIZE_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%tX not supported by mbed\r\n");
#else
result_minimal = mbed_printf("tX: %tX\r\n", 0);
result_file = mbed_fprintf(stderr, "tX: %tX\r\n", 0);
result_baseline = printf("tX: %tX\r\n", 0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("tX: %tX\r\n", UINTPTR_MAX);
result_file = mbed_fprintf(stderr, "tX: %tX\r\n", UINTPTR_MAX);
result_baseline = printf("tX: %tX\r\n", UINTPTR_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
result_minimal = mbed_printf("x: %x\r\n", 11259375);
result_baseline = printf("x: %x\r\n", 11259375);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
/******************************************************************************/
/* */
/* SNPRINTF */
/* */
/******************************************************************************/
static control_t test_snprintf_d(const size_t call_count)
{
char buffer_baseline[100];
char buffer_minimal[100];
int result_baseline;
int result_minimal;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhd: %hhd\r\n", SCHAR_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhd: %hhd\r\n", SCHAR_MIN);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhd: %hhd\r\n", SCHAR_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhd: %hhd\r\n", SCHAR_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hd: %hd\r\n", SHRT_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hd: %hd\r\n", SHRT_MIN);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hd: %hd\r\n", SHRT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hd: %hd\r\n", SHRT_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "d: %d\r\n", INT_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "d: %d\r\n", INT_MIN);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "d: %d\r\n", INT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "d: %d\r\n", INT_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ld: %ld\r\n", LONG_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ld: %ld\r\n", LONG_MIN);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ld: %ld\r\n", LONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ld: %ld\r\n", LONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lld: %lld\r\n", LLONG_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lld: %lld\r\n", LLONG_MIN);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lld: %lld\r\n", LLONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lld: %lld\r\n", LLONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#ifdef TARGET_LIKE_MBED
printf("%%jd not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jd: %jd\r\n", (intmax_t) INT32_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jd: %jd\r\n", (intmax_t) INT32_MIN);
TEST_ASSERT_EQUAL_STRING("jd: -2147483648\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jd: %jd\r\n", (intmax_t) INT32_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jd: %jd\r\n", (intmax_t) INT32_MAX);
TEST_ASSERT_EQUAL_STRING("jd: 2147483647\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%zd not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zd: %zd\r\n", (ssize_t) INT32_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zd: %zd\r\n", (ssize_t) INT32_MIN);
TEST_ASSERT_EQUAL_STRING("zd: -2147483648\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zd: %zd\r\n", (ssize_t) INT32_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zd: %zd\r\n", (ssize_t) INT32_MAX);
TEST_ASSERT_EQUAL_STRING("zd: 2147483647\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%td not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "td: %td\r\n", PTRDIFF_MIN);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "td: %td\r\n", PTRDIFF_MIN);
TEST_ASSERT_EQUAL_STRING("td: -2147483648\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "td: %td\r\n", PTRDIFF_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "td: %td\r\n", PTRDIFF_MAX);
TEST_ASSERT_EQUAL_STRING("td: 2147483647\r\n", buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
return CaseNext;
}
static control_t test_snprintf_u(const size_t call_count)
{
char buffer_baseline[100];
char buffer_minimal[100];
int result_baseline;
int result_minimal;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhu: %hhu\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhu: %hhu\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhu: %hhu\r\n", UCHAR_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhu: %hhu\r\n", UCHAR_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hu: %hu\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hu: %hu\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hu: %hu\r\n", USHRT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hu: %hu\r\n", USHRT_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "u: %u\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "u: %u\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "u: %u\r\n", UINT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "u: %u\r\n", UINT_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lu: %lu\r\n", 0UL);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lu: %lu\r\n", 0UL);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lu: %lu\r\n", ULONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lu: %lu\r\n", ULONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llu: %llu\r\n", 0ULL);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llu: %llu\r\n", 0ULL);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llu: %llu\r\n", ULLONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llu: %llu\r\n", ULLONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#ifdef TARGET_LIKE_MBED
printf("%%ju not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ju: %ju\r\n", (uintmax_t) 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ju: %ju\r\n", (uintmax_t) 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "ju: %ju\r\n", UINTMAX_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "ju: %ju\r\n", UINTMAX_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%zu not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zu: %zu\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zu: %zu\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zu: %zu\r\n", SIZE_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zu: %zu\r\n", SIZE_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%tu not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tu: %tu\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tu: %tu\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tu: %tu\r\n", UINTPTR_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tu: %tu\r\n", UINTPTR_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
return CaseNext;
}
static control_t test_snprintf_x(const size_t call_count)
{
char buffer_baseline[100];
char buffer_minimal[100];
int result_baseline;
int result_minimal;
/*************************************************************************/
/*************************************************************************/
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhX: %hhX\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhX: %hhX\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hhX: %hhX\r\n", UCHAR_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hhX: %hhX\r\n", UCHAR_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hX: %hX\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hX: %hX\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "hX: %hX\r\n", USHRT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "hX: %hX\r\n", USHRT_MAX);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "X: %X\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "X: %X\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "X: %X\r\n", UINT_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "X: %X\r\n", UINT_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lX: %lX\r\n", 0UL);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lX: %lX\r\n", 0UL);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "lX: %lX\r\n", ULONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "lX: %lX\r\n", ULONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llX: %llX\r\n", 0ULL);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llX: %llX\r\n", 0ULL);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "llX: %llX\r\n", ULLONG_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "llX: %llX\r\n", ULLONG_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#ifdef TARGET_LIKE_MBED
printf("%%jX not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jX: %jX\r\n", (uintmax_t) 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jX: %jX\r\n", (uintmax_t) 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "jX: %jX\r\n", UINTMAX_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "jX: %jX\r\n", UINTMAX_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%xX not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zX: %zX\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zX: %zX\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "zX: %zX\r\n", SIZE_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "zX: %zX\r\n", SIZE_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
#ifdef TARGET_LIKE_MBED
printf("%%tX not supported by mbed\r\n");
#else
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tX: %tX\r\n", 0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tX: %tX\r\n", 0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "tX: %tX\r\n", UINTPTR_MAX);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "tX: %tX\r\n", UINTPTR_MAX);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
return CaseNext;
}
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
static control_t test_printf_f(const size_t call_count)
{
int result_baseline;
int result_minimal;
/*************************************************************************/
/*************************************************************************/
double pi = 3.14159265359;
result_minimal = mbed_printf("f: %f\r\n", 3.0089);
result_baseline = printf("f: %f\r\n", 3.0089);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_printf("f: %f\r\n", 7.0);
result_baseline = printf("f: %f\r\n", 7.0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_printf("f: %f\r\n", -1 * pi);
result_baseline = printf("f: %f\r\n", -1 * pi);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_printf("f: %f\r\n", 0.0);
result_baseline = printf("f: %f\r\n", 0.0);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_printf("f: %f\r\n", pi);
result_baseline = printf("f: %f\r\n", pi);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
static control_t test_snprintf_f(const size_t call_count)
{
char buffer_baseline[100];
char buffer_minimal[100];
int result_baseline;
int result_minimal;
/*************************************************************************/
/*************************************************************************/
double pi = 3.14159265359;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", 3.0089);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", 3.0089);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", 7.0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", 7.0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", -1 * pi);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", -1 * pi);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", 0.0);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", 0.0);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %f\r\n", pi);
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "f: %f\r\n", pi);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
#endif
/* Generic buffer overflow test function.
* Template parameters:
* 'T' is the type being tested
* 'buf_size' is the buffer size used in tests
* Function parameters:
* 'fmt' is the format to use for sprintf
* 'data' is the data that will be printed
*/
template<typename T, size_t buf_size>
static control_t test_snprintf_buffer_overflow_generic(const char *fmt, T data)
{
char buffer_baseline[buf_size];
char buffer_minimal[buf_size];
int result_baseline;
int result_minimal;
/* empty buffer test */
result_minimal = mbed_snprintf(buffer_minimal, 0, fmt, data);
result_baseline = snprintf(buffer_baseline, 0, fmt, data);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
/* buffer isn't large enough, output needs to be truncated */
result_minimal = mbed_snprintf(buffer_minimal, buf_size - 2, fmt, data);
result_baseline = snprintf(buffer_baseline, buf_size - 2, fmt, data);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
/* buffer is one byte shorter than needed, string terminator must
be written and output must be truncated */
result_minimal = mbed_snprintf(buffer_minimal, buf_size - 1, fmt, data);
result_baseline = snprintf(buffer_baseline, buf_size - 1, fmt, data);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
/* buffer is just long enough */
result_minimal = mbed_snprintf(buffer_minimal, buf_size, fmt, data);
result_baseline = snprintf(buffer_baseline, buf_size, fmt, data);
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
/* Based on the generic buffer overflow function above, create tests for
each relevant data type. In each case, the buffer for printing will only
be large enough to fit the printed data. */
static control_t test_snprintf_buffer_overflow_d(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<int, sizeof("d: -1024")>("d: %d", -1024);
}
static control_t test_snprintf_buffer_overflow_ld(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<long, sizeof("ld: -1048576")>("ld: %ld", -1048576L);
}
static control_t test_snprintf_buffer_overflow_lld(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<long long, sizeof("lld: -1099511627776")>("lld: %lld", -1099511627776LL);
}
static control_t test_snprintf_buffer_overflow_u(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned int, sizeof("u: 1024")>("u: %u", 1024);
}
static control_t test_snprintf_buffer_overflow_lu(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned long, sizeof("lu: 1048576")>("lu: %lu", 1048576UL);
}
static control_t test_snprintf_buffer_overflow_llu(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned long long, sizeof("llu: 1099511627776")>("llu: %llu", 1099511627776ULL);
}
static control_t test_snprintf_buffer_overflow_x(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned int, sizeof("x: 0x400")>("x: 0x%x", 0x400);
}
static control_t test_snprintf_buffer_overflow_lx(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned long, sizeof("lx: 0x100000")>("lx: 0x%lx", 0x100000UL);
}
static control_t test_snprintf_buffer_overflow_llx(const size_t call_count)
{
return test_snprintf_buffer_overflow_generic<unsigned long long, sizeof("llx: 0x10000000000")>("llx: 0x%llx", 0x10000000000ULL);
}
utest::v1::status_t greentea_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(30*60, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("printf %d", test_printf_d),
Case("snprintf %d", test_snprintf_d),
Case("printf %u", test_printf_u),
Case("snprintf %u", test_snprintf_u),
Case("printf %x", test_printf_x),
Case("snprintf %x", test_snprintf_x),
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
Case("printf %f", test_printf_f),
Case("snprintf %f", test_snprintf_f),
#endif
Case("snprintf buffer overflow %d", test_snprintf_buffer_overflow_d),
Case("snprintf buffer overflow %ld", test_snprintf_buffer_overflow_ld),
Case("snprintf buffer overflow %lld", test_snprintf_buffer_overflow_lld),
Case("snprintf buffer overflow %u", test_snprintf_buffer_overflow_u),
Case("snprintf buffer overflow %lu", test_snprintf_buffer_overflow_lu),
Case("snprintf buffer overflow %llu", test_snprintf_buffer_overflow_llu),
Case("snprintf buffer overflow %x", test_snprintf_buffer_overflow_x),
Case("snprintf buffer overflow %lx", test_snprintf_buffer_overflow_lx),
Case("snprintf buffer overflow %llx", test_snprintf_buffer_overflow_llx),
};
Specification specification(greentea_setup, cases, greentea_test_teardown_handler);
int main()
{
return !Harness::run(specification);
}

View File

@ -0,0 +1,7 @@
{
"target_overrides": {
"*": {
"minimal-printf.enable-file-stream": 1
}
}
}

View File

@ -0,0 +1,25 @@
{
"name": "minimal-printf",
"config": {
"console-output": {
"help": "Console output. Options: UART, SWO",
"value": "UART"
},
"enable-64-bit": {
"help": "Enable printing 64 bit integers",
"value": true
},
"enable-file-stream": {
"help": "Enable printing to a FILE stream",
"value": true
},
"enable-floating-point": {
"help": "Enable floating point printing",
"value": false
},
"set-floating-point-max-decimals": {
"help": "Maximum number of decimals to be printed",
"value": 6
}
}
}

View File

@ -0,0 +1,66 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_printf_implementation.h"
#include <limits.h>
int mbed_printf(const char *format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int mbed_snprintf(char* buffer, size_t length, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
va_end(arguments);
return result;
}
int mbed_vprintf(const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
}
int mbed_vsnprintf(char* buffer, size_t length, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
}
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
int mbed_fprintf(FILE* stream, const char *format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
va_end(arguments);
return result;
}
int mbed_vfprintf(FILE* stream, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
}
#endif

View File

@ -0,0 +1,75 @@
/* mbed Microcontroller Library
* Copyright (c) 2016 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PRINTF_H
#define MBED_PRINTF_H
#include <stdio.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Minimal printf
*
* Prints directly to stdio/UART without using malloc.
*/
int mbed_printf(const char *format, ...);
/**
* Minimal snprintf
*
* Prints directly to buffer without using malloc.
*/
int mbed_snprintf(char* buffer, size_t length, const char* format, ...);
/**
* Minimal printf
*
* Prints directly to stdio/UART without using malloc.
*/
int mbed_vprintf(const char* format, va_list arguments);
/**
* Minimal snprintf
*
* Prints directly to buffer without using malloc.
*/
int mbed_vsnprintf(char* buffer, size_t length, const char* format, va_list arguments);
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
/**
* Minimal fprintf
*
* Prints directly to file stream without using malloc.
*/
int mbed_fprintf(FILE* stream, const char *format, ...);
/**
* Minimal vfprintf
*
* Prints directly to file stream without using malloc.
*/
int mbed_vfprintf(FILE* stream, const char* format, va_list arguments);
#endif
#ifdef __cplusplus
}
#endif
#endif // MBED_PRINTF_H

View File

@ -0,0 +1,371 @@
/* mbed Microcontroller Library
* Copyright (c) 2019 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Arm Compiler uses dedicated functions for each format specifier used by
* [sn/v/vsn]printf. When minimal-printf overwrites [sn/v/vsn]printf the
* linker is unable to remove unused functions related to printf.
*
* The following stubs replace the built-in functions and helps the linker
* to resolve dependencies and correctly remove unused functions.
*/
#if defined(TOOLCHAIN_ARM)
#include "mbed_printf_implementation.h"
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
/**
* Arm Compiler uses __2[s/sn/vsn]printf internally.
*/
int $Sub$$__2printf(const char *format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int $Sub$$__2sprintf(char* buffer, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int $Sub$$__2snprintf(char* buffer, size_t length, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
va_end(arguments);
return result;
}
int $Sub$$__2vprintf(char* buffer, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int $Sub$$__2vsnprintf(char* buffer, size_t length, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
}
/**
* Replace the built-in functions which the linker is unable to prune with dummy stubs
* that take up less space.
*/
int $Sub$$_printf_a(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_c(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_char(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_char_common(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_char_file_locked(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_charcount(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_cs_common(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_d(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_dec(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_e(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_f(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_fp_dec(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_fp_dec_real(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_fp_hex(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_fp_hex_real(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_fp_infnan(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_g(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_hex_int_ll_ptr(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_hex_ptr(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_i(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_int_common(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_int_dec(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_int_hex(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_int_oct(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_l(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_lc(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_lcs_common(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_ll(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_ll_hex(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_ll_oct(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_lld(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_lli(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_llo(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_llu(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_llx(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_longlong_dec(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_longlong_hex(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_longlong_oct(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_ls(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_n(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_o(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_oct_int_ll(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_p(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_pad(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_percent(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_percent_end(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_s(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_str(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_string(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_truncate(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_truncate_signed(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_truncate_unsigned(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_u(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_wchar(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_wctomb(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_wstring(const char *format, ...)
{
return 0;
}
int $Sub$$_printf_x(const char *format, ...)
{
return 0;
}
#endif

View File

@ -0,0 +1,805 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_printf_implementation.h"
#include <stdbool.h>
#include <limits.h>
#include <stdint.h>
#include <stddef.h>
/***************************/
/* MBED */
/***************************/
#if TARGET_LIKE_MBED
#define CONSOLE_OUTPUT_UART 1
#define CONSOLE_OUTPUT_SWO 2
#define mbed_console_concat_(x) CONSOLE_OUTPUT_##x
#define mbed_console_concat(x) mbed_console_concat_(x)
#define CONSOLE_OUTPUT mbed_console_concat(MBED_CONF_MINIMAL_PRINTF_CONSOLE_OUTPUT)
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
static char mbed_stdio_out_prev = 0;
#endif
#if CONSOLE_OUTPUT == CONSOLE_OUTPUT_UART
#if DEVICE_SERIAL
/*
Serial initialization and new line replacement is a direct copy from mbed_retarget.cpp
If the static modifier were to be removed, this part of the code would not be necessary.
*/
#include "hal/serial_api.h"
static serial_t stdio_uart = { 0 };
/* module variable for keeping track of initialization */
static bool not_initialized = true;
static void init_serial()
{
if (not_initialized)
{
not_initialized = false;
serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
#if MBED_CONF_PLATFORM_STDIO_BAUD_RATE
serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
#endif
}
}
#define MBED_INITIALIZE_PRINT(x) { init_serial(); }
#define MBED_PRINT_CHARACTER(x) { serial_putc(&stdio_uart, x); }
#else
#define MBED_INITIALIZE_PRINT(x)
#define MBED_PRINT_CHARACTER(x)
#endif // if DEVICE_SERIAL
#elif CONSOLE_OUTPUT == CONSOLE_OUTPUT_SWO
#include "hal/itm_api.h"
#define MBED_INITIALIZE_PRINT(x) { mbed_itm_init(); }
#define MBED_PRINT_CHARACTER(x) { mbed_itm_send(ITM_PORT_SWO, x); }
#endif // if CONSOLE_OUTPUT
/***************************/
/* Linux */
/***************************/
#else
/* Linux implementation is for debug only */
#define MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT 1
#define MBED_CONF_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS 6
#define MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT 1
#define MBED_INITIALIZE_PRINT(x) { ; }
#define MBED_PRINT_CHARACTER(x) { printf("%c", x); }
#endif
#ifndef MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
#define MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT 0
#endif
#ifndef MBED_CONF_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS
#define MBED_CONF_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS 6
#endif
#ifndef MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
#define MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT 1
#endif
/**
* Check architecture and choose storage data type.
* On 32 bit machines, the default storage type is 32 bit wide
* unless 64 bit integers are enabled in the configuration.
*/
#if INTPTR_MAX == INT32_MAX
#define MBED_SIGNED_NATIVE_TYPE int32_t
#define MBED_UNSIGNED_NATIVE_TYPE uint32_t
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
#define MBED_SIGNED_STORAGE int64_t
#define MBED_UNSIGNED_STORAGE uint64_t
#else
#define MBED_SIGNED_STORAGE int32_t
#define MBED_UNSIGNED_STORAGE uint32_t
#endif
#elif INTPTR_MAX == INT64_MAX
#define MBED_SIGNED_NATIVE_TYPE int64_t
#define MBED_UNSIGNED_NATIVE_TYPE uint64_t
#define MBED_SIGNED_STORAGE int64_t
#define MBED_UNSIGNED_STORAGE uint64_t
#else
#error unsupported architecture
#endif
/**
* Precision defines
*/
#define PRECISION_DEFAULT (INT_MAX)
/**
* Enum for storing width modifier.
*/
typedef enum {
LENGTH_NONE = 0x00,
LENGTH_H = 0x11,
LENGTH_L = 0x21,
LENGTH_J = 0x31,
LENGTH_Z = 0x41,
LENGTH_T = 0x51,
LENGTH_CAPITAL_L = 0x61,
LENGTH_HH = 0x72,
LENGTH_LL = 0x82
} length_t;
/**
* Prototypes
*/
static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, int* result, MBED_SIGNED_STORAGE value, FILE* stream);
static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value, FILE* stream);
static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value, FILE* stream, bool upper);
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value, FILE* stream);
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character, FILE* stream);
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string, size_t precision, FILE* stream);
/**
* @brief Print a single character, checking for buffer and size overflows.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] data The char to be printed.
*/
static void mbed_minimal_putchar(char *buffer, size_t length, int* result, char data, FILE* stream)
{
/* only continue if 'result' doesn't overflow */
if ((*result >= 0) && (*result <= INT_MAX - 1))
{
/* write data only if there's enough space */
if ((size_t)*result < length)
{
if (buffer)
{
buffer[*result] = data;
}
else
{
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
if (stream)
{
fputc(data, (FILE*) stream);
}
else
#endif
{
MBED_PRINT_CHARACTER(data);
}
}
}
/* increment 'result' even if data was not written. This ensures that
'mbed_minimal_formatted_string' returns the correct value. */
*result += 1;
}
}
/**
* @brief Print signed integer.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
*/
static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, int* result, MBED_SIGNED_STORAGE value, FILE* stream)
{
MBED_UNSIGNED_STORAGE new_value = 0;
/* if value is negative print sign and treat as positive number */
if (value < 0)
{
/* write sign */
mbed_minimal_putchar(buffer, length, result, '-', stream);
/* get absolute value using two's complement */
new_value = ~((MBED_UNSIGNED_STORAGE) value) + 1;
}
else
{
new_value = value;
}
/* use unsigned long int function */
mbed_minimal_formatted_string_unsigned(buffer, length, result, new_value, stream);
}
/**
* @brief Print unsigned integer.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
*/
static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value, FILE* stream)
{
/* treat 0 as a corner case */
if (value == 0)
{
mbed_minimal_putchar(buffer, length, result, '0', stream);
}
else
{
/* allocate 3 digits per byte */
char scratch[sizeof(MBED_UNSIGNED_STORAGE) * 3] = { 0 };
size_t index = 0;
/* write numbers in reverse order to scratch pad */
for ( ; value > 0; index++)
{
/* use '0' as base and add digit */
scratch[index] = '0' + (value % 10);
/* shift value one decimal position */
value = value / 10;
}
/* write scratch pad to buffer or output */
for ( ; index > 0; index--)
{
mbed_minimal_putchar(buffer, length, result, scratch[index - 1], stream);
}
}
}
/**
* @brief Print hexadecimal.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param upper Flag to print the hexadecimal in upper or lower case.
*/
static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value, FILE* stream, bool upper)
{
bool print_leading_zero = false;
for (int index = 7; index >= 0; index--)
{
/* get most significant byte */
uint8_t output = value >> (8 * index);
/* only print leading zeros when set */
if (print_leading_zero || (output != 0) || (index == 0))
{
unsigned int nibble_one = (output >> 4);
unsigned int nibble_two = (output & 0x0F);
const char int2hex_lower[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
const char int2hex_upper[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
const char *int2hex = upper ? int2hex_upper : int2hex_lower;
if (print_leading_zero || nibble_one != 0) {
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_one], stream);
}
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_two], stream);
/* print zeroes after the first non-zero byte */
print_leading_zero = true;
}
}
}
/**
* @brief Print pointer.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The pointer to be printed.
*/
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value, FILE* stream)
{
/* write leading 0x */
mbed_minimal_putchar(buffer, length, result, '0', stream);
mbed_minimal_putchar(buffer, length, result, 'x', stream);
/* write rest as a regular hexadecimal number */
mbed_minimal_formatted_string_hexadecimal(buffer, length, result, (ptrdiff_t) value, stream, true);
}
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
/**
* @brief Write double.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
*/
static void mbed_minimal_formatted_string_double(char* buffer, size_t length, int* result, double value, FILE* stream)
{
/* get integer part */
MBED_SIGNED_STORAGE integer = value;
/* write integer part */
mbed_minimal_formatted_string_signed(buffer, length, result, integer, stream);
/* write decimal point */
mbed_minimal_formatted_string_character(buffer, length, result, '.', stream);
/* get decimal part */
double precision = 1.0;
for (size_t index = 0; index < MBED_CONF_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS; index++)
{
precision *= 10;
}
value = (value - integer) * precision;
/* convert to unsigned integer */
MBED_UNSIGNED_STORAGE decimal = 0;
if (value < 0)
{
MBED_SIGNED_STORAGE temp = value;
decimal = ~((MBED_UNSIGNED_STORAGE) temp) + 1;
}
else
{
decimal = value;
}
/* round up or down */
value -= decimal;
if (!((value > -0.5) && (value < 0.5)))
{
decimal++;
}
/* convert precision to unsigned integer */
MBED_UNSIGNED_STORAGE precision_in_uint = precision;
precision_in_uint /= 10;
/* ensure that leading zeros are printed if decimal equals 0 */
MBED_UNSIGNED_STORAGE val = decimal ? decimal : decimal + 1;
while (precision_in_uint > val) {
/* print leading zeros */
mbed_minimal_putchar(buffer, length, result, '0', stream);
precision_in_uint /= 10;
}
/* write decimal part */
mbed_minimal_formatted_string_unsigned(buffer, length, result, decimal, stream);
}
#endif
/**
* @brief Print character.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The character to be printed.
*/
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character, FILE* stream)
{
/* write character */
if (buffer)
{
mbed_minimal_putchar(buffer, length, result, character, stream);
}
else
{
/* convert \n to \r\n if enabled in platform configuration */
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
if (character == '\n' && mbed_stdio_out_prev != '\r')
{
mbed_minimal_putchar(buffer, length, result, '\r', stream);
}
/* cache character */
mbed_stdio_out_prev = character;
#endif
mbed_minimal_putchar(buffer, length, result, character, stream);
}
}
/**
* @brief Print string with precision.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The string to be printed.
* @param[in] precision The maximum number of characters to be printed.
*/
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string, size_t precision, FILE* stream)
{
while ((*string != '\0') && (precision))
{
mbed_minimal_putchar(buffer, length, result, *string, stream);
string++;
precision--;
}
}
/**
* @brief Parse formatted string and invoke write handlers based on type.
*
* @param buffer The buffer to write to, write to stdout if NULL.
* @param[in] length The length of the buffer.
* @param[in] format The formatted string.
* @param[in] arguments The va_list arguments.
*
* @return Number of characters written.
*/
int mbed_minimal_formatted_string(char* buffer, size_t length, const char* format, va_list arguments, FILE* stream)
{
/* initialize output if needed */
MBED_INITIALIZE_PRINT();
int result = 0;
bool empty_buffer = false;
/* ensure that function wasn't called with an empty buffer, or with or with
a buffer size that is larger than the maximum 'int' value, or with
a NULL format specifier */
if (format && length <= INT_MAX)
{
/* Make sure that there's always space for the NULL terminator */
if (length > 0)
{
length --;
}
else
{
/* the buffer is empty, there's no place to write the terminator */
empty_buffer = true;
}
/* parse string */
for (size_t index = 0; format[index] != '\0'; index++)
{
/* format specifier begin */
if (format[index] == '%')
{
size_t next_index = index + 1;
/**************************************************************
* skip and ignore flags [-+(space)#0]
*************************************************************/
if ((format[next_index] == '-') ||
(format[next_index] == '+') ||
(format[next_index] == ' ') ||
(format[next_index] == '#') ||
(format[next_index] == '0'))
{
/* skip to next character */
next_index++;
}
/**************************************************************
* skip and ignore width [(number)*]
*************************************************************/
if (format[next_index] == '*')
{
/* skip to next character */
next_index++;
/* discard argument */
va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
else
{
while ((format[next_index] >= '0') &&
(format[next_index] <= '9'))
{
/* skip to next character */
next_index++;
}
}
/**************************************************************
* look for precision modifier
*************************************************************/
int precision = PRECISION_DEFAULT;
if ((format[next_index] == '.') &&
(format[next_index + 1] == '*'))
{
next_index += 2;
/* read precision from argument list */
precision = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
else if (format[next_index] == '.')
{
/* precision modifier found, reset default to 0 and increment index */
next_index++;
precision = 0;
/* parse precision until not a decimal */
size_t inner_index = 0;
while ((format[next_index + inner_index] >= '0') &&
(format[next_index + inner_index] <= '9'))
{
precision = precision * 10 + (format[next_index + inner_index] - '0');
inner_index++;
}
/* move index forward to point at next character */
next_index += inner_index;
}
/**************************************************************
* look for length modifier, default to NONE
*************************************************************/
length_t length_modifier = LENGTH_NONE;
/* look for two character length modifier */
if ((format[next_index] == 'h') && (format[next_index + 1] == 'h'))
{
length_modifier = LENGTH_HH;
}
else if ((format[next_index] == 'l') && (format[next_index + 1] == 'l'))
{
length_modifier = LENGTH_LL;
}
/* look for one character length modifier if two character search failed */
else if (format[next_index] == 'h')
{
length_modifier = LENGTH_H;
}
else if (format[next_index] == 'l')
{
length_modifier = LENGTH_L;
}
else if (format[next_index] == 'j')
{
length_modifier = LENGTH_J;
}
else if (format[next_index] == 'z')
{
length_modifier = LENGTH_Z;
}
else if (format[next_index] == 't')
{
length_modifier = LENGTH_T;
}
else if (format[next_index] == 'L')
{
length_modifier = LENGTH_CAPITAL_L;
}
/* increment index, length is encoded in modifier enum */
next_index += (length_modifier & 0x0F);
/**************************************************************
* read out character - this is a supported format character,
* '\0', or a not suported character
*************************************************************/
char next = format[next_index];
/* signed integer */
if ((next == 'd') || (next == 'i'))
{
MBED_SIGNED_STORAGE value = 0;
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
/* if 64 bit is enabled and the integer types are larger than the native type */
if (((length_modifier == LENGTH_LL) && (sizeof(long long int) > sizeof(MBED_SIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_L) && (sizeof(long int) > sizeof(MBED_SIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_NONE) && (sizeof(int) > sizeof(MBED_SIGNED_NATIVE_TYPE))))
{
/* use 64 bit storage type for readout */
value = va_arg(arguments, MBED_SIGNED_STORAGE);
}
else
#endif
{
/* use native storage type (which can be 32 or 64 bit) */
value = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
}
/* constrict value based on lenght modifier */
switch (length_modifier)
{
case LENGTH_NONE:
value = (int) value;
break;
case LENGTH_HH:
value = (signed char) value;
break;
case LENGTH_H:
value = (short int) value;
break;
case LENGTH_L:
value = (long int) value;
break;
case LENGTH_LL:
value = (long long int) value;
break;
case LENGTH_J:
value = (intmax_t) value;
break;
case LENGTH_T:
value = (ptrdiff_t) value;
break;
default:
break;
}
index = next_index;
mbed_minimal_formatted_string_signed(buffer, length, &result, value, stream);
}
/* unsigned integer */
else if ((next == 'u') || (next == 'x') || (next == 'X'))
{
MBED_UNSIGNED_STORAGE value = 0;
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_64_BIT
/* if 64 bit is enabled and the integer types are larger than the native type */
if (((length_modifier == LENGTH_LL) && (sizeof(unsigned long long int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_L) && (sizeof(unsigned long int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))) ||
((length_modifier == LENGTH_NONE) && (sizeof(unsigned int) > sizeof(MBED_UNSIGNED_NATIVE_TYPE))))
{
/* use 64 bit storage type for readout */
value = va_arg(arguments, MBED_UNSIGNED_STORAGE);
}
else
#endif
{
/* use native storage type (which can be 32 or 64 bit) */
value = va_arg(arguments, MBED_UNSIGNED_NATIVE_TYPE);
}
/* constrict value based on lenght modifier */
switch (length_modifier)
{
case LENGTH_NONE:
value = (unsigned int) value;
break;
case LENGTH_HH:
value = (unsigned char) value;
break;
case LENGTH_H:
value = (unsigned short int) value;
break;
case LENGTH_L:
value = (unsigned long int) value;
break;
case LENGTH_LL:
value = (unsigned long long int) value;
break;
case LENGTH_J:
value = (uintmax_t) value;
break;
case LENGTH_Z:
value = (size_t) value;
break;
case LENGTH_T:
value = (ptrdiff_t) value;
break;
default:
break;
}
index = next_index;
/* write unsigned or hexadecimal */
if (next == 'u')
{
mbed_minimal_formatted_string_unsigned(buffer, length, &result, value, stream);
}
else
{
mbed_minimal_formatted_string_hexadecimal(buffer, length, &result, value, stream, next == 'X');
}
}
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
/* treat all floating points the same */
else if ((next == 'f') || (next == 'F') || (next == 'g') || (next == 'G'))
{
double value = va_arg(arguments, double);
index = next_index;
mbed_minimal_formatted_string_double(buffer, length, &result, value, stream);
}
#endif
/* character */
else if (next == 'c')
{
char value = va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
index = next_index;
mbed_minimal_formatted_string_character(buffer, length, &result, value, stream);
}
/* string */
else if (next == 's')
{
char* value = va_arg(arguments, char*);
index = next_index;
mbed_minimal_formatted_string_string(buffer, length, &result, value, precision, stream);
}
/* pointer */
else if (next == 'p')
{
void* value = va_arg(arguments, void*);
index = next_index;
mbed_minimal_formatted_string_void_pointer(buffer, length, &result, value, stream);
}
else
{
/* write all characters between format beginning and unrecognied modifier */
while (index < next_index)
{
mbed_minimal_formatted_string_character(buffer, length, &result, format[index], stream);
index++;
}
/* if this is not the end of the string, write unrecognized modifier */
if (next != '\0')
{
mbed_minimal_formatted_string_character(buffer, length, &result, format[index], stream);
}
else
{
/* break out of for loop */
break;
}
}
}
else
/* not a format specifier */
{
/* write normal character */
mbed_minimal_formatted_string_character(buffer, length, &result, format[index], stream);
}
}
if (buffer && !empty_buffer)
{
/* NULL-terminate the buffer no matter what. We use '<=' to compare instead of '<'
because we know that we initially reserved space for '\0' by decrementing length */
if ((size_t)result <= length)
{
buffer[result] = '\0';
}
else
{
buffer[length] = '\0';
}
}
}
return result;
}

View File

@ -0,0 +1,20 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
int mbed_minimal_formatted_string(char* buffer, size_t length, const char* format, va_list arguments, FILE* stream);

View File

@ -0,0 +1,128 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_printf_implementation.h"
#include <limits.h>
#if defined(TOOLCHAIN_GCC)
#define SUB_PRINTF __wrap_printf
#define SUB_SPRINTF __wrap_sprintf
#define SUB_SNPRINTF __wrap_snprintf
#define SUB_VPRINTF __wrap_vprintf
#define SUB_VSPRINTF __wrap_vsprintf
#define SUB_VSNPRINTF __wrap_vsnprintf
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
#define SUB_FPRINTF __wrap_fprintf
#define SUB_VFPRINTF __wrap_vfprintf
#endif
#elif defined(TOOLCHAIN_ARM)
#define SUPER_PRINTF $Super$$printf
#define SUB_PRINTF $Sub$$printf
#define SUPER_SPRINTF $Super$$sprintf
#define SUB_SPRINTF $Sub$$sprintf
#define SUPER_SNPRINTF $Super$$snprintf
#define SUB_SNPRINTF $Sub$$snprintf
#define SUPER_VPRINTF $Super$$vprintf
#define SUB_VPRINTF $Sub$$vprintf
#define SUPER_VSPRINTF $Super$$vsprintf
#define SUB_VSPRINTF $Sub$$vsprintf
#define SUPER_VSNPRINTF $Super$$vsnprintf
#define SUB_VSNPRINTF $Sub$$vsnprintf
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
#define SUB_FPRINTF $Sub$$fprintf
#define SUB_VFPRINTF $Sub$$vfprintf
#endif
#elif defined(__ICCARM__)
#define SUPER_PRINTF $Super$$__iar_printf
#define SUB_PRINTF $Sub$$__iar_printf
#define SUPER_SPRINTF $Super$$__iar_sprintf
#define SUB_SPRINTF $Sub$$__iar_sprintf
#define SUPER_SNPRINTF $Super$$__iar_snprintf
#define SUB_SNPRINTF $Sub$$__iar_snprintf
#define SUPER_VPRINTF $Super$$__iar_vprintf
#define SUB_VPRINTF $Sub$$__iar_vprintf
#define SUPER_VSPRINTF $Super$$__iar_vsprintf
#define SUB_VSPRINTF $Sub$$__iar_vsprintf
#define SUPER_VSNPRINTF $Super$$__iar_vsnprintf
#define SUB_VSNPRINTF $Sub$$__iar_vsnprintf
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
#define SUB_FPRINTF $Sub$$fprintf
#define SUB_VFPRINTF $Sub$$vfprintf
#endif
#endif
int SUB_PRINTF(const char *format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int SUB_SPRINTF(char* buffer, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
va_end(arguments);
return result;
}
int SUB_SNPRINTF(char* buffer, size_t length, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
va_end(arguments);
return result;
}
int SUB_VPRINTF(const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
}
int SUB_VSPRINTF(char* buffer, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
}
int SUB_VSNPRINTF(char* buffer, size_t length, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
}
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
int SUB_FPRINTF(FILE* stream, const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
va_end(arguments);
return result;
}
int SUB_VFPRINTF(FILE* stream, const char* format, va_list arguments)
{
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
}
#endif

View File

@ -0,0 +1,64 @@
{
"GCC_ARM": {
"common": ["-c", "-Wall", "-Wextra",
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
"-MMD", "-fno-delete-null-pointer-checks",
"-fomit-frame-pointer", "-O0", "-g3", "-DMBED_DEBUG",
"-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": ["-x", "assembler-with-cpp"],
"c": ["-std=gnu99"],
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r",
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
"-Wl,-n",
"-Wl,--wrap,printf", "-Wl,--wrap,sprintf", "-Wl,--wrap,snprintf",
"-Wl,--wrap,vprintf", "-Wl,--wrap,vsprintf", "-Wl,--wrap,vsnprintf",
"-Wl,--wrap,fprintf", "-Wl,--wrap,vfprintf"]
},
"ARMC6": {
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-g", "-O1",
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions",
"-DMULADDC_CANNOT_USE_R7", "-fdata-sections",
"-fno-exceptions", "-MMD", "-D_LIBCPP_EXTERN_TEMPLATE(...)=",
"-fshort-enums", "-fshort-wchar", "-DMBED_DEBUG",
"-DMBED_TRAP_ERRORS_ENABLED=1", "--ide=mbed"],
"asm": ["--ide=mbed"],
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
"cxx": ["-fno-rtti", "-std=gnu++98"],
"ld": ["--verbose", "--remove", "--show_full_path", "--legacyalign", "--keep=os_cb_sections"]
},
"ARM": {
"common": ["-c", "--gnu", "-Otime", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O0", "-g", "-DMBED_DEBUG",
"-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--show_full_path", "--keep=os_cb_sections"]
},
"uARM": {
"common": ["-c", "--gnu", "-Otime", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O0", "-D__MICROLIB", "-g",
"--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DMBED_DEBUG",
"-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--library_type=microlib"]
},
"IAR": {
"common": [
"--no_wrap_diagnostics", "-e",
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r", "-DMBED_DEBUG",
"-DMBED_TRAP_ERRORS_ENABLED=1", "--enable_restrict"],
"asm": [],
"c": ["--vla", "--diag_suppress=Pe546"],
"cxx": ["--guard_calls", "--no_static_destruction"],
"ld": ["--skip_dynamic_initialization", "--threaded_lib"]
}
}

View File

@ -0,0 +1,61 @@
{
"GCC_ARM": {
"common": ["-c", "-Wall", "-Wextra",
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
"-MMD", "-fno-delete-null-pointer-checks",
"-fomit-frame-pointer", "-Os", "-g1", "-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": ["-x", "assembler-with-cpp"],
"c": ["-std=gnu99"],
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r",
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
"-Wl,-n",
"-Wl,--wrap,printf", "-Wl,--wrap,sprintf", "-Wl,--wrap,snprintf",
"-Wl,--wrap,vprintf", "-Wl,--wrap,vsprintf", "-Wl,--wrap,vsnprintf",
"-Wl,--wrap,fprintf", "-Wl,--wrap,vfprintf"]
},
"ARMC6": {
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Os",
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions",
"-DMULADDC_CANNOT_USE_R7", "-fdata-sections",
"-fno-exceptions", "-MMD", "-D_LIBCPP_EXTERN_TEMPLATE(...)=",
"-fshort-enums", "-fshort-wchar", "-DMBED_TRAP_ERRORS_ENABLED=1", "--ide=mbed"],
"asm": ["--ide=mbed"],
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
"cxx": ["-fno-rtti", "-std=gnu++98"],
"ld": ["--show_full_path", "--legacyalign", "--keep=os_cb_sections"]
},
"ARM": {
"common": ["-c", "--gnu", "-Otime", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O3", "-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--show_full_path", "--keep=os_cb_sections"]
},
"uARM": {
"common": ["-c", "--gnu", "-Otime", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O3", "-D__MICROLIB",
"--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD",
"-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--library_type=microlib"]
},
"IAR": {
"common": [
"--no_wrap_diagnostics", "-e",
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh", "--enable_restrict",
"-DMBED_TRAP_ERRORS_ENABLED=1"],
"asm": [],
"c": ["--vla", "--diag_suppress=Pe546"],
"cxx": ["--guard_calls", "--no_static_destruction"],
"ld": ["--skip_dynamic_initialization", "--threaded_lib"]
}
}

View File

@ -0,0 +1,59 @@
{
"GCC_ARM": {
"common": ["-c", "-Wall", "-Wextra",
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
"-MMD", "-fno-delete-null-pointer-checks",
"-fomit-frame-pointer", "-Os", "-DNDEBUG", "-g1"],
"asm": ["-x", "assembler-with-cpp"],
"c": ["-std=gnu99"],
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r",
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
"-Wl,-n",
"-Wl,--wrap,printf", "-Wl,--wrap,sprintf", "-Wl,--wrap,snprintf",
"-Wl,--wrap,vprintf", "-Wl,--wrap,vsprintf", "-Wl,--wrap,vsnprintf",
"-Wl,--wrap,fprintf", "-Wl,--wrap,vfprintf"]
},
"ARMC6": {
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz",
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions",
"-DMULADDC_CANNOT_USE_R7", "-fdata-sections",
"-fno-exceptions", "-MMD", "-D_LIBCPP_EXTERN_TEMPLATE(...)=",
"-fshort-enums", "-fshort-wchar", "-DNDEBUG", "--ide=mbed"],
"asm": ["--ide=mbed"],
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
"cxx": ["-fno-rtti", "-std=gnu++98"],
"ld": ["--show_full_path", "--legacyalign"]
},
"ARM": {
"common": ["-c", "--gnu", "-Ospace", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O3", "-DNDEBUG"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--show_full_path", "--keep=os_cb_sections"]
},
"uARM": {
"common": ["-c", "--gnu", "-Ospace", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O3", "-D__MICROLIB",
"--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DNDEBUG"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": ["--library_type=microlib"]
},
"IAR": {
"common": [
"--no_wrap_diagnostics", "-e",
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz", "-DNDEBUG", "--enable_restrict"],
"asm": [],
"c": ["--vla", "--diag_suppress=Pe546"],
"cxx": ["--guard_calls", "--no_static_destruction"],
"ld": ["--skip_dynamic_initialization", "--threaded_lib"]
}
}