diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml index 24b76ee..b6320f5 100644 --- a/.github/workflows/check-format.yml +++ b/.github/workflows/check-format.yml @@ -48,7 +48,7 @@ jobs: - name: Build picolibc container if: steps.cache.outputs.cache-hit != 'true' - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: platforms: linux/amd64 file: .github/Dockerfile-check-format diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml new file mode 100644 index 0000000..c61898c --- /dev/null +++ b/.github/workflows/license-check.yml @@ -0,0 +1,73 @@ +name: License Check + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + scancode: + name: Scancode License Scan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.12" + + - name: Install scancode-toolkit + run: pip install 'scancode-toolkit==32.3.0' + + - name: Scan licenses + run: | + scancode \ + --license \ + --license-policy license-policy.yml \ + --only-findings \ + --processes "$(nproc)" \ + --json-pp scancode-results.json \ + --ignore ".git/*" \ + --ignore ".github/*" \ + --ignore "scripts/import-upstream.sh" \ + --ignore "COPYLEFT_EXCLUSIONS" \ + --ignore "COPYING.picolibc" \ + --ignore "find-copyright" \ + --ignore "README.md" \ + --ignore "README.upstream.md" \ + . + + - name: Check for forbidden licenses + run: | + jq -r ' + [.files[] | select(.license_policy[]?.policy == "forbidden")] + | if length > 0 then + "Forbidden licenses found:", + (.[] | " \(.path): \(.detected_license_expression_spdx)"), + halt_error(1) + else + "No forbidden licenses found." + end + ' scancode-results.json + + - name: Upload scancode results + if: always() + uses: actions/upload-artifact@v7 + with: + name: scancode-results + path: scancode-results.json + + exclusions-check: + name: COPYLEFT_EXCLUSIONS Consistency + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Verify excluded paths do not exist + run: | + awk '!/^#/ && NF { if (system("test ! -e " $0)) { print "ERROR: Excluded file found: " $0; exit 1 } }' COPYLEFT_EXCLUSIONS + echo "All excluded paths are absent from the tree." diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 35d7d1f..9f02c31 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -45,7 +45,7 @@ jobs: - name: Build picolibc container if: steps.cache.outputs.cache-hit != 'true' - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: platforms: linux/amd64 file: .github/Dockerfile diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 10c7ce9..8ec1ee9 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -45,7 +45,7 @@ jobs: - name: Build picolibc container if: steps.cache.outputs.cache-hit != 'true' - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: platforms: linux/amd64 file: .github/Dockerfile diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml new file mode 100644 index 0000000..2600ae8 --- /dev/null +++ b/.github/workflows/tag-release.yml @@ -0,0 +1,27 @@ +name: Tag Release + +on: + pull_request: + types: [closed] + branches: [main] + +permissions: + contents: write + +jobs: + tag: + name: Create version tag + if: github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'update-upstream-') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Create tag + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + version="${GITHUB_HEAD_REF#update-upstream-}" + tag="${version}-bsd" + echo "Creating tag: $tag" + gh release create "$tag" --title "picolibc ${version} (BSD)" --notes "Based on upstream picolibc ${version}" diff --git a/.github/workflows/update-upstream.yml b/.github/workflows/update-upstream.yml new file mode 100644 index 0000000..c603b35 --- /dev/null +++ b/.github/workflows/update-upstream.yml @@ -0,0 +1,86 @@ +name: Update from Upstream + +on: + workflow_dispatch: + inputs: + to_ref: + description: "Upstream version tag to import up to, e.g., 1.9.0" + required: true + type: string + +permissions: + contents: write + pull-requests: write + +jobs: + update: + name: Import Upstream Commits + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Import upstream commits + id: import + run: | + # Auto-detect from_ref: find latest *-bsd tag, strip suffix to get upstream ref + from=$(git tag -l '*-bsd' --sort=-v:refname | head -1 | sed 's/-bsd$//') + if [ -z "$from" ]; then + echo "No *-bsd tags found. Tag the initial import first (e.g., git tag 1.8.11-bsd)." >&2 + exit 1 + fi + target="${{ inputs.to_ref }}" + + branch="update-upstream-${target}" + git branch -D "$branch" 2>/dev/null || true + git push origin --delete "$branch" 2>/dev/null || true + git checkout -b "$branch" + + scripts/import-upstream.sh "$from" "$target" 2>&1 | tee import-log.txt + + imported=$(grep -oP 'Imported: \K[0-9]+' import-log.txt || echo "0") + echo "imported=$imported" >> "$GITHUB_OUTPUT" + echo "branch=$branch" >> "$GITHUB_OUTPUT" + echo "from=$from" >> "$GITHUB_OUTPUT" + + - name: Create or update PR + if: steps.import.outputs.imported != '0' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET: ${{ inputs.to_ref }} + BRANCH: ${{ steps.import.outputs.branch }} + FROM: ${{ steps.import.outputs.from }} + run: | + git push origin "$BRANCH" + + # Generate PR body + cat > pr-body.md </dev/null || true) + if [[ -n "$existing_pr" ]]; then + gh pr edit "$existing_pr" --title "Update from upstream picolibc ${TARGET}" --body-file pr-body.md + else + gh pr create --base main --head "$BRANCH" --title "Update from upstream picolibc ${TARGET}" --body-file pr-body.md + fi diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml index 1972f23..09ebaef 100644 --- a/.github/workflows/zephyr.yml +++ b/.github/workflows/zephyr.yml @@ -45,7 +45,7 @@ jobs: - name: Build picolibc container if: steps.cache.outputs.cache-hit != 'true' - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: platforms: linux/amd64 file: .github/Dockerfile-zephyr diff --git a/COPYLEFT_EXCLUSIONS b/COPYLEFT_EXCLUSIONS new file mode 100644 index 0000000..c99a458 --- /dev/null +++ b/COPYLEFT_EXCLUSIONS @@ -0,0 +1,15 @@ +# Copyleft Exclusions +# +# Files excluded from this fork because they are under copyleft licenses. +# Used by scripts/import-upstream.sh and CI license checks. +# One path per line. Lines starting with # are comments. + +# GPL-2.0-or-later: Printf test suite by Bart Massey +test/test-stdio/test-printf.c +test/test-stdio/test-printf-testcases.h + +# AGPL-3.0-or-later: Meson cross-file generator script +scripts/GeneratePicolibcCrossFile.sh + +# GPL-2.0-only: GPL license text file +COPYING.GPL2 diff --git a/README.md b/README.md index d9f21b9..211f26f 100644 --- a/README.md +++ b/README.md @@ -1,1465 +1,74 @@ -# Picolibc -Copyright © 2018-2023 Keith Packard +# picolibc-bsd -Picolibc is library offering standard C library APIs that targets -small embedded systems with limited RAM. Picolibc was formed by blending -code from [Newlib](http://sourceware.org/newlib/) and -[AVR Libc](https://www.nongnu.org/avr-libc/). +A redistribution of [picolibc](https://github.com/picolibc/picolibc) with all copyleft-licensed +files removed. -Build status: +See the [upstream README](README.upstream.md) for picolibc documentation. - * [![Linux](https://github.com/picolibc/picolibc/actions/workflows/linux.yml/badge.svg)](https://github.com/picolibc/picolibc/actions/workflows/linux.yml) - * [![Zephyr](https://github.com/picolibc/picolibc/actions/workflows/zephyr.yml/badge.svg)](https://github.com/picolibc/picolibc/actions/workflows/zephyr.yml) - * [![Coreboot](https://github.com/picolibc/picolibc/actions/workflows/coreboot.yml/badge.svg?branch=main)](https://github.com/picolibc/picolibc/actions/workflows/coreboot.yml) +## Why this fork exists -## License - -Picolibc source comes from a variety of places and has a huge variety -of copyright holders and license texts. While much of the code comes -from Newlib, none of the GPL-related bits used to build the library -are left in the repository, so all of the source code uses BSD-like -licenses, a mixture of 2- and 3- clause BSD itself and a variety of -other (mostly older) licenses with similar terms. - -There are two files used for testing printf, test/printf-tests.c and -test/testcases.c which are licensed under the GPL version 2 or -later. There is also a shell script, GeneratePicolibcCrossFile.sh -which is licensed under the AGPL version 3 or later which is provided -as a helper for people building the library, but not used by picolibc -otherwise. - -The file COPYING.picolibc contains all of the current copyright and -license information in the Debian standard machine-readable format. It -was generated using the make-copyrights and find-copyright -scripts. - -## Supported Architectures - -Picolibc has integrated testing support for many architectures which -is used to validate the code for all patch integration: - - * ARC (32- and 64- bit) - * ARM (32- and 64- bit) - * i386 (Native and Linux hosted, for testing) - * LatticeMico32 - * LoongArch - * Motorola 68000 (m68k) - * MIPS - * MSP430 - * Nios II - * OpenRisc - * Power9 - * Renesas RX - * RISC-V (both 32- and 64- bit) - * SparcV8 (32 bit) - * SuperH - * x86_64 (Native and Linux hosted, for testing) - * Xtensa ESP32 - -There is also build infrastructure and continuous build validation, -but no integrated testing available for additional architectures: - - * Microblaze (32-bit, big and little endian) - * Sparc64 - * Xtensa (ESP8266, LX106) - -Supporting new architectures requires: - - 1. Add libc/machine/_architecture_ for architecture-specific libc - bits. This should at least include setjmp/longjmp support as these - cannot be performed in architecture independent code and are - needed by libstdc++. If available, it should also include thread - local storage setup code as libc/machine/_architecture_/tls.c; the - build system looks for that file by name when determining if TLS - is available. - - 2. Checking for atomic support for stdio. Picolibc requires - atomics for ungetc to work correctly in a reentrant - environment. By default, it stores them in 16-bit values, but - some architectures only have 32-bit atomics. To avoid ABI - issues, the size selected isn't detected automatically, instead - it must be configured in libc/include/stdio.h. - - 3. If necessary, add libm/machine/_architecture_ for any - architecture-specific math bits - - 4. picocrt/machine/_architecture_ source code and build bits - for startup code needed for the architecture. Useful in all - cases, but this is necessary to run tests under emulation if your - platform can do that. - - 5. cross-_gcc-triple_.txt to configure the meson cross-compilation - mechanism to use the right tools - - 6. do-_architecture_-configure to make testing the cross-compilation - setup easier. - - 7. run-_architecture_ script to run tests under QEMU. Look at the ARM - and RISC-V examples to get a sense of what this needs to do and - how it gets invoked from the cross-_gcc-triple_.txt configuration - file. - -## Relation to newlib - -Picolibc includes a lot of code originally from newlib. However, it -has been reformatted and restructured to make it easier to read and -maintain going forward. - -Here's a list of some differences between picolibc and newlib: - - 1. Designed for and tested on 32- and 64- bit embedded - systems. Newlib (and newlib-nano) are used on both embedded - systems and Cygwin, with the bulk of the development focused on - improving the Cygwin support. Because the Cygwin version needs to - be very careful about ABI stability, many parts of the newlib code - base are very difficult to change. Picolibc has no such - constraints, so much work has been done to improve the ABI and API - for use in embedded systems. - - 2. Stdio. Picolibc's stdio implementation borrows some code from - AVR-Libc along with substantial new code. The goal is to remain - compatible with relevant C and POSIX standards while using a very - narrow API to the underlying system (it only requires getc and - putc) along with doing no internal allocation and using a minimal - amount of RAM. - - 3. Thread-local-storage support. Instead of creating a large data - structure containing all possible thread-specific data, Picolibc - uses the underlying TLS support from the compiler which only - allocates the amount of per-thread storage needed to support the - API called by the application. Typically, this means you use only - 4 bytes for errno. - - 4. Integrated test suite. Along with dozens of new tests, picolibc - includes tests from newlib and musl. These tests are run as a part - of the patch review process and new code or bugfixes are expected - to include tests that verify functionality and keep bugs from - recurring. - - 5. Bare-metal startup code and linker scripts for many - architectures. These may not support precisely what your - application requires, but these provide a good basis for writing - your own startup code and linker scripts. These are used to create - bare-metal versions of the test suite which can then be run using - QEMU. - - 6. Meson-based build system. This is largely used to avoid conflicts - with the newlib autotools build system files, but a side effect is - that the library builds very quickly. - - 7. Narrow and well-defined POSIX OS requirements. Portions of - Picolibc which require underlying OS support are documented so - that you will know which functions are necessary based on the API - in use. In particular, picolibc requires no POSIX functions to - support stdin/stdout/stderr, and instead requires only functions - to get and put single characters to the target device. - - 8. Built-in semihosting support for many architectures. This allows - you to take advantage of existing gdb, openocd and qemu - semihosting support for things like debugging output even before - you have a serial port working. - - 9. Clear BSD licensing. All non-BSD compatible library source code - has been removed so that the status of the resulting library is - not in question. - -## Documentation - -Introductory documentation. Read these first: - - * [Building Picolibc](doc/build.md). Explains how to compile picolibc yourself. - * [Using Picolibc](doc/using.md). Shows how to compile and link - applications once you have picolibc built and installed. - * [Linking with Picolibc.ld](doc/linking.md). Provides more details - about the linking process. - * [Hello World](hello-world/README.md). Build and run a stand-alone C - application by following step-by-step instructions - -Detailed documentation. Use these to learn more details about how to -use Picolibc: - - * [Picolibc initialization](doc/init.md) - * [Operating System Support](doc/os.md). - * [Printf and Scanf in Picolibc](doc/printf.md) - * [Thread Local Storage](doc/tls.md) - * [Re-entrancy and Locking](doc/locking.md) - * [Selecting ctype implementation](doc/ctype.md) - * [Picolibc as embedded source](doc/embedsource.md) - * [Releasing Picolibc](doc/releasing.md) - * [Copyright and license information](COPYING.picolibc) - -## Releases - -### Picolibc release 1.8.11 - - * Use __math_inexact to generate FE_INEXACT in several math - functions. Thanks to Gergely Futo. - - * Support riscv '-mlarge' model in asm code. - - * Initialize riscv vector unit in startup code when present. - - * Improve arm32 A-profile operation in Thumb state. Thanks to Victor - Campos. - - * Remove duplicate isinf and isnan declarations that were visible - even when building with C++. Thanks to Mostafa Salman. - - * Improve accuracy of cacoshf for real inputs. Thanks to Ahmed - Shehab. - - * Avoid use of float types in vfprintf to avoid unnecessary fpu - register use. - - * Add missing pid_t and getdate_err declarations to time.h. - - * Implement getdate and getdate_r as required by POSIX. - - * Fix numerous minor bugs in strptime. - - * Test exception handling on m68k - - * Add Hexagon architecture support. Thanks to Kushal Pal. - - * Clean up RISC-V asm code integration. Thanks to Venkata Ramanaiah - Nalamothu. - - * Add more math tests, including exhaustive binary 32 testing. - - * Improve cbrtf precision to within 1ulp. - - * Fix lgammaf for values between -0x1p-70 and -0x1p-64. - - * Add some missing stdint.h bits that are new in C23. - - * Improve accuracy of erfcf for values between 1.25 and 28. Improve - performance for values between 0x1p-56 and 0x1p-26. - - * Fix memchr on targets with 16-bit int and 32-bit long (MSP430). - - * Mask needle with 0xff on rx version of memchr. - - * Add missing POSIX functionality in fnmatch to support character - classes, equivalence classes and collating sequences. Limit fnmatch - recursion for '*' operators to 16 levels. - - * Rename cross compile property 'libgcc' to 'librt' since we can now - specify either libgcc or compiler-rt as run-time library. However, - 'libgcc' is still supported for backward compatibility. - - * Fix bug in 32-bit riscv stpcpy which returned the wrong - value. Improve performance slightly by avoiding duplicate memory - reads of the tail of the string. - - * Make sure `__STDC_LIB_EXT1__` gets defined as appropriate. Thanks to - Mostafa Salman. - - * Fix -long_option parsing in getopt_long_only. - - * Add strfmon and strfmon_l as required by POSIX. - - * Add dprintf and vdprintf as required by POSIX. - - * Improve JIS transcoding performance by building translation tables - in both directions. - - * Fix a bunch of iconv bugs and improve POSIX conformance by - supporting //IGNORE, //DISCARD and //TRANSLIT modes. - - * Reformat code with clang-format - - * Restructure directories, moving libc and libm to the top level and - moving all tests under tests/. Remove stdio and malloc variants. - - * Add 'no-flash' crt0 variant, thanks to Kushal Pal. - - * Update minimum required meson version from 0.53 to 0.61. - - * Add -Dfstat-bufsiz option that uses fstat to select stdio buffer - sizes. Thanks to Alexey Lapshin. - - * Rewrite __rem_pio2f. This new version is faster than the old while - remaining API compatible and not using double datatypes. - - * Update libc/machine/riscv. Thanks to Yuriy Kolerov. - - * Fix the way the zicsr extension is enabled while building the crt0 - code. Thanks to Yuriy Kolerov. - - * Avoid linking in malloc when using bufio with static FILEs. - -### Picolibc release 1.8.10 - - * Add missing POSIX constants to limits.h. - - * Add Renesas RX support. Thanks to Duy Dguyen. - - * Update to Unicode 16.0. This matches glibc 2.41. - - * Add TLS support and testing on loongarch, m68k, or1k, powerpc and - superh. - - * Fix a couple of strncpy bugs in ARC assembly code. - - * Clean up preprocessor symbols: remove unused symbols, rename - picolibc.h symbols to use a __ prefix and not include PICOLIBC or - NEWLIB in the names. - - * Detect compiler attributes and builtins at compile time rather than - configure time where possible. Delete attributes and builtins not - used within the library implementation. - - * Remove non-standard elf.h and mstats API. - - * Clean up float predicates to make sure we provide implementations - of isinf, isnan and finite for all three types, both with and - without __ prefixes. Use symbol aliases to share the same function - implementation. Use the __ versions for the type generic macros - instead of fpclassify. Switch users of these within the math - library to use the type-generic versions. - - * Start SuperH FPU in single mode when required. - - * Test sh1 and sh2 targets using the binutils simulator. - - * Initialize PowerPC IPLT table at startup. - - * Switch printf/scanf aliases to prefer --printf=/--scanf= compiler - options - - * Control UCS-2 and UCS-4 locales with mb-ucs-charsets configuration - option. - - * Add stdio-locking option to provide full POSIX re-entrancy support - in tinystdio. Thanks to Alexey Lapshin. - - * Add wcsto* string to number functions using tinystdio conversion - code. Avoids malloc call for float conversions. - - * Add TLS API support for x86 targets. Thanks to TK Chia. - - * Add -fsanitize=undefined handlers and make library build with that - enabled. - -### Picolibc release 1.8.9 - - * Use common clang/gcc feature detection macros on arm. - - * Additional clang/compiler-rt work-arounds for arm which is less - consistent in handling exceptions. - - * Use clang multilib support for aarch64 - - * Build fix on arc which would build two strchr versions in release - mode. - - * Add picocrt and semihost support for xtensa. Test xtensa dc233c. - - * Add C11's header and implementation. - - * Add nano-malloc-clear-freed option to erase memory released in free - or realloc. - - * Add memset_explicit from C23. - - * Work around broken clang builtin malloc which fails to set errno. - - * Widen C++ _CTYPE_DATA array to fix mis-classification of \t; C++ - requires bitmasks for all ctype operations, and 8 bits is not - enough. Thanks to M-Moawad. - - * Update case conversion tables to Unicode 15.1.0 - - * Fix documentation formatting. Thanks to Eduard Tanase. - - * Fix support for using long-long vfprintf version by default. Thanks - to Louis Peens. - - * Remove arm unaligned memcpy asm code. This couldn't support targets - that only supported unaligned access. Use a new faster C version - for this case. - - * Add asnprintf and vasnprintf as provided by newlib - - * Support ARM's FVP emulator. Thanks to Oliver Stannard. - - * Remove arc strlen asm code as it would access memory *before* the - provided buffer and fall afoul of the stack bounds checking - hardware. - - * Support --printf={d,f,l,i,m} in place of - -DPICOLIBC_*_PRINTF_SCANF. This is the syntax proposed in the - patches submitted to gcc for picolibc support. - - * Add LoongArch support, including testing. Thanks to Jiaxun Yang. - - * Use new picolibc-ci-tools project which builds custom toolchain - bits automatically. Thanks to Jiaxun Yang. - - * Add OpenRisc support, including testing. Thanks to Joel Holdsworth. - - * Add Lattic3Mico32 support, including testing. Thanks to Jiaxun Yang. - - * Add MIPS semihosting support. Thanks to Jiaxun Yang. - - * Add older GCC compiler support, including versions < 4.4. Thanks to - Joel Holdsworth. - - * Add coreboot configurations and tests. Thanks to Jeremy Bettis and - Jon Murphy. - - * Fix numerous charset conversion errors for non-Unicode locales. - - * Make sure malloc return is aligned by using max_align_t. Thanks to - Alex Richardson. - - * Replace iconv and locale implementations with smaller code offering - the same locale functionality as before while the iconv code shares - the same charset support as the locale code instead of having a - completely separate implementation. - -### Picolibc release 1.8.8 - - * Fixed 3 bugs in the powf computation. Thanks to Fabian Schriever. - - * Fixed a bunch of build issues found by Zephyr. - - * Improve C++ testing and compatibility. - -### Picolibc release 1.8.7 - - * Support ARM v8.1-m BTI and PAC features - - * Fix stdio buffered backend automatic flushing of stdout when - reading stdin. - - * Support _FORTIFY_SOURCE=3 - - * Fix several fesetround implementations to return an error when - passed an invalid argument. Thanks to Abdallah Abdelhafeez. - - * Document headers which the compiler must provide. Thanks to Alexey - Brodkin. - - * Generate mktemp/tmpnam filenames using random() so they don't - repeat even if they aren't used before another name is generated. - - * Set error flag when fgetc is called on an file without read - mode. Thanks to Mohamed Moawad. - - * Add type casting to CMPLX, CMPLXF and CMPLXL macros (as glibc - does). Thanks to Mostafa Salman. - - * Add mips64 support and build the library during CI. - - * Make fgets return any accumulated string on EOF instead of - always returning NULL. Thanks to Hana Ashour. - - * Use C99 minimum array size in asctime_r and ctime_r API - declarations ('[static 26]'). Bounds check the generated value and - return NULL/EOVERFLOW on overflow. - - * Make Zephyr's -Oz cmake option enable - PREFER_SIZE_OVER_SPEED. Thanks to Jonathon Penix. - - * Add funopen to tinystdio. - - * Validate all public headers with a C++ compiler to make sure they - at least compile successfully. Fix time.h. - - * Stop using -include picolibc.h during library build. - - * Add -Wmissing-declarations and -Wmissing-prototypes to library - build flags. Fix a rather large pile of missing prototypes caused - by source files failing to add _GNU_SOURCE or _DEFAULT_SOURCE - definitions. - - * Add POSIX "unlocked" I/O functions to tinystdio. These don't - actually do anything because tinystdio doesn't do any - locking. However, flockfile/funlockfile grab the global C library - lock so applications synchronizing with that API will "work". - - * Fix wide orientation handling in tinystdio. Thanks to Ahmed Shehab. - - * Add aarch64 soft float support for armv8. Clang allows this with - -march=armv8-a+nofp -mabi=aapcs-soft. This required building a - custom toolchain that included a compiler-rt library built with the - right options. - - * Add fgetpos and fsetpos to tinystdio. Thanks to Hana Ashour. - - * Restore missing members of 'struct sigevent'. Over eager removal of - _POSIX_THREADS support caused these to be accidentally deleted some - time ago. - - * Test on i386 native target. - - * Fix hex float scanning and printing. Thanks to Hana Ashour and - Ahmed Shehab. - - * Fix double rounding in %f printf. Thanks to Ahmed Shehab for - constructing a test case that identified the issue. - - * Add mem_align to the "big" malloc version. Thanks to Simon Tatham. - - * Adjust POSIX and C headers to limit symbol exposure to that - specified in the standards. - - * Fix rounding in float scanf. This does round twice for input longer - than the required number of digits, but that's permitted by the C - specification. - - * Support %a/%A in scanf. Support arbitrary precision in %a/%A - printf. Fix NaN/INF formatting in %a/%A printf. Thanks to Ahmed - Shehab. - - * Provide a build-time option to enable %n in printf. This is - disabled by default for security concerns, but supported in case - someone needs strict C conformance. Thanks to Ahmed Shehab. - - * Make freopen clear the unget buffer. Thanks to Mostafa Salman. - - * Fix wide and multi-byte character support in printf and scanf. For - strict standards conformance, there's now an option that enables - %lc/%ls in printf even if multi-byte support is not enabled. - - * Enable MMU in picocrt on A profile ARM and AARCH64 targets when - present. This is required by the latest qemu which now more - accurately emulates this hardware. Thanks to Alex Richardson. - - * Fix AARCH64 asm code in ILP32 mode. - - * Parse NaN() in sscanf. This is required by the standard, - although picolibc doesn't do anything with . Thanks to - Mohamed Moawad. - - * Clean up header files. Picolibc tries to limit symbol definitions - to those specified in the C and POSIX specs. - - * Add support for C's Annex K functions. These are bounds-checking - versions of various memory and string functions. Thanks to Mostafa - Salman. - - * Perform locale string validation in newlocale even when _MB_CAPABLE - isn't defined. Thanks to Mostafa Salman. - - * Place compiler-rt library after C library when linking - tests. Thanks to Oliver Stannard. - -### Picolibc version 1.8.6 - - * Fix some FORTITY_SOURCE issues with tinystdio - - * Add __eh_* symbols to picolibc.ld for LLVM libunwind. Thanks Alex - Richardson. - - * Merge in newlib annual release (4.4.0). Some minor updates to - aarch64 assembly code formatting (thanks to Sebastian Huber) and a - few other fixes. - - * Enable 32-bit SPARC for testing. - - * Fix a bunch of fmemopen bugs and add some tests. Thanks to Alex - Richardson. - - * Finish support for targets with unusual float types, mapping - target types to 32-, 64-, 80- and 128- bit picolibc code. - - * Add SuperH support, including testing infrastructure. Thanks to - Adrian Siekierka for help with this. - - * Improve debugger stack trace in risc-v exception code. Thanks to - Alex Richardson. - - * Add an option (-Dfast-bufio=true) for more efficient fread/fwrite - implementations when layered atop bufio. Thanks for the suggestion - from Zachary Yedidia. - - * Fix cmake usage of FORMAT_ variables (note the lack of a leading - underscore). - - * Remove explicit _POSIX_C_SOURCE definition in zephyr/zephr.cmake. - - * Clean up public inline functions to share a common mechanism for - using gnu_inline semantics. Fix isblank. This ensures that no - static inline declarations exist in public API headers which are - required to be external linkage ("real") symbols. - - * Create an alternate ctype implementation that avoids using the - _ctype_ array and just does direct value comparisons. This only - works when picolibc is limited to ASCII. Applications can select - whether they want this behavior at application compilation time - without needing to rebuild the C library. Thanks to P. Frost for - the suggestion. - - * Unify most fenv implementations to use gnu_inline instead of - regular functions to improve performance. x86 was left out because - those fenv functions are complicated by the mix of 8087 and modern - FPU support. - - * Add a separate FILE for stderr when using POSIX I/O. Split - stdin/stdout/stderr into three files to avoid pulling in - those which aren't used. Thanks to Zachary Yedidia. - -### Picolibc version 1.8.5 - - * Detect clang multi-lib support correctly by passing compiler flags. - Thanks to xbjfk for identifying the problem. - - * Create a new 'long-long' printf variant. This provides enough - variety to satisfy the Zephyr cbprintf options without needing to - build the library from scratch. - - * Adjust use of custom binary to decimal conversion code so that it - is only enabled for types beyond the register size of the - target. This avoids the cost of this code when the application is - already likely to be using the soft division routines. - -### Picolibc version 1.8.4 - - * Make math overflow and underflow handlers respect rounding modes. - - * Add full precision fma/fmaf fallbacks by adapting the long-double - code which uses two floats/doubles and some careful exponent - management to ensure that only a single rounding operation occurs. - - * Fix more m68k 80-bit float bugs - - * Fix m68k asm ABI by returning pointers in %a0 and %d0 - - * Use an m68k-unknown-elf toolchain for m68k testing, including - multi-lib to check various FPU configurations on older and more - modern 68k targets. - - * Improve CI speed by using ccache on zephyr and mac tests, - compressing the docker images and automatically canceling jobs when - the related PR is updated. Thanks to Peter Jonsson. - - * Move a bunch of read-only data out of RAM and into flash by adding - 'const' attributes in various places. - - * Add a new linker symbol, `__heap_size_min`, which specifies a - minimum heap size. The linker will emit an error if this much space - is not available between the end of static data and the stack. - - * Fix a bunch of bugs on targets with 16-bit int type. Thanks to - Peter Jonsson for many of these. - - * Work around a handful of platform bugs on MSP430. I think these are - compiler bugs as they occur using both the binutils simulator and - mspsim. - - * Run tests on MSP430 using the simulator that comes with gdb. Thanks to - Peter Jonsson for spliting tests apart to make them small enough to - link in under 1MB. This requires a patch adding primitive - semihosting to the simulator. - - * Provide a division-free binary to decimal conversion option for - printf at friends. This is useful on targets without hardware - divide as it avoids pulling in a (usually large) software - implementation. This is controlled with the 'printf-small-ultoa' - meson option and is 'false' by default. - - * Add 'minimal' printf and scanf variants. These reduce functionality - by removing code that acts on most data modifers including width - and precision fields and alternate presentation modes. A new config - variable, minimal-io-long-long, controls whether that code supports - long long types. - - * Add a 'assert-verbose' option which controls whether the assert - macro is chatty by default. It is 'true' by default, which - preserves the existing code, but when set to 'false', then a - failing assert calls __assert_no_msg with no arguments, saving the - memory usually occupied by the filename, function name and - expression. - - * Fix arm asm syntax for mrc/mcr instructions to make clang happy. - Thanks to Radovan Blažek for this patch. - -### Picolibc version 1.8.3 - - * Fix bugs in floor and ceil implementations. - - * Use -fanalyzer to find and fix a range of issues. - - * Add __ubsan_handle_out_of_bounds implementation. This enables - building applications with -fsanitize=bounds and - -fno-sanitize-undefined-trap-on-error. - - * Validate exception configuration on targets with mixed exception - support where some types have exceptions and others don't. Right - now, that's only arm platforms where any soft float implementations - don't build with exception support. - - * Fix bugs in nexttowards/nextafter on clang caused by the compiler - re-ordering code and causing incorrect exception generation. - - * Use the small/slow string code when -fsanitize=address is used - while building the library. This avoids reading beyond the end of - strings and triggering faults. - - * Handle soft float on x86 and sparc targets. That mostly required - disabling the hardware exception API, along with a few other minor - bug fixes. - - * Add runtime support for arc, mips, nios2 and m68k. This enables CI - testing on these architectures using qemu. - - * Fix 80-bit floating math library support for m68k targets. - - * Fix arm testing infra to use various qemu models that expand - testing to all standard multi-lib configurations. - - * Adjust floating exception stubs to return success when appropriate, - instead of always returning ENOSYS. - - * Make sure sNaN raises FE_INVALID and is converted to qNaN in - truncl, frexpl and roundl - - * Avoid NaN result from fmal caused by multiply overflow when - addend is infinity (-inf + inf results in NaN in that case). - -### Picolibc version 1.8.2 - - * Support _ZEPHYR_SOURCE macro which, like _POSIX_SOURCE et al, - controls whether the library expresses the Zephyr C library API. - This is also automatically selected when the __ZEPHYR__ macro is - defined and no other _*_SOURCE macro is defined. - - * Add another cross compile property, 'libgcc', which specifies the - library containing soft float and other compiler support routines. - - * Fix a couple of minor imprecisions in pow and 80-bit powl. - - * Merge newlib changes that included an update to the ARM assembly - code. - - * Replace inexact float/string conversion code with smaller code that - doesn't use floating point operations to save additional space on - soft float targets. - - * More cmake fixes, including making the inexact printf and locale - options work. - -### Picolibc version 1.8.1 +Picolibc is a lightweight C library for embedded systems. The core library sources are permissively +licensed (BSD-3-Clause and similar), but the upstream repository includes a small number of +copyleft-licensed files: - * Fix cmake build system to auto-detect compiler characteristics - instead of assuming the compiler is a recent version of GCC. This - allows building using cmake with clang. +- `test/` directory - GPLv2+ test suite files +- `scripts/GeneratePicolibcCrossFile.sh` - AGPLv3+ build helper +- `COPYING.GPL2` - GPL license text - * Fix cmake build system to leave out TLS support when TLS is - disabled on the cmake command line. +These files are not needed to build or use picolibc, but their presence in git history can +complicate license compliance for projects that vendor picolibc as a submodule or dependency. - * Replace inline asm with attributes for __weak_reference macro +This fork provides a clean tree containing only permissively-licensed files, suitable for embedding +without copyleft concerns. - * Add allocation attributes to malloc and stdio functions. This - allows the compiler to detect allocation related mistakes as well - as perform some additional optimizations. Bugs found by this change - were also addressed. +## History structure - * Add wchar_t support to tinystdio, eliminating the last missing - feature compared with the legacy stdio bits from newlib. With this, - libstdc++ can be built with wide char I/O support, eliminating the - last missing feature there as well. +The first commit in this repository is the unmodified upstream picolibc at the base version tag. The +second commit removes copyleft files and adds fork tooling. Future upstream updates are +cherry-picked one commit at a time with copyleft files filtered, preserving individual commit +granularity. - * Eliminate use of command line tools when building with a new enough - version of meson. Thanks to Michael Platings. +## Updating from upstream - * Add Microblaze support. Thanks to Alp Sayin. +Updates can be triggered manually via the +[Update from Upstream](.github/workflows/update-upstream.yml) GitHub Actions workflow, which takes +an upstream version tag (e.g., `1.9.0`) as input. The workflow: - * Switch semihosting to use binary mode when opening files. Thanks to - Hardy Griech. +1. Detects the current base version from the latest `*-bsd` tag +2. Runs `scripts/import-upstream.sh` to cherry-pick upstream commits with copyleft files filtered + out +3. Opens a PR for review +4. On merge, a `-bsd` tag and GitHub release are created automatically - * Build and install static library versions of the crt0 startup - code. These allows developers to reference them as libraries on the - command line instead of needing special compiler support to locate - the different variants, which is useful when using clang. Thanks to - Simon Tatham. +### Manual import - * Simplify the signal/raise implementation to use a single global - array of signal handlers and to not use getpid and kill, instead - raise now directly invokes _exit. This makes using assert and abort - simpler and doesn't cause a large TLS block to be allocated. Thanks - to Joe Nelson for discovering the use of a TLS variable here. +To import locally instead of using the workflow: -### Picolibc version 1.8 +```bash +scripts/import-upstream.sh +# e.g., scripts/import-upstream.sh 1.8.11 1.9.0 +``` -With the addition of nearly complete long double support in the math -library, it seems like it's time to declare a larger version increment -than usual. +After importing, tag the result and push: - * Improve arc and xtensa support, adding TLS helpers and other build fixes +```bash +git tag -bsd +git push origin main --tags +``` - * Fix FPSCR state for Arm8.1-M low overhead loops (thanks to David - Green) +## License scanning - * Add -Werror=double-promotion to default error set and fix related - errors. (thanks to Ryan McClelland) +This repository uses [scancode-toolkit](https://github.com/aboutcode-org/scancode-toolkit) in CI to +verify that no copyleft-licensed files are present. See `.github/workflows/license-check.yml`. - * Fix locking bug in malloc out-of-memory path and freeing a locked - mutex in the tinystdio bufio code. These were found with lock - debugging code in Zephyr. - - * Add some missing functions in tinystdio, strto*l_l, remove, - tmpname/tmpfile which were published in stdio.h but not included in - the library. - - * Switch read/write functions to use POSIX types instead of legacy - cygwin types. This makes mapping to existing an POSIX api work - right. - - * Add %b support to tinystdio printf and scanf. These are disabled by - default as they aren't yet standardized. - - * Fix avr math function support. The avr version of gcc has modes - where double and long double are 32 or 64 bits, so the math library - code now detects all of that at compile time rather than build time - and reconfigures the functions to match the compiler types. - - * Add nearly complete long double support from openlibm for 80-bit - Intel and 128-bit IEEE values (in addition to supporting 64-bit - long doubles). Still missing are Bessel functions and decimal - printf/scanf support. - - * Add limited long double support for IBM 'double double' form. This - is enough to run some simple tests, but doesn't have any - significant math functions yet. - - * Get Power9 code running under qemu with OPAL. This was mostly - needed to validate the big-endian and exception code for 128-bit - long doubles, but was also used to validate the double double - support. - - * Provide times() and sysconf() implementations in semihosting. You - can now build and run the dhrystone benchmark without any further - code. - - * Fix use of TLS variables with stricter alignment requirements in - the default linker script and startup code. (thanks to Joakim - Nohlgård and Alexander Richardson who found this issue while - working on lld support). - -### Picolibc version 1.7.9 - - * Support all Zephyr SDK targets - - * Support relocating the toolchain by using GCC_EXEC_PREFIX for - sysroot-install when compiler doesn't use sysroot. - - * Add MIPS, SPARC and ARC support - - * Deal with RISC-V changes in gcc that don't reliably include zicsr - - * Support Picolibc as default C library with -Dsystem-libc option. - With this, you can use picolibc without any extra compiler options. - - * Merge current newlib bits to get code that doesn't use struct _reent - - * Get rid of struct _reent in legacy stdio code - - * Support 16-bit int targets by fixing a few places assuming - sizeof(int) == 4, object sizes not using size_t, wint_t for - ucs-4 values - - * Add MSP430 support - - * Fix a couple of clang bugs (one on Cortex M0) - - * Support libc++ by adding non-standard mbstate_t.h - - * Merge i686 and x86_64 code to allow x86 multilib builds - - * Merge Xtensa newlib bits - - * Support Xtensa ESP32 targets - - * Add Nios II support - -### Picolibc version 1.7.8 - - 1. Fix el/ix level 4 code type errors - - 2. Fix out-of-source CMake build (thanks Max Behensky) - - 3. Improve build.md docs (thanks Kalle Raiskila) - - 4. Fix cmake build for various architectures - - 5. Initialize lock in fdopen - - 6. Remove %M from linker paths in single-arch builds - - 7. Shrink tinystdio vfprintf and vfscanf a bit - - 8. Use -fno-builtin-malloc -fno-builtin-free (GCC 12 compat) - - 9. Use -fno-builtin-copysignl (GCC 12 compat) - - 10. Add _zicsr to -march for risc-v picocrt (binutils 2.38 compat) - - 11. Add -no-warn-rwx-segments to link spec (binutils 2.38 compat) - -### Picolibc version 1.7.7 - - 1. Fix semihost gettimeofday, add a test. - - 2. Fix config option documentation. (Thanks to rdiez) - - 3. Document how re-entrant locking APIs are used. (Thanks to rdiez) - - 4. Fix some 16-bit int issues in tinystdio. (Thanks to Ayke van - Laethem) - - 5. Make header files a bit more POSIX compliant, installing rpc - headers, moving byte swapping macros to arpa/inet.h - - 6. Fix some stdio bugs found by Zephyr test suite: snprintf return - value on buffer overflow, add ftello/fseeko, fputc return value, - %0a formatting, clear EOF status after ungetc/fseek. - - 7. Re-do buffered I/O support to handle mixed read/write files - correctly. This adds setbuf, setbuffer, setlinebuf, setvbuf. - - 8. Add fmemopen and freopen. - - 9. Add enough cmake support to allow Zephyr to build picolibc as a - module using that, rather than meson. - - 10. Merge current newlib bits - - 11. Fix %p printf/scanf on ILP64 targets. - -### Picolibc version 1.7.6 - - 1. Fix use with C++ applications caused by a syntax error in - picolibc.specs - - 2. Automatically include '-nostdlib' to options used while - evaluating build rules to ensure tests work as expected. - - 3. Publish aarch64 inline math functions, ensure that inline fma - functions work in installed applications for arm and risc-v. - -### Picolibc version 1.7.5 - - 1. Fix build on big-endian systems (thanks to Thomas Daede) - - 2. Add m68k support (thanks to Thomas Daede). - - 3. Fix build issues with ARM Cortex-a9 target (thanks to Ilia - Sergachev). - - 4. Fix fwrite(x,0,y,z) in both tinystdio and legacy stdio. tinystdio - returned the wrong value and legacy stdio caused a divide-by-zero - fault. - - 5. Update Ryu code to match upstream (minor fixes) - - 6. Fix various __NEWLIB and __PICOLIBC macros; they were using a - single leading underscore instead of two (thanks to Vincent - Palatin). - - 7. Fix tinystdio error-handling bugs - - 8. Merge recent newlib changes (fixed ltdoa in legacy stdio) - - 9. Speed improvements for github CI system - - 10. Big-endian PowerPC support - - 11. Fail builds if most 'run_command' uses fail (thanks to Johan de - Claville Christiansen) - - 12. Positional parameters in tinystdio. With this, I think tinystdio - is feature complete. - - 13. Support for multiple build-styles of picolibc (minsize/release) - in one binary package. This still requires separate meson runs. - - 14. Testing with glibc test code. This uncovered numerous bugs, - mostly math errno/exception mistakes, but also a few serious - bugs, including a couple of places where the nano-malloc failed - to check for out-of-memory. Picolibc now passes all of the glibc - math tests except for jn, yn, lgamma and tgamma. The picolibc - versions of those functions are too inaccurate. Picolibc also - passes most other relevant glibc tests, including stdio, - string and stdlib areas. - - 15. Tinystdio version of fcvt now has a static buffer large enough to - hold the maximum return size. - - 16. Tinystdio versions of ecvtbuf and fcvtbuf have been replaced - with ecvt_r and fcvt_r equivalents, which take a 'len' parameter - to prevent buffer overruns. - - 17. Add the GeneratePicolibcCrossFile.sh script which provides a way - to isolate picolibc build scripts from the vagaries of meson - version shifts (thanks to R. Diez). - - 18. Add 'semihost' version of crt0 that calls 'exit' after main - returns. The ARM and RISC-V versions of this also include trap - handlers for exceptions that print out information and exit when - an exception occurs. - -### Picolibc version 1.7.4 - - 1. Clean up meson build bits, including use of 'fs module (thanks to - Yasushi Shoji). - - 2. Speed up github actions by sharing Debian docker image (thanks to - Yasushi Shoji). - - 3. Reduce use of intermediate static libraries during build - - 4. Use standard Meson architecture names everywhere (thanks to - Yasushi Shoji). - - 5. Support building with -D_FORTIFY_SOURCE enabled. - - 6. Clean up 32-bit arm assembly code, eliminating __aeabi wrappers - where possible. - - 7. Add basename, dirname and fnmatch back. - - 8. Fix all old-style (K&R) function definitions. - - 9. Enable lots more compiler warning flags. - - 10. Remove last uses of alloca in legacy stdio code. - - 11. Add tests from musl libc-testsuite. There aren't many tests, but - these identified a few bugs. - - 12. Add lots more exception and errno tests for the math functions. - - 13. Restructure math library to always use the `__math_err` functions - to raise exceptions and set errno. This removes the w_*.c wrapper - functions and eliminates the `__ieee names`. This centralizes - compiler work-arounds to ensure run-time evaluation of - expressions intended to raise exceptions. In the process, all of - the libm/math files were reformatted with clang-format. - - 14. Make tinystdio '%a' compatible with glibc, including supporting - rounding and trimming trailing zeros when possible. - - 15. Remove floating point exception generation code on targets - without floating point exception support. This reduces code size - on soft float machines without affecting results. - -### Picolibc version 1.7.3 - - 1. Add -Wall -Wextra to default builds. Fixed warnings this raised. - - 2. Add htonl and friends (based on __htonl). Thanks to Johan de - Claville Christiansen - - 3. Set errno in scalbn and scalbnf (patch forwarded to newlib). - - 4. Merge newlib recent changes which includes a couple of libm fixes. - -### Picolibc version 1.7.2 - - 1. Fix picolibc.ld to split C++ exceptions back apart (thanks to - Khalil Estell) - - 2. Add vsscanf to tinystdio (required for libstdc++). - - 3. Also stick -isystem in C++ compile command to try and get - picolibc headers to be used instead of newlib. - -### Picolibc version 1.7.1 - - 1. Add __cxa_atexit implementation to 'picoexit' path as required by - C++ - - 2. Fix lack of 'hh' support in integer-only tinystdio printf path. - - 3. Fix tinystdio __file flag initialization for C++ apps - -### Picolibc version 1.7 - - 1. Merge libc and libm into a single library. Having them split - doesn't offer any advantages while requiring that applications add - '-lm' to link successfully. Having them merged allows use of libm - calls from libc code. - - 2. Add hex float format to *printf, *scanf and strto{d,f,ld}. This is - required for C99 support. - - 3. Unify strto{d,f,ld} and *scanf floating point parsing code. This - ensures that the library is consistent in how floats are parsed. - - 4. Make strto{d,f,ld} set errno to ERANGE on overflow/underflow, - including when the result is a subnormal number. - -### Picolibc version 1.6.2 - - 1. Change `restrict` keyword in published headers to `__restrict` to - restore compatibility with applications building with --std=c18. - - 2. Additional cleanups in time conversion funcs (Thanks to R. Riez) - -### Picolibc version 1.6.1 - - 1. Code cleanups for time conversion funcs (Thanks to R. Diez) - - 2. Add '-fno-stack-protector' when supported by the C compiler - to avoid trouble building with native Ubuntu GCC. - - 3. Bug fix for converting denorms with sscanf and strto{d,f,ld}. - - 4. Use __asm__ for inline asm code to allow building applications - with --std=c18 - - 5. Fix exit code for semihosting 'abort' call to make it visible - to the hosting system. - - 6. Add strfromf and strfromd implementations. These are simple - wrappers around sscanf, but strfromf handles float conversions - without requiring a pass through 'double' or special linker hacks. - -### Picolibc version 1.6 - - 1. Bugfix for snprintf(buf, 0) and vsnprintf(buf, 0) to avoid - smashing memory - - 2. Support building libstdc++ on top of picolibc - - 3. Add 'hosted' crt0 variant that calls exit when main - returns. This makes testing easier without burdening embedded apps - with unused exit processing code. - - 4. Add 'minimal' crt0 variant that skips constructors to - save space on systems known to not use any. - - 5. Fix HW floating point initialization on 32-bit ARM processors to - perform 'dsb' and 'isb' instructions to ensure the FPU enabling - write is complete before executing any FPU instructions. - - 6. Create a new '--picolibc-prefix' GCC command line parameter that - sets the base of all picolibc file names. - - 7. Add bare-metal i386 and x86_64 initializatiton code (thanks to - Mike Haertel). These initalize the processor from power up to - running code without requiring any BIOS. - - 8. Merge newlib as of late April, 2021 - - 9. Add 'timegm' function (thanks to R. Diez). - -10. Fix a number of tinystdio bugs: handle fread with size==0, parse - 'NAN' and 'INF' in fscanf in a case-insensitive manner, fix - negative precision to '*' arguments in printf, fix handling of - 'j', 'z' and 't' argument size specifiers (thanks to Sebastian - Meyer). - -11. Make the fenv API more consistent and more conformant with the - spec. All architectures now fall back to the default code - for soft float versions, which avoids having the various exception - and rounding modes get defined when not supported. - -### Picolibc version 1.5.1 - - 1. Make riscv crt0 '_exit' symbol 'weak' to allow linking without - this function. - -### Picolibc version 1.5 - - 1. Make picolibc more compatible with C++ compilers. - - 2. Add GCC specs file and linker script for building C++ applications - with G++ that enable exception handling by linking in call stack - information. - - 3. A few clang build fixes, including libm exception generation - - 4. Nano malloc fixes, especially for 'unusual' arguments - - 5. Merge in newlib 4.1.0 code - - 6. More libm exception/errno/infinity fixes, mostly in the gamma funcs. - - 7. Add tests for all semihost v2.0 functions. - - 8. A few RISC-V assembly fixes and new libm code. - - 9. Build fixes to reliably replace generic code with - architecture-specific implementations. - -With a patch which is pending for GCC 11, we'll be able to build C++ -applications that use picolibc with exceptions and iostream. - -### Picolibc version 1.4.7 - - 1. Fix numerous libm exception and errno bugs. The math functions are - all now verified to match the C19 and Posix standards in this - area. - - 2. Change behavior of 'gamma' function to match glibc which returns - lgamma for this function. Applications should not use this - function, they should pick either lgamma or tgamma as appropriate. - - 3. Fix fma/fmaf on arm and RISC-V so that the machine-specific versions - are used when the hardware has support. Also fix the math library - to only use fma/fmaf when it is supported by the hardware. - - 4. Fix numerous nano-malloc bugs, especially with unusual parameters. - - 5. Change nano-malloc to always clear returned memory. - - 6. Improve nano-realloc to perform better in various ways, including - merging adjacent free blocks and expanding the heap. - - 7. Add malloc tests, both a basic functional test and a stress test. - - 8. Improve build portability to Windows. Picolibc should now build - using mingw. - - 9. Use hardware TLS register on ARM when available. - - 10. Support clang compiler. Thanks to Denis Feklushkin - and Joakim Nohlgård . - - 11. Avoid implicit float/double conversions. Check this by having - clang builds use -Wdouble-promotion -Werror=double-promotion - flags - - 12. Have portable code check for machine-specific overrides by - matching filenames. This avoids building libraries with - duplicate symbols and retains compatibility with newlib (which - uses a different mechanism for this effect). - - 13. Patches to support building with [CompCert](http://compcert.inria.fr/), a - formally verified compiler. Thanks to Sebastian Meyer - . - -### Picolibc version 1.4.6 - - 1. Install 'ssp' (stack smashing protection) header files. This fixes - compiling with -D_FORTIFY_SOURCE. - - 2. Make getc/ungetc re-entrant. This feature, which is enabled by - default, uses atomic instruction sequences that do not require - OS support. - - 3. Numerous iconv fixes, including enabling testing and switching - external CCS file loading to use stdio. By default, iconv provides - built-in CCS data for all of the supported encodings, which takes - a fairly large amount of read-only memory. Iconv is now always - included in picolibc as it isn't included in applications unless - explicitly referenced by them. - - 4. Add __getauxval stub implementation to make picolibc work with - GCC version 10 compiled for aarch64-linux-gnu. - - 5. Change how integer- and float- only versions of printf and scanf - are selected. Instead of re-defining the symbols using the C - preprocessor, picolibc now re-defines the symbols at link - time. This avoids having applications compiled with a mixture of - modes link in multiple versions of the underlying functions, while - still preserving the smallest possible integer-only - implementation. - - 6. Document how to use picolibc on a native POSIX system for - testing. Check out the [os.md](doc/os.md) file for details. - - 7. Merge current newlib bits in. This includes better fenv support, - for which tests are now included in the picolibc test suite. - -### Picolibc version 1.4.5 - - 1. Fix section order in picolibc.ld to give applications correct - control over the layout of .preserve, .init and .fini regions. - - 2. Add startup and TLS support for aarch64 and non Cortex-M 32-bit - arm. - -### Picolibc version 1.4.4 - - 1. Fix floating point 'g' format output in tinystdio. (e.g., - for 10.0, print '10' instead of '1e+01'). There are tests which - verify a range of 'g' cases like these now. - - 2. Merge current newlib bits. The only thing which affects picolibc - is the addition of fenv support for arm. - -### Picolibc version 1.4.3 - - 1. Make fix for CVE 2019-14871 - CVE 2019-14878 in original newlib - stdio code not call 'abort'. Allocation failures are now reported - back to the application. - - 2. Add 'exact' floating point print/scan code to tinystdio. Thanks - to Sreepathi Pai for pointing me at the Ryu code by Ulf - Adams. - - 3. Add regular expression functions from newlib. These were removed - by accident while removing POSIX filesystem-specific code. - - 4. Make tinystdio versions of [efg]cvt functions. This means that the - default tinystdio version of picolibc no longer calls malloc from - these functions. - - 5. More clang-compatibility fixes. (Thanks to Denis Feklushkin) - - 6. Remove stdatomic.h and tgmath.h. (they should not be provide by picolibc) - -### Picolibc version 1.4.2 - - 1. Clang source compatibility. Clang should now be able to compile - the library. Thanks to Denis Feklushkin for figuring out how - to make this work. - - 2. aarch64 support. This enables the existing aarch64 code and - provides an example configuration file for getting it - built. Thanks for Anthony Anderson for this feature. - - 3. Testing on github on push and pull-request. For now, this is - limited to building the library due to a bug in qemu. - - 4. Get newlib stdio working again. You can now usefully use Newlib's - stdio. This requires a working malloc and is substantially larger - than tinystdio, but has more accurate floating point input. This - requires POSIX functions including read, write and a few others. - - 5. Fix long double strtold. The working version is only available - when using tinystdio; if using newlib stdio, strtold is simply not - available. - - 6. Improve tinystdio support for C99 printf/scanf additions. - - 7. Check for correct prefix when sysroot-install option is - selected. The value of this option depends on how gcc was - configured, and (alas) meson won't let us set it at runtime, so - instead we complain if the wrong value was given and display the - correct value. - - 8. Sync up with current newlib head. - -### Picolibc version 1.4.1 - -This release contains an important TLS fix for ARM along with a few -minor compatibility fixes - - 1. Make __aeabi_read_tp respect ARM ABI register requirements to - avoid clobbering register contents during TLS variable use. - - 2. Use cpu_family instead of cpu in meson config, which is 'more - correct' when building for a single cpu instead of multilib. - - 3. Make arm sample interrupt vector work with clang - - 4. Use __inline instead of inline in published headers to allow - compiling with -ansi - - 5. Make 'naked' RISC-V _start function contain only asm - statements as required by clang (and recommended by gcc). - - 6. Use -msave-restore in sample RISC-V cross-compile - configuration. This saves text space. - -### Picolibc version 1.4 - -This release was focused on cleaning up the copyright and license -information. - - 1. Copyright information should now be present in every source file. - - 2. License information, where it could be inferred from the - repository, was added to many files. - - 3. 4-clause BSD licenses were changed (with permission) to 3-clause - - 4. Fix RISC-V ieeefp.h exception bits - - 5. Merge past newlib 3.2.0 - - 6. Add PICOLIBC_TLS preprocessor define when the library has TLS support - -### Picolibc version 1.3 - -This release now includes tests, and fixes bugs found by them. - - 1. ESP8266 support added, thanks to Jonathan McDowell. - - 2. Numerous test cases from newlib have been fixed, and - precision requirements adjusted so that the library now - passes its own test suite on x86, RISC-V and ARM. - - 3. String/number conversion bug fixes. This includes fcvt/ecvt/gcvt - shared with newlib and tinystdio printf/scanf - - 4. A few RISC-V ABI fixes, including setting the TLS base correctly, - compiling with -mcmodel=medany, and enabling the FPU for libraries - built to use it. - - 5. Semihosting updates, including adding unlink, kill and getpid - (which are used by some tests). - -### Picolibc version 1.2 - -This release includes important fixes in picolibc.ld and more -semihosting support. - - 1. File I/O and clock support for semihosting. This enables fopen/fdopen - support in tinystdio along with an API to fetch a real time clock - value. - - 2. Fix picolibc.ld to not attempt to use redefined symbols for memory - space definitions. These re-definitions would fail and the default - values be used for system memory definitions. Instead, just use - the ? : operators each place the values are needed. Linker scripts - continue to mystify. - - 3. Expose library definitions in 'picolibc.h', instead of 'newlib.h' - and '_newlib_version.h' - - 4. Define HAVE_SEMIHOST when semihosting support is available. This - lets the 'hello-world' example do some semihost specific things. - -### Picolibc version 1.1 - -A minor update from 1.0, this release includes: - - 1. semihost support. This adds console I/O and exit(3) support on ARM - and RISC-V hosts using the standard semihosting interfaces. - - 2. Posix I/O support in tinystdio. When -Dposix-io=true is included - in the meson command line (which is the default), tinystdio adds - support for fopen and fdopen by using malloc, open, close, read, - write and lseek. If -Dposix-console=true is also passed to meson, - then picolibc will direct stdin/stdout/stderr to the posix - standard file descriptors (0, 1, 2). - - 3. Merge recent upstream newlib code. This brings picolibc up to date - with current newlib sources. - - 4. Hello world example. This uses a simple Makefile to demonstrate - how to us picolibc when installed for ARM and RISC-V embedded - processors. The resulting executables can be run under qemu. - - 5. Remove libm/mathfp directory. This experimental code never - worked correctly anyways. - -### Picolibc version 1.0 - -This is the first release of picolibc. Major changes from newlib -include: - - 1. Remove all non-BSD licensed code. None of it was used in building - the embedded library, and removing it greatly simplifies the - license situation. - - 2. Move thread-local values to native TLS mechanism - - 3. Add smaller stdio from avr-libc, which is enabled by default +## License - 4. Switch build system to meson. This has two notable benefits; the first - is that building the library is much faster, the second is that - it isolates build system changes from newlib making merging of - newlib changes much easier. +All source code files in this repository are under permissive licenses (BSD-3-Clause, BSD-2-Clause, +MIT, ISC, and similar). The `COPYING.picolibc` file contains a license inventory that references +copyleft licenses for documentation purposes - those files have been removed from the tree. See +`COPYING.picolibc` for per-file license details. - 5. Add simple startup code. This can be used in environments that - don't have complicated requirements, allowing small applications - to avoid needing to figure this out. +## Attribution +picolibc is created and maintained by Keith Packard and contributors. See the +[upstream repository](https://github.com/picolibc/picolibc) for full contributor history. diff --git a/README.upstream.md b/README.upstream.md new file mode 100644 index 0000000..d9f21b9 --- /dev/null +++ b/README.upstream.md @@ -0,0 +1,1465 @@ +# Picolibc +Copyright © 2018-2023 Keith Packard + +Picolibc is library offering standard C library APIs that targets +small embedded systems with limited RAM. Picolibc was formed by blending +code from [Newlib](http://sourceware.org/newlib/) and +[AVR Libc](https://www.nongnu.org/avr-libc/). + +Build status: + + * [![Linux](https://github.com/picolibc/picolibc/actions/workflows/linux.yml/badge.svg)](https://github.com/picolibc/picolibc/actions/workflows/linux.yml) + * [![Zephyr](https://github.com/picolibc/picolibc/actions/workflows/zephyr.yml/badge.svg)](https://github.com/picolibc/picolibc/actions/workflows/zephyr.yml) + * [![Coreboot](https://github.com/picolibc/picolibc/actions/workflows/coreboot.yml/badge.svg?branch=main)](https://github.com/picolibc/picolibc/actions/workflows/coreboot.yml) + +## License + +Picolibc source comes from a variety of places and has a huge variety +of copyright holders and license texts. While much of the code comes +from Newlib, none of the GPL-related bits used to build the library +are left in the repository, so all of the source code uses BSD-like +licenses, a mixture of 2- and 3- clause BSD itself and a variety of +other (mostly older) licenses with similar terms. + +There are two files used for testing printf, test/printf-tests.c and +test/testcases.c which are licensed under the GPL version 2 or +later. There is also a shell script, GeneratePicolibcCrossFile.sh +which is licensed under the AGPL version 3 or later which is provided +as a helper for people building the library, but not used by picolibc +otherwise. + +The file COPYING.picolibc contains all of the current copyright and +license information in the Debian standard machine-readable format. It +was generated using the make-copyrights and find-copyright +scripts. + +## Supported Architectures + +Picolibc has integrated testing support for many architectures which +is used to validate the code for all patch integration: + + * ARC (32- and 64- bit) + * ARM (32- and 64- bit) + * i386 (Native and Linux hosted, for testing) + * LatticeMico32 + * LoongArch + * Motorola 68000 (m68k) + * MIPS + * MSP430 + * Nios II + * OpenRisc + * Power9 + * Renesas RX + * RISC-V (both 32- and 64- bit) + * SparcV8 (32 bit) + * SuperH + * x86_64 (Native and Linux hosted, for testing) + * Xtensa ESP32 + +There is also build infrastructure and continuous build validation, +but no integrated testing available for additional architectures: + + * Microblaze (32-bit, big and little endian) + * Sparc64 + * Xtensa (ESP8266, LX106) + +Supporting new architectures requires: + + 1. Add libc/machine/_architecture_ for architecture-specific libc + bits. This should at least include setjmp/longjmp support as these + cannot be performed in architecture independent code and are + needed by libstdc++. If available, it should also include thread + local storage setup code as libc/machine/_architecture_/tls.c; the + build system looks for that file by name when determining if TLS + is available. + + 2. Checking for atomic support for stdio. Picolibc requires + atomics for ungetc to work correctly in a reentrant + environment. By default, it stores them in 16-bit values, but + some architectures only have 32-bit atomics. To avoid ABI + issues, the size selected isn't detected automatically, instead + it must be configured in libc/include/stdio.h. + + 3. If necessary, add libm/machine/_architecture_ for any + architecture-specific math bits + + 4. picocrt/machine/_architecture_ source code and build bits + for startup code needed for the architecture. Useful in all + cases, but this is necessary to run tests under emulation if your + platform can do that. + + 5. cross-_gcc-triple_.txt to configure the meson cross-compilation + mechanism to use the right tools + + 6. do-_architecture_-configure to make testing the cross-compilation + setup easier. + + 7. run-_architecture_ script to run tests under QEMU. Look at the ARM + and RISC-V examples to get a sense of what this needs to do and + how it gets invoked from the cross-_gcc-triple_.txt configuration + file. + +## Relation to newlib + +Picolibc includes a lot of code originally from newlib. However, it +has been reformatted and restructured to make it easier to read and +maintain going forward. + +Here's a list of some differences between picolibc and newlib: + + 1. Designed for and tested on 32- and 64- bit embedded + systems. Newlib (and newlib-nano) are used on both embedded + systems and Cygwin, with the bulk of the development focused on + improving the Cygwin support. Because the Cygwin version needs to + be very careful about ABI stability, many parts of the newlib code + base are very difficult to change. Picolibc has no such + constraints, so much work has been done to improve the ABI and API + for use in embedded systems. + + 2. Stdio. Picolibc's stdio implementation borrows some code from + AVR-Libc along with substantial new code. The goal is to remain + compatible with relevant C and POSIX standards while using a very + narrow API to the underlying system (it only requires getc and + putc) along with doing no internal allocation and using a minimal + amount of RAM. + + 3. Thread-local-storage support. Instead of creating a large data + structure containing all possible thread-specific data, Picolibc + uses the underlying TLS support from the compiler which only + allocates the amount of per-thread storage needed to support the + API called by the application. Typically, this means you use only + 4 bytes for errno. + + 4. Integrated test suite. Along with dozens of new tests, picolibc + includes tests from newlib and musl. These tests are run as a part + of the patch review process and new code or bugfixes are expected + to include tests that verify functionality and keep bugs from + recurring. + + 5. Bare-metal startup code and linker scripts for many + architectures. These may not support precisely what your + application requires, but these provide a good basis for writing + your own startup code and linker scripts. These are used to create + bare-metal versions of the test suite which can then be run using + QEMU. + + 6. Meson-based build system. This is largely used to avoid conflicts + with the newlib autotools build system files, but a side effect is + that the library builds very quickly. + + 7. Narrow and well-defined POSIX OS requirements. Portions of + Picolibc which require underlying OS support are documented so + that you will know which functions are necessary based on the API + in use. In particular, picolibc requires no POSIX functions to + support stdin/stdout/stderr, and instead requires only functions + to get and put single characters to the target device. + + 8. Built-in semihosting support for many architectures. This allows + you to take advantage of existing gdb, openocd and qemu + semihosting support for things like debugging output even before + you have a serial port working. + + 9. Clear BSD licensing. All non-BSD compatible library source code + has been removed so that the status of the resulting library is + not in question. + +## Documentation + +Introductory documentation. Read these first: + + * [Building Picolibc](doc/build.md). Explains how to compile picolibc yourself. + * [Using Picolibc](doc/using.md). Shows how to compile and link + applications once you have picolibc built and installed. + * [Linking with Picolibc.ld](doc/linking.md). Provides more details + about the linking process. + * [Hello World](hello-world/README.md). Build and run a stand-alone C + application by following step-by-step instructions + +Detailed documentation. Use these to learn more details about how to +use Picolibc: + + * [Picolibc initialization](doc/init.md) + * [Operating System Support](doc/os.md). + * [Printf and Scanf in Picolibc](doc/printf.md) + * [Thread Local Storage](doc/tls.md) + * [Re-entrancy and Locking](doc/locking.md) + * [Selecting ctype implementation](doc/ctype.md) + * [Picolibc as embedded source](doc/embedsource.md) + * [Releasing Picolibc](doc/releasing.md) + * [Copyright and license information](COPYING.picolibc) + +## Releases + +### Picolibc release 1.8.11 + + * Use __math_inexact to generate FE_INEXACT in several math + functions. Thanks to Gergely Futo. + + * Support riscv '-mlarge' model in asm code. + + * Initialize riscv vector unit in startup code when present. + + * Improve arm32 A-profile operation in Thumb state. Thanks to Victor + Campos. + + * Remove duplicate isinf and isnan declarations that were visible + even when building with C++. Thanks to Mostafa Salman. + + * Improve accuracy of cacoshf for real inputs. Thanks to Ahmed + Shehab. + + * Avoid use of float types in vfprintf to avoid unnecessary fpu + register use. + + * Add missing pid_t and getdate_err declarations to time.h. + + * Implement getdate and getdate_r as required by POSIX. + + * Fix numerous minor bugs in strptime. + + * Test exception handling on m68k + + * Add Hexagon architecture support. Thanks to Kushal Pal. + + * Clean up RISC-V asm code integration. Thanks to Venkata Ramanaiah + Nalamothu. + + * Add more math tests, including exhaustive binary 32 testing. + + * Improve cbrtf precision to within 1ulp. + + * Fix lgammaf for values between -0x1p-70 and -0x1p-64. + + * Add some missing stdint.h bits that are new in C23. + + * Improve accuracy of erfcf for values between 1.25 and 28. Improve + performance for values between 0x1p-56 and 0x1p-26. + + * Fix memchr on targets with 16-bit int and 32-bit long (MSP430). + + * Mask needle with 0xff on rx version of memchr. + + * Add missing POSIX functionality in fnmatch to support character + classes, equivalence classes and collating sequences. Limit fnmatch + recursion for '*' operators to 16 levels. + + * Rename cross compile property 'libgcc' to 'librt' since we can now + specify either libgcc or compiler-rt as run-time library. However, + 'libgcc' is still supported for backward compatibility. + + * Fix bug in 32-bit riscv stpcpy which returned the wrong + value. Improve performance slightly by avoiding duplicate memory + reads of the tail of the string. + + * Make sure `__STDC_LIB_EXT1__` gets defined as appropriate. Thanks to + Mostafa Salman. + + * Fix -long_option parsing in getopt_long_only. + + * Add strfmon and strfmon_l as required by POSIX. + + * Add dprintf and vdprintf as required by POSIX. + + * Improve JIS transcoding performance by building translation tables + in both directions. + + * Fix a bunch of iconv bugs and improve POSIX conformance by + supporting //IGNORE, //DISCARD and //TRANSLIT modes. + + * Reformat code with clang-format + + * Restructure directories, moving libc and libm to the top level and + moving all tests under tests/. Remove stdio and malloc variants. + + * Add 'no-flash' crt0 variant, thanks to Kushal Pal. + + * Update minimum required meson version from 0.53 to 0.61. + + * Add -Dfstat-bufsiz option that uses fstat to select stdio buffer + sizes. Thanks to Alexey Lapshin. + + * Rewrite __rem_pio2f. This new version is faster than the old while + remaining API compatible and not using double datatypes. + + * Update libc/machine/riscv. Thanks to Yuriy Kolerov. + + * Fix the way the zicsr extension is enabled while building the crt0 + code. Thanks to Yuriy Kolerov. + + * Avoid linking in malloc when using bufio with static FILEs. + +### Picolibc release 1.8.10 + + * Add missing POSIX constants to limits.h. + + * Add Renesas RX support. Thanks to Duy Dguyen. + + * Update to Unicode 16.0. This matches glibc 2.41. + + * Add TLS support and testing on loongarch, m68k, or1k, powerpc and + superh. + + * Fix a couple of strncpy bugs in ARC assembly code. + + * Clean up preprocessor symbols: remove unused symbols, rename + picolibc.h symbols to use a __ prefix and not include PICOLIBC or + NEWLIB in the names. + + * Detect compiler attributes and builtins at compile time rather than + configure time where possible. Delete attributes and builtins not + used within the library implementation. + + * Remove non-standard elf.h and mstats API. + + * Clean up float predicates to make sure we provide implementations + of isinf, isnan and finite for all three types, both with and + without __ prefixes. Use symbol aliases to share the same function + implementation. Use the __ versions for the type generic macros + instead of fpclassify. Switch users of these within the math + library to use the type-generic versions. + + * Start SuperH FPU in single mode when required. + + * Test sh1 and sh2 targets using the binutils simulator. + + * Initialize PowerPC IPLT table at startup. + + * Switch printf/scanf aliases to prefer --printf=/--scanf= compiler + options + + * Control UCS-2 and UCS-4 locales with mb-ucs-charsets configuration + option. + + * Add stdio-locking option to provide full POSIX re-entrancy support + in tinystdio. Thanks to Alexey Lapshin. + + * Add wcsto* string to number functions using tinystdio conversion + code. Avoids malloc call for float conversions. + + * Add TLS API support for x86 targets. Thanks to TK Chia. + + * Add -fsanitize=undefined handlers and make library build with that + enabled. + +### Picolibc release 1.8.9 + + * Use common clang/gcc feature detection macros on arm. + + * Additional clang/compiler-rt work-arounds for arm which is less + consistent in handling exceptions. + + * Use clang multilib support for aarch64 + + * Build fix on arc which would build two strchr versions in release + mode. + + * Add picocrt and semihost support for xtensa. Test xtensa dc233c. + + * Add C11's header and implementation. + + * Add nano-malloc-clear-freed option to erase memory released in free + or realloc. + + * Add memset_explicit from C23. + + * Work around broken clang builtin malloc which fails to set errno. + + * Widen C++ _CTYPE_DATA array to fix mis-classification of \t; C++ + requires bitmasks for all ctype operations, and 8 bits is not + enough. Thanks to M-Moawad. + + * Update case conversion tables to Unicode 15.1.0 + + * Fix documentation formatting. Thanks to Eduard Tanase. + + * Fix support for using long-long vfprintf version by default. Thanks + to Louis Peens. + + * Remove arm unaligned memcpy asm code. This couldn't support targets + that only supported unaligned access. Use a new faster C version + for this case. + + * Add asnprintf and vasnprintf as provided by newlib + + * Support ARM's FVP emulator. Thanks to Oliver Stannard. + + * Remove arc strlen asm code as it would access memory *before* the + provided buffer and fall afoul of the stack bounds checking + hardware. + + * Support --printf={d,f,l,i,m} in place of + -DPICOLIBC_*_PRINTF_SCANF. This is the syntax proposed in the + patches submitted to gcc for picolibc support. + + * Add LoongArch support, including testing. Thanks to Jiaxun Yang. + + * Use new picolibc-ci-tools project which builds custom toolchain + bits automatically. Thanks to Jiaxun Yang. + + * Add OpenRisc support, including testing. Thanks to Joel Holdsworth. + + * Add Lattic3Mico32 support, including testing. Thanks to Jiaxun Yang. + + * Add MIPS semihosting support. Thanks to Jiaxun Yang. + + * Add older GCC compiler support, including versions < 4.4. Thanks to + Joel Holdsworth. + + * Add coreboot configurations and tests. Thanks to Jeremy Bettis and + Jon Murphy. + + * Fix numerous charset conversion errors for non-Unicode locales. + + * Make sure malloc return is aligned by using max_align_t. Thanks to + Alex Richardson. + + * Replace iconv and locale implementations with smaller code offering + the same locale functionality as before while the iconv code shares + the same charset support as the locale code instead of having a + completely separate implementation. + +### Picolibc release 1.8.8 + + * Fixed 3 bugs in the powf computation. Thanks to Fabian Schriever. + + * Fixed a bunch of build issues found by Zephyr. + + * Improve C++ testing and compatibility. + +### Picolibc release 1.8.7 + + * Support ARM v8.1-m BTI and PAC features + + * Fix stdio buffered backend automatic flushing of stdout when + reading stdin. + + * Support _FORTIFY_SOURCE=3 + + * Fix several fesetround implementations to return an error when + passed an invalid argument. Thanks to Abdallah Abdelhafeez. + + * Document headers which the compiler must provide. Thanks to Alexey + Brodkin. + + * Generate mktemp/tmpnam filenames using random() so they don't + repeat even if they aren't used before another name is generated. + + * Set error flag when fgetc is called on an file without read + mode. Thanks to Mohamed Moawad. + + * Add type casting to CMPLX, CMPLXF and CMPLXL macros (as glibc + does). Thanks to Mostafa Salman. + + * Add mips64 support and build the library during CI. + + * Make fgets return any accumulated string on EOF instead of + always returning NULL. Thanks to Hana Ashour. + + * Use C99 minimum array size in asctime_r and ctime_r API + declarations ('[static 26]'). Bounds check the generated value and + return NULL/EOVERFLOW on overflow. + + * Make Zephyr's -Oz cmake option enable + PREFER_SIZE_OVER_SPEED. Thanks to Jonathon Penix. + + * Add funopen to tinystdio. + + * Validate all public headers with a C++ compiler to make sure they + at least compile successfully. Fix time.h. + + * Stop using -include picolibc.h during library build. + + * Add -Wmissing-declarations and -Wmissing-prototypes to library + build flags. Fix a rather large pile of missing prototypes caused + by source files failing to add _GNU_SOURCE or _DEFAULT_SOURCE + definitions. + + * Add POSIX "unlocked" I/O functions to tinystdio. These don't + actually do anything because tinystdio doesn't do any + locking. However, flockfile/funlockfile grab the global C library + lock so applications synchronizing with that API will "work". + + * Fix wide orientation handling in tinystdio. Thanks to Ahmed Shehab. + + * Add aarch64 soft float support for armv8. Clang allows this with + -march=armv8-a+nofp -mabi=aapcs-soft. This required building a + custom toolchain that included a compiler-rt library built with the + right options. + + * Add fgetpos and fsetpos to tinystdio. Thanks to Hana Ashour. + + * Restore missing members of 'struct sigevent'. Over eager removal of + _POSIX_THREADS support caused these to be accidentally deleted some + time ago. + + * Test on i386 native target. + + * Fix hex float scanning and printing. Thanks to Hana Ashour and + Ahmed Shehab. + + * Fix double rounding in %f printf. Thanks to Ahmed Shehab for + constructing a test case that identified the issue. + + * Add mem_align to the "big" malloc version. Thanks to Simon Tatham. + + * Adjust POSIX and C headers to limit symbol exposure to that + specified in the standards. + + * Fix rounding in float scanf. This does round twice for input longer + than the required number of digits, but that's permitted by the C + specification. + + * Support %a/%A in scanf. Support arbitrary precision in %a/%A + printf. Fix NaN/INF formatting in %a/%A printf. Thanks to Ahmed + Shehab. + + * Provide a build-time option to enable %n in printf. This is + disabled by default for security concerns, but supported in case + someone needs strict C conformance. Thanks to Ahmed Shehab. + + * Make freopen clear the unget buffer. Thanks to Mostafa Salman. + + * Fix wide and multi-byte character support in printf and scanf. For + strict standards conformance, there's now an option that enables + %lc/%ls in printf even if multi-byte support is not enabled. + + * Enable MMU in picocrt on A profile ARM and AARCH64 targets when + present. This is required by the latest qemu which now more + accurately emulates this hardware. Thanks to Alex Richardson. + + * Fix AARCH64 asm code in ILP32 mode. + + * Parse NaN() in sscanf. This is required by the standard, + although picolibc doesn't do anything with . Thanks to + Mohamed Moawad. + + * Clean up header files. Picolibc tries to limit symbol definitions + to those specified in the C and POSIX specs. + + * Add support for C's Annex K functions. These are bounds-checking + versions of various memory and string functions. Thanks to Mostafa + Salman. + + * Perform locale string validation in newlocale even when _MB_CAPABLE + isn't defined. Thanks to Mostafa Salman. + + * Place compiler-rt library after C library when linking + tests. Thanks to Oliver Stannard. + +### Picolibc version 1.8.6 + + * Fix some FORTITY_SOURCE issues with tinystdio + + * Add __eh_* symbols to picolibc.ld for LLVM libunwind. Thanks Alex + Richardson. + + * Merge in newlib annual release (4.4.0). Some minor updates to + aarch64 assembly code formatting (thanks to Sebastian Huber) and a + few other fixes. + + * Enable 32-bit SPARC for testing. + + * Fix a bunch of fmemopen bugs and add some tests. Thanks to Alex + Richardson. + + * Finish support for targets with unusual float types, mapping + target types to 32-, 64-, 80- and 128- bit picolibc code. + + * Add SuperH support, including testing infrastructure. Thanks to + Adrian Siekierka for help with this. + + * Improve debugger stack trace in risc-v exception code. Thanks to + Alex Richardson. + + * Add an option (-Dfast-bufio=true) for more efficient fread/fwrite + implementations when layered atop bufio. Thanks for the suggestion + from Zachary Yedidia. + + * Fix cmake usage of FORMAT_ variables (note the lack of a leading + underscore). + + * Remove explicit _POSIX_C_SOURCE definition in zephyr/zephr.cmake. + + * Clean up public inline functions to share a common mechanism for + using gnu_inline semantics. Fix isblank. This ensures that no + static inline declarations exist in public API headers which are + required to be external linkage ("real") symbols. + + * Create an alternate ctype implementation that avoids using the + _ctype_ array and just does direct value comparisons. This only + works when picolibc is limited to ASCII. Applications can select + whether they want this behavior at application compilation time + without needing to rebuild the C library. Thanks to P. Frost for + the suggestion. + + * Unify most fenv implementations to use gnu_inline instead of + regular functions to improve performance. x86 was left out because + those fenv functions are complicated by the mix of 8087 and modern + FPU support. + + * Add a separate FILE for stderr when using POSIX I/O. Split + stdin/stdout/stderr into three files to avoid pulling in + those which aren't used. Thanks to Zachary Yedidia. + +### Picolibc version 1.8.5 + + * Detect clang multi-lib support correctly by passing compiler flags. + Thanks to xbjfk for identifying the problem. + + * Create a new 'long-long' printf variant. This provides enough + variety to satisfy the Zephyr cbprintf options without needing to + build the library from scratch. + + * Adjust use of custom binary to decimal conversion code so that it + is only enabled for types beyond the register size of the + target. This avoids the cost of this code when the application is + already likely to be using the soft division routines. + +### Picolibc version 1.8.4 + + * Make math overflow and underflow handlers respect rounding modes. + + * Add full precision fma/fmaf fallbacks by adapting the long-double + code which uses two floats/doubles and some careful exponent + management to ensure that only a single rounding operation occurs. + + * Fix more m68k 80-bit float bugs + + * Fix m68k asm ABI by returning pointers in %a0 and %d0 + + * Use an m68k-unknown-elf toolchain for m68k testing, including + multi-lib to check various FPU configurations on older and more + modern 68k targets. + + * Improve CI speed by using ccache on zephyr and mac tests, + compressing the docker images and automatically canceling jobs when + the related PR is updated. Thanks to Peter Jonsson. + + * Move a bunch of read-only data out of RAM and into flash by adding + 'const' attributes in various places. + + * Add a new linker symbol, `__heap_size_min`, which specifies a + minimum heap size. The linker will emit an error if this much space + is not available between the end of static data and the stack. + + * Fix a bunch of bugs on targets with 16-bit int type. Thanks to + Peter Jonsson for many of these. + + * Work around a handful of platform bugs on MSP430. I think these are + compiler bugs as they occur using both the binutils simulator and + mspsim. + + * Run tests on MSP430 using the simulator that comes with gdb. Thanks to + Peter Jonsson for spliting tests apart to make them small enough to + link in under 1MB. This requires a patch adding primitive + semihosting to the simulator. + + * Provide a division-free binary to decimal conversion option for + printf at friends. This is useful on targets without hardware + divide as it avoids pulling in a (usually large) software + implementation. This is controlled with the 'printf-small-ultoa' + meson option and is 'false' by default. + + * Add 'minimal' printf and scanf variants. These reduce functionality + by removing code that acts on most data modifers including width + and precision fields and alternate presentation modes. A new config + variable, minimal-io-long-long, controls whether that code supports + long long types. + + * Add a 'assert-verbose' option which controls whether the assert + macro is chatty by default. It is 'true' by default, which + preserves the existing code, but when set to 'false', then a + failing assert calls __assert_no_msg with no arguments, saving the + memory usually occupied by the filename, function name and + expression. + + * Fix arm asm syntax for mrc/mcr instructions to make clang happy. + Thanks to Radovan Blažek for this patch. + +### Picolibc version 1.8.3 + + * Fix bugs in floor and ceil implementations. + + * Use -fanalyzer to find and fix a range of issues. + + * Add __ubsan_handle_out_of_bounds implementation. This enables + building applications with -fsanitize=bounds and + -fno-sanitize-undefined-trap-on-error. + + * Validate exception configuration on targets with mixed exception + support where some types have exceptions and others don't. Right + now, that's only arm platforms where any soft float implementations + don't build with exception support. + + * Fix bugs in nexttowards/nextafter on clang caused by the compiler + re-ordering code and causing incorrect exception generation. + + * Use the small/slow string code when -fsanitize=address is used + while building the library. This avoids reading beyond the end of + strings and triggering faults. + + * Handle soft float on x86 and sparc targets. That mostly required + disabling the hardware exception API, along with a few other minor + bug fixes. + + * Add runtime support for arc, mips, nios2 and m68k. This enables CI + testing on these architectures using qemu. + + * Fix 80-bit floating math library support for m68k targets. + + * Fix arm testing infra to use various qemu models that expand + testing to all standard multi-lib configurations. + + * Adjust floating exception stubs to return success when appropriate, + instead of always returning ENOSYS. + + * Make sure sNaN raises FE_INVALID and is converted to qNaN in + truncl, frexpl and roundl + + * Avoid NaN result from fmal caused by multiply overflow when + addend is infinity (-inf + inf results in NaN in that case). + +### Picolibc version 1.8.2 + + * Support _ZEPHYR_SOURCE macro which, like _POSIX_SOURCE et al, + controls whether the library expresses the Zephyr C library API. + This is also automatically selected when the __ZEPHYR__ macro is + defined and no other _*_SOURCE macro is defined. + + * Add another cross compile property, 'libgcc', which specifies the + library containing soft float and other compiler support routines. + + * Fix a couple of minor imprecisions in pow and 80-bit powl. + + * Merge newlib changes that included an update to the ARM assembly + code. + + * Replace inexact float/string conversion code with smaller code that + doesn't use floating point operations to save additional space on + soft float targets. + + * More cmake fixes, including making the inexact printf and locale + options work. + +### Picolibc version 1.8.1 + + * Fix cmake build system to auto-detect compiler characteristics + instead of assuming the compiler is a recent version of GCC. This + allows building using cmake with clang. + + * Fix cmake build system to leave out TLS support when TLS is + disabled on the cmake command line. + + * Replace inline asm with attributes for __weak_reference macro + + * Add allocation attributes to malloc and stdio functions. This + allows the compiler to detect allocation related mistakes as well + as perform some additional optimizations. Bugs found by this change + were also addressed. + + * Add wchar_t support to tinystdio, eliminating the last missing + feature compared with the legacy stdio bits from newlib. With this, + libstdc++ can be built with wide char I/O support, eliminating the + last missing feature there as well. + + * Eliminate use of command line tools when building with a new enough + version of meson. Thanks to Michael Platings. + + * Add Microblaze support. Thanks to Alp Sayin. + + * Switch semihosting to use binary mode when opening files. Thanks to + Hardy Griech. + + * Build and install static library versions of the crt0 startup + code. These allows developers to reference them as libraries on the + command line instead of needing special compiler support to locate + the different variants, which is useful when using clang. Thanks to + Simon Tatham. + + * Simplify the signal/raise implementation to use a single global + array of signal handlers and to not use getpid and kill, instead + raise now directly invokes _exit. This makes using assert and abort + simpler and doesn't cause a large TLS block to be allocated. Thanks + to Joe Nelson for discovering the use of a TLS variable here. + +### Picolibc version 1.8 + +With the addition of nearly complete long double support in the math +library, it seems like it's time to declare a larger version increment +than usual. + + * Improve arc and xtensa support, adding TLS helpers and other build fixes + + * Fix FPSCR state for Arm8.1-M low overhead loops (thanks to David + Green) + + * Add -Werror=double-promotion to default error set and fix related + errors. (thanks to Ryan McClelland) + + * Fix locking bug in malloc out-of-memory path and freeing a locked + mutex in the tinystdio bufio code. These were found with lock + debugging code in Zephyr. + + * Add some missing functions in tinystdio, strto*l_l, remove, + tmpname/tmpfile which were published in stdio.h but not included in + the library. + + * Switch read/write functions to use POSIX types instead of legacy + cygwin types. This makes mapping to existing an POSIX api work + right. + + * Add %b support to tinystdio printf and scanf. These are disabled by + default as they aren't yet standardized. + + * Fix avr math function support. The avr version of gcc has modes + where double and long double are 32 or 64 bits, so the math library + code now detects all of that at compile time rather than build time + and reconfigures the functions to match the compiler types. + + * Add nearly complete long double support from openlibm for 80-bit + Intel and 128-bit IEEE values (in addition to supporting 64-bit + long doubles). Still missing are Bessel functions and decimal + printf/scanf support. + + * Add limited long double support for IBM 'double double' form. This + is enough to run some simple tests, but doesn't have any + significant math functions yet. + + * Get Power9 code running under qemu with OPAL. This was mostly + needed to validate the big-endian and exception code for 128-bit + long doubles, but was also used to validate the double double + support. + + * Provide times() and sysconf() implementations in semihosting. You + can now build and run the dhrystone benchmark without any further + code. + + * Fix use of TLS variables with stricter alignment requirements in + the default linker script and startup code. (thanks to Joakim + Nohlgård and Alexander Richardson who found this issue while + working on lld support). + +### Picolibc version 1.7.9 + + * Support all Zephyr SDK targets + + * Support relocating the toolchain by using GCC_EXEC_PREFIX for + sysroot-install when compiler doesn't use sysroot. + + * Add MIPS, SPARC and ARC support + + * Deal with RISC-V changes in gcc that don't reliably include zicsr + + * Support Picolibc as default C library with -Dsystem-libc option. + With this, you can use picolibc without any extra compiler options. + + * Merge current newlib bits to get code that doesn't use struct _reent + + * Get rid of struct _reent in legacy stdio code + + * Support 16-bit int targets by fixing a few places assuming + sizeof(int) == 4, object sizes not using size_t, wint_t for + ucs-4 values + + * Add MSP430 support + + * Fix a couple of clang bugs (one on Cortex M0) + + * Support libc++ by adding non-standard mbstate_t.h + + * Merge i686 and x86_64 code to allow x86 multilib builds + + * Merge Xtensa newlib bits + + * Support Xtensa ESP32 targets + + * Add Nios II support + +### Picolibc version 1.7.8 + + 1. Fix el/ix level 4 code type errors + + 2. Fix out-of-source CMake build (thanks Max Behensky) + + 3. Improve build.md docs (thanks Kalle Raiskila) + + 4. Fix cmake build for various architectures + + 5. Initialize lock in fdopen + + 6. Remove %M from linker paths in single-arch builds + + 7. Shrink tinystdio vfprintf and vfscanf a bit + + 8. Use -fno-builtin-malloc -fno-builtin-free (GCC 12 compat) + + 9. Use -fno-builtin-copysignl (GCC 12 compat) + + 10. Add _zicsr to -march for risc-v picocrt (binutils 2.38 compat) + + 11. Add -no-warn-rwx-segments to link spec (binutils 2.38 compat) + +### Picolibc version 1.7.7 + + 1. Fix semihost gettimeofday, add a test. + + 2. Fix config option documentation. (Thanks to rdiez) + + 3. Document how re-entrant locking APIs are used. (Thanks to rdiez) + + 4. Fix some 16-bit int issues in tinystdio. (Thanks to Ayke van + Laethem) + + 5. Make header files a bit more POSIX compliant, installing rpc + headers, moving byte swapping macros to arpa/inet.h + + 6. Fix some stdio bugs found by Zephyr test suite: snprintf return + value on buffer overflow, add ftello/fseeko, fputc return value, + %0a formatting, clear EOF status after ungetc/fseek. + + 7. Re-do buffered I/O support to handle mixed read/write files + correctly. This adds setbuf, setbuffer, setlinebuf, setvbuf. + + 8. Add fmemopen and freopen. + + 9. Add enough cmake support to allow Zephyr to build picolibc as a + module using that, rather than meson. + + 10. Merge current newlib bits + + 11. Fix %p printf/scanf on ILP64 targets. + +### Picolibc version 1.7.6 + + 1. Fix use with C++ applications caused by a syntax error in + picolibc.specs + + 2. Automatically include '-nostdlib' to options used while + evaluating build rules to ensure tests work as expected. + + 3. Publish aarch64 inline math functions, ensure that inline fma + functions work in installed applications for arm and risc-v. + +### Picolibc version 1.7.5 + + 1. Fix build on big-endian systems (thanks to Thomas Daede) + + 2. Add m68k support (thanks to Thomas Daede). + + 3. Fix build issues with ARM Cortex-a9 target (thanks to Ilia + Sergachev). + + 4. Fix fwrite(x,0,y,z) in both tinystdio and legacy stdio. tinystdio + returned the wrong value and legacy stdio caused a divide-by-zero + fault. + + 5. Update Ryu code to match upstream (minor fixes) + + 6. Fix various __NEWLIB and __PICOLIBC macros; they were using a + single leading underscore instead of two (thanks to Vincent + Palatin). + + 7. Fix tinystdio error-handling bugs + + 8. Merge recent newlib changes (fixed ltdoa in legacy stdio) + + 9. Speed improvements for github CI system + + 10. Big-endian PowerPC support + + 11. Fail builds if most 'run_command' uses fail (thanks to Johan de + Claville Christiansen) + + 12. Positional parameters in tinystdio. With this, I think tinystdio + is feature complete. + + 13. Support for multiple build-styles of picolibc (minsize/release) + in one binary package. This still requires separate meson runs. + + 14. Testing with glibc test code. This uncovered numerous bugs, + mostly math errno/exception mistakes, but also a few serious + bugs, including a couple of places where the nano-malloc failed + to check for out-of-memory. Picolibc now passes all of the glibc + math tests except for jn, yn, lgamma and tgamma. The picolibc + versions of those functions are too inaccurate. Picolibc also + passes most other relevant glibc tests, including stdio, + string and stdlib areas. + + 15. Tinystdio version of fcvt now has a static buffer large enough to + hold the maximum return size. + + 16. Tinystdio versions of ecvtbuf and fcvtbuf have been replaced + with ecvt_r and fcvt_r equivalents, which take a 'len' parameter + to prevent buffer overruns. + + 17. Add the GeneratePicolibcCrossFile.sh script which provides a way + to isolate picolibc build scripts from the vagaries of meson + version shifts (thanks to R. Diez). + + 18. Add 'semihost' version of crt0 that calls 'exit' after main + returns. The ARM and RISC-V versions of this also include trap + handlers for exceptions that print out information and exit when + an exception occurs. + +### Picolibc version 1.7.4 + + 1. Clean up meson build bits, including use of 'fs module (thanks to + Yasushi Shoji). + + 2. Speed up github actions by sharing Debian docker image (thanks to + Yasushi Shoji). + + 3. Reduce use of intermediate static libraries during build + + 4. Use standard Meson architecture names everywhere (thanks to + Yasushi Shoji). + + 5. Support building with -D_FORTIFY_SOURCE enabled. + + 6. Clean up 32-bit arm assembly code, eliminating __aeabi wrappers + where possible. + + 7. Add basename, dirname and fnmatch back. + + 8. Fix all old-style (K&R) function definitions. + + 9. Enable lots more compiler warning flags. + + 10. Remove last uses of alloca in legacy stdio code. + + 11. Add tests from musl libc-testsuite. There aren't many tests, but + these identified a few bugs. + + 12. Add lots more exception and errno tests for the math functions. + + 13. Restructure math library to always use the `__math_err` functions + to raise exceptions and set errno. This removes the w_*.c wrapper + functions and eliminates the `__ieee names`. This centralizes + compiler work-arounds to ensure run-time evaluation of + expressions intended to raise exceptions. In the process, all of + the libm/math files were reformatted with clang-format. + + 14. Make tinystdio '%a' compatible with glibc, including supporting + rounding and trimming trailing zeros when possible. + + 15. Remove floating point exception generation code on targets + without floating point exception support. This reduces code size + on soft float machines without affecting results. + +### Picolibc version 1.7.3 + + 1. Add -Wall -Wextra to default builds. Fixed warnings this raised. + + 2. Add htonl and friends (based on __htonl). Thanks to Johan de + Claville Christiansen + + 3. Set errno in scalbn and scalbnf (patch forwarded to newlib). + + 4. Merge newlib recent changes which includes a couple of libm fixes. + +### Picolibc version 1.7.2 + + 1. Fix picolibc.ld to split C++ exceptions back apart (thanks to + Khalil Estell) + + 2. Add vsscanf to tinystdio (required for libstdc++). + + 3. Also stick -isystem in C++ compile command to try and get + picolibc headers to be used instead of newlib. + +### Picolibc version 1.7.1 + + 1. Add __cxa_atexit implementation to 'picoexit' path as required by + C++ + + 2. Fix lack of 'hh' support in integer-only tinystdio printf path. + + 3. Fix tinystdio __file flag initialization for C++ apps + +### Picolibc version 1.7 + + 1. Merge libc and libm into a single library. Having them split + doesn't offer any advantages while requiring that applications add + '-lm' to link successfully. Having them merged allows use of libm + calls from libc code. + + 2. Add hex float format to *printf, *scanf and strto{d,f,ld}. This is + required for C99 support. + + 3. Unify strto{d,f,ld} and *scanf floating point parsing code. This + ensures that the library is consistent in how floats are parsed. + + 4. Make strto{d,f,ld} set errno to ERANGE on overflow/underflow, + including when the result is a subnormal number. + +### Picolibc version 1.6.2 + + 1. Change `restrict` keyword in published headers to `__restrict` to + restore compatibility with applications building with --std=c18. + + 2. Additional cleanups in time conversion funcs (Thanks to R. Riez) + +### Picolibc version 1.6.1 + + 1. Code cleanups for time conversion funcs (Thanks to R. Diez) + + 2. Add '-fno-stack-protector' when supported by the C compiler + to avoid trouble building with native Ubuntu GCC. + + 3. Bug fix for converting denorms with sscanf and strto{d,f,ld}. + + 4. Use __asm__ for inline asm code to allow building applications + with --std=c18 + + 5. Fix exit code for semihosting 'abort' call to make it visible + to the hosting system. + + 6. Add strfromf and strfromd implementations. These are simple + wrappers around sscanf, but strfromf handles float conversions + without requiring a pass through 'double' or special linker hacks. + +### Picolibc version 1.6 + + 1. Bugfix for snprintf(buf, 0) and vsnprintf(buf, 0) to avoid + smashing memory + + 2. Support building libstdc++ on top of picolibc + + 3. Add 'hosted' crt0 variant that calls exit when main + returns. This makes testing easier without burdening embedded apps + with unused exit processing code. + + 4. Add 'minimal' crt0 variant that skips constructors to + save space on systems known to not use any. + + 5. Fix HW floating point initialization on 32-bit ARM processors to + perform 'dsb' and 'isb' instructions to ensure the FPU enabling + write is complete before executing any FPU instructions. + + 6. Create a new '--picolibc-prefix' GCC command line parameter that + sets the base of all picolibc file names. + + 7. Add bare-metal i386 and x86_64 initializatiton code (thanks to + Mike Haertel). These initalize the processor from power up to + running code without requiring any BIOS. + + 8. Merge newlib as of late April, 2021 + + 9. Add 'timegm' function (thanks to R. Diez). + +10. Fix a number of tinystdio bugs: handle fread with size==0, parse + 'NAN' and 'INF' in fscanf in a case-insensitive manner, fix + negative precision to '*' arguments in printf, fix handling of + 'j', 'z' and 't' argument size specifiers (thanks to Sebastian + Meyer). + +11. Make the fenv API more consistent and more conformant with the + spec. All architectures now fall back to the default code + for soft float versions, which avoids having the various exception + and rounding modes get defined when not supported. + +### Picolibc version 1.5.1 + + 1. Make riscv crt0 '_exit' symbol 'weak' to allow linking without + this function. + +### Picolibc version 1.5 + + 1. Make picolibc more compatible with C++ compilers. + + 2. Add GCC specs file and linker script for building C++ applications + with G++ that enable exception handling by linking in call stack + information. + + 3. A few clang build fixes, including libm exception generation + + 4. Nano malloc fixes, especially for 'unusual' arguments + + 5. Merge in newlib 4.1.0 code + + 6. More libm exception/errno/infinity fixes, mostly in the gamma funcs. + + 7. Add tests for all semihost v2.0 functions. + + 8. A few RISC-V assembly fixes and new libm code. + + 9. Build fixes to reliably replace generic code with + architecture-specific implementations. + +With a patch which is pending for GCC 11, we'll be able to build C++ +applications that use picolibc with exceptions and iostream. + +### Picolibc version 1.4.7 + + 1. Fix numerous libm exception and errno bugs. The math functions are + all now verified to match the C19 and Posix standards in this + area. + + 2. Change behavior of 'gamma' function to match glibc which returns + lgamma for this function. Applications should not use this + function, they should pick either lgamma or tgamma as appropriate. + + 3. Fix fma/fmaf on arm and RISC-V so that the machine-specific versions + are used when the hardware has support. Also fix the math library + to only use fma/fmaf when it is supported by the hardware. + + 4. Fix numerous nano-malloc bugs, especially with unusual parameters. + + 5. Change nano-malloc to always clear returned memory. + + 6. Improve nano-realloc to perform better in various ways, including + merging adjacent free blocks and expanding the heap. + + 7. Add malloc tests, both a basic functional test and a stress test. + + 8. Improve build portability to Windows. Picolibc should now build + using mingw. + + 9. Use hardware TLS register on ARM when available. + + 10. Support clang compiler. Thanks to Denis Feklushkin + and Joakim Nohlgård . + + 11. Avoid implicit float/double conversions. Check this by having + clang builds use -Wdouble-promotion -Werror=double-promotion + flags + + 12. Have portable code check for machine-specific overrides by + matching filenames. This avoids building libraries with + duplicate symbols and retains compatibility with newlib (which + uses a different mechanism for this effect). + + 13. Patches to support building with [CompCert](http://compcert.inria.fr/), a + formally verified compiler. Thanks to Sebastian Meyer + . + +### Picolibc version 1.4.6 + + 1. Install 'ssp' (stack smashing protection) header files. This fixes + compiling with -D_FORTIFY_SOURCE. + + 2. Make getc/ungetc re-entrant. This feature, which is enabled by + default, uses atomic instruction sequences that do not require + OS support. + + 3. Numerous iconv fixes, including enabling testing and switching + external CCS file loading to use stdio. By default, iconv provides + built-in CCS data for all of the supported encodings, which takes + a fairly large amount of read-only memory. Iconv is now always + included in picolibc as it isn't included in applications unless + explicitly referenced by them. + + 4. Add __getauxval stub implementation to make picolibc work with + GCC version 10 compiled for aarch64-linux-gnu. + + 5. Change how integer- and float- only versions of printf and scanf + are selected. Instead of re-defining the symbols using the C + preprocessor, picolibc now re-defines the symbols at link + time. This avoids having applications compiled with a mixture of + modes link in multiple versions of the underlying functions, while + still preserving the smallest possible integer-only + implementation. + + 6. Document how to use picolibc on a native POSIX system for + testing. Check out the [os.md](doc/os.md) file for details. + + 7. Merge current newlib bits in. This includes better fenv support, + for which tests are now included in the picolibc test suite. + +### Picolibc version 1.4.5 + + 1. Fix section order in picolibc.ld to give applications correct + control over the layout of .preserve, .init and .fini regions. + + 2. Add startup and TLS support for aarch64 and non Cortex-M 32-bit + arm. + +### Picolibc version 1.4.4 + + 1. Fix floating point 'g' format output in tinystdio. (e.g., + for 10.0, print '10' instead of '1e+01'). There are tests which + verify a range of 'g' cases like these now. + + 2. Merge current newlib bits. The only thing which affects picolibc + is the addition of fenv support for arm. + +### Picolibc version 1.4.3 + + 1. Make fix for CVE 2019-14871 - CVE 2019-14878 in original newlib + stdio code not call 'abort'. Allocation failures are now reported + back to the application. + + 2. Add 'exact' floating point print/scan code to tinystdio. Thanks + to Sreepathi Pai for pointing me at the Ryu code by Ulf + Adams. + + 3. Add regular expression functions from newlib. These were removed + by accident while removing POSIX filesystem-specific code. + + 4. Make tinystdio versions of [efg]cvt functions. This means that the + default tinystdio version of picolibc no longer calls malloc from + these functions. + + 5. More clang-compatibility fixes. (Thanks to Denis Feklushkin) + + 6. Remove stdatomic.h and tgmath.h. (they should not be provide by picolibc) + +### Picolibc version 1.4.2 + + 1. Clang source compatibility. Clang should now be able to compile + the library. Thanks to Denis Feklushkin for figuring out how + to make this work. + + 2. aarch64 support. This enables the existing aarch64 code and + provides an example configuration file for getting it + built. Thanks for Anthony Anderson for this feature. + + 3. Testing on github on push and pull-request. For now, this is + limited to building the library due to a bug in qemu. + + 4. Get newlib stdio working again. You can now usefully use Newlib's + stdio. This requires a working malloc and is substantially larger + than tinystdio, but has more accurate floating point input. This + requires POSIX functions including read, write and a few others. + + 5. Fix long double strtold. The working version is only available + when using tinystdio; if using newlib stdio, strtold is simply not + available. + + 6. Improve tinystdio support for C99 printf/scanf additions. + + 7. Check for correct prefix when sysroot-install option is + selected. The value of this option depends on how gcc was + configured, and (alas) meson won't let us set it at runtime, so + instead we complain if the wrong value was given and display the + correct value. + + 8. Sync up with current newlib head. + +### Picolibc version 1.4.1 + +This release contains an important TLS fix for ARM along with a few +minor compatibility fixes + + 1. Make __aeabi_read_tp respect ARM ABI register requirements to + avoid clobbering register contents during TLS variable use. + + 2. Use cpu_family instead of cpu in meson config, which is 'more + correct' when building for a single cpu instead of multilib. + + 3. Make arm sample interrupt vector work with clang + + 4. Use __inline instead of inline in published headers to allow + compiling with -ansi + + 5. Make 'naked' RISC-V _start function contain only asm + statements as required by clang (and recommended by gcc). + + 6. Use -msave-restore in sample RISC-V cross-compile + configuration. This saves text space. + +### Picolibc version 1.4 + +This release was focused on cleaning up the copyright and license +information. + + 1. Copyright information should now be present in every source file. + + 2. License information, where it could be inferred from the + repository, was added to many files. + + 3. 4-clause BSD licenses were changed (with permission) to 3-clause + + 4. Fix RISC-V ieeefp.h exception bits + + 5. Merge past newlib 3.2.0 + + 6. Add PICOLIBC_TLS preprocessor define when the library has TLS support + +### Picolibc version 1.3 + +This release now includes tests, and fixes bugs found by them. + + 1. ESP8266 support added, thanks to Jonathan McDowell. + + 2. Numerous test cases from newlib have been fixed, and + precision requirements adjusted so that the library now + passes its own test suite on x86, RISC-V and ARM. + + 3. String/number conversion bug fixes. This includes fcvt/ecvt/gcvt + shared with newlib and tinystdio printf/scanf + + 4. A few RISC-V ABI fixes, including setting the TLS base correctly, + compiling with -mcmodel=medany, and enabling the FPU for libraries + built to use it. + + 5. Semihosting updates, including adding unlink, kill and getpid + (which are used by some tests). + +### Picolibc version 1.2 + +This release includes important fixes in picolibc.ld and more +semihosting support. + + 1. File I/O and clock support for semihosting. This enables fopen/fdopen + support in tinystdio along with an API to fetch a real time clock + value. + + 2. Fix picolibc.ld to not attempt to use redefined symbols for memory + space definitions. These re-definitions would fail and the default + values be used for system memory definitions. Instead, just use + the ? : operators each place the values are needed. Linker scripts + continue to mystify. + + 3. Expose library definitions in 'picolibc.h', instead of 'newlib.h' + and '_newlib_version.h' + + 4. Define HAVE_SEMIHOST when semihosting support is available. This + lets the 'hello-world' example do some semihost specific things. + +### Picolibc version 1.1 + +A minor update from 1.0, this release includes: + + 1. semihost support. This adds console I/O and exit(3) support on ARM + and RISC-V hosts using the standard semihosting interfaces. + + 2. Posix I/O support in tinystdio. When -Dposix-io=true is included + in the meson command line (which is the default), tinystdio adds + support for fopen and fdopen by using malloc, open, close, read, + write and lseek. If -Dposix-console=true is also passed to meson, + then picolibc will direct stdin/stdout/stderr to the posix + standard file descriptors (0, 1, 2). + + 3. Merge recent upstream newlib code. This brings picolibc up to date + with current newlib sources. + + 4. Hello world example. This uses a simple Makefile to demonstrate + how to us picolibc when installed for ARM and RISC-V embedded + processors. The resulting executables can be run under qemu. + + 5. Remove libm/mathfp directory. This experimental code never + worked correctly anyways. + +### Picolibc version 1.0 + +This is the first release of picolibc. Major changes from newlib +include: + + 1. Remove all non-BSD licensed code. None of it was used in building + the embedded library, and removing it greatly simplifies the + license situation. + + 2. Move thread-local values to native TLS mechanism + + 3. Add smaller stdio from avr-libc, which is enabled by default + + 4. Switch build system to meson. This has two notable benefits; the first + is that building the library is much faster, the second is that + it isolates build system changes from newlib making merging of + newlib changes much easier. + + 5. Add simple startup code. This can be used in environments that + don't have complicated requirements, allowing small applications + to avoid needing to figure this out. + diff --git a/license-policy.yml b/license-policy.yml new file mode 100644 index 0000000..c8fca71 --- /dev/null +++ b/license-policy.yml @@ -0,0 +1,37 @@ +license_policies: + - license_key: gpl-2.0 + label: Copyleft + policy: forbidden + - license_key: gpl-2.0-plus + label: Copyleft + policy: forbidden + - license_key: gpl-3.0 + label: Copyleft + policy: forbidden + - license_key: gpl-3.0-plus + label: Copyleft + policy: forbidden + - license_key: agpl-3.0 + label: Copyleft + policy: forbidden + - license_key: agpl-3.0-plus + label: Copyleft + policy: forbidden + - license_key: lgpl-2.0 + label: Copyleft + policy: forbidden + - license_key: lgpl-2.0-plus + label: Copyleft + policy: forbidden + - license_key: lgpl-2.1 + label: Copyleft + policy: forbidden + - license_key: lgpl-2.1-plus + label: Copyleft + policy: forbidden + - license_key: lgpl-3.0 + label: Copyleft + policy: forbidden + - license_key: lgpl-3.0-plus + label: Copyleft + policy: forbidden diff --git a/scripts/GeneratePicolibcCrossFile.sh b/scripts/GeneratePicolibcCrossFile.sh deleted file mode 100755 index 988bc74..0000000 --- a/scripts/GeneratePicolibcCrossFile.sh +++ /dev/null @@ -1,613 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2022 R. Diez - Licensed under the GNU AGPLv3 -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# - -set -o errexit -set -o nounset -set -o pipefail - -# set -x # Enable tracing of this script. - -declare -r SCRIPT_NAME="GeneratePicolibcCrossFile.sh" -declare -r VERSION_NUMBER="1.02" - -declare -r -i EXIT_CODE_SUCCESS=0 -declare -r -i EXIT_CODE_ERROR=1 - - -abort () -{ - echo >&2 && echo "Error in script \"$0\": $*" >&2 - exit $EXIT_CODE_ERROR -} - - -display_help () -{ -cat - <-gcc. - This option allows you to override it. Specify --c-compiler=xxx multiple - times to add further compiler arguments. - --linker=xxxx Add Meson setting 'c_ld'. Specify --linker=xxx multiple times - to add further linker arguments. - --cflag=xxx Add a C compiler flag for the target. Example: --cflag="-O2" - These flags land in Meson setting 'c_args'. - --lflag=xxx Add a linker flag for the target. Example: --lflag="-L/target/libs" - These flags land in Meson setting 'c_link_args'. - --exewrap=xxx The first time, add Meson setting 'exe_wrapper' with the given - argument, and add Meson setting "needs_exe_wrapper = true". - Subsequent --exewrap=xxx options add further arguments to 'exe_wrapper'. - --meson-compat=0.55 Provides compability with Meson versions up to 0.55. - -Usage example: - ./$SCRIPT_NAME \\ - --target-arch=arm-none-eabi \\ - --cpu-family=arm \\ - --cpu=cortex-m3 \\ - --endianness=little \\ - --cflag="-g" \\ - --cflag="-O2" \\ - >cross-build-settings.txt - -If you are calling this script from a GNU Make makefile, and you have a variable with all compiler flags, -you can generate the corresponding --cflags=xxx options like this: - \$(patsubst %,--cflag=%,\$(PICOLIBC_C_FLAGS_FOR_TARGET)) - -Exit status: 0 means success. Any other value means error. - -EOF -} - - -display_license() -{ -cat - <. - -EOF -} - - -process_command_line_argument () -{ - case "$OPTION_NAME" in - help) - display_help - exit $EXIT_CODE_SUCCESS - ;; - - version) - echo "$VERSION_NUMBER" - exit $EXIT_CODE_SUCCESS - ;; - - license) - display_license - exit $EXIT_CODE_SUCCESS - ;; - - target-arch) - if [[ $OPTARG = "" ]]; then - abort "Option --target-arch has an empty value."; - fi - TARGET_ARCH="$OPTARG" - ;; - - cpu-family) - if [[ $OPTARG = "" ]]; then - abort "Option --cpu-family has an empty value."; - fi - CPU_FAMILY_NAME="$OPTARG" - ;; - - cpu) - if [[ $OPTARG = "" ]]; then - abort "Option --cpu has an empty value."; - fi - CPU_NAME="$OPTARG" - ;; - - system) - if [[ $OPTARG = "" ]]; then - abort "Option --system has an empty value."; - fi - SYSTEM_NAME="$OPTARG" - ;; - - c-compiler) - if [[ $OPTARG = "" ]]; then - abort "Option --c-compiler has an empty value."; - fi - C_COMPILER+=("$OPTARG") - ;; - - linker) - if [[ $OPTARG = "" ]]; then - abort "Option --linker has an empty value."; - fi - LINKER+=("$OPTARG") - ;; - - endianness) - if [[ $OPTARG = "" ]]; then - abort "Option --endianness has an empty value."; - fi - ENDIANNESS="$OPTARG" - ;; - - cflag) - if [[ $OPTARG = "" ]]; then - abort "Option --cflag has an empty value."; - fi - CFLAGS_FOR_TARGET+=("$OPTARG") - ;; - - lflag) - if [[ $OPTARG = "" ]]; then - abort "Option --lflag has an empty value."; - fi - LINKER_FLAGS_FOR_TARGET+=("$OPTARG") - ;; - - exewrap) - if [[ $OPTARG = "" ]]; then - abort "Option --exewrap has an empty value."; - fi - EXE_WRAPPER+=("$OPTARG") - ;; - - meson-compat) - if [[ $OPTARG = "" ]]; then - abort "Option --meson-compat has an empty value."; - fi - MESON_COMPATIBILITY="$OPTARG" - ;; - - *) # We should actually never land here, because parse_command_line_arguments() already checks if an option is known. - abort "Unknown command-line option \"--${OPTION_NAME}\".";; - esac -} - - -parse_command_line_arguments () -{ - # The way command-line arguments are parsed below was originally described on the following page: - # http://mywiki.wooledge.org/ComplexOptionParsing - # But over the years I have rewritten or amended most of the code myself. - - if false; then - echo "USER_SHORT_OPTIONS_SPEC: $USER_SHORT_OPTIONS_SPEC" - echo "Contents of USER_LONG_OPTIONS_SPEC:" - for key in "${!USER_LONG_OPTIONS_SPEC[@]}"; do - printf -- "- %s=%s\\n" "$key" "${USER_LONG_OPTIONS_SPEC[$key]}" - done - fi - - # The first colon (':') means "use silent error reporting". - # The "-:" means an option can start with '-', which helps parse long options which start with "--". - local MY_OPT_SPEC=":-:$USER_SHORT_OPTIONS_SPEC" - - local OPTION_NAME - local OPT_ARG_COUNT - local OPTARG # This is a standard variable in Bash. Make it local just in case. - local OPTARG_AS_ARRAY - - while getopts "$MY_OPT_SPEC" OPTION_NAME; do - - case "$OPTION_NAME" in - - -) # This case triggers for options beginning with a double hyphen ('--'). - # If the user specified "--longOpt" , OPTARG is then "longOpt". - # If the user specified "--longOpt=xx", OPTARG is then "longOpt=xx". - - if [[ "$OPTARG" =~ .*=.* ]] # With this --key=value format, only one argument is possible. - then - - OPTION_NAME=${OPTARG/=*/} - OPTARG=${OPTARG#*=} - OPTARG_AS_ARRAY=("") - - if ! test "${USER_LONG_OPTIONS_SPEC[$OPTION_NAME]+string_returned_if_exists}"; then - abort "Unknown command-line option \"--$OPTION_NAME\"." - fi - - # Retrieve the number of arguments for this option. - OPT_ARG_COUNT=${USER_LONG_OPTIONS_SPEC[$OPTION_NAME]} - - if (( OPT_ARG_COUNT != 1 )); then - abort "Command-line option \"--$OPTION_NAME\" does not take 1 argument." - fi - - process_command_line_argument - - else # With this format, multiple arguments are possible, like in "--key value1 value2". - - OPTION_NAME="$OPTARG" - - if ! test "${USER_LONG_OPTIONS_SPEC[$OPTION_NAME]+string_returned_if_exists}"; then - abort "Unknown command-line option \"--$OPTION_NAME\"." - fi - - # Retrieve the number of arguments for this option. - OPT_ARG_COUNT=${USER_LONG_OPTIONS_SPEC[$OPTION_NAME]} - - if (( OPT_ARG_COUNT == 0 )); then - OPTARG="" - OPTARG_AS_ARRAY=("") - process_command_line_argument - elif (( OPT_ARG_COUNT == 1 )); then - # If this is the last option, and its argument is missing, then OPTIND is out of bounds. - if (( OPTIND > $# )); then - abort "Option '--$OPTION_NAME' expects one argument, but it is missing." - fi - OPTARG="${!OPTIND}" - OPTARG_AS_ARRAY=("") - process_command_line_argument - else - OPTARG="" - # OPTARG_AS_ARRAY is not standard in Bash. I have introduced it to make it clear that - # arguments are passed as an array in this case. It also prevents many Shellcheck warnings. - OPTARG_AS_ARRAY=("${@:OPTIND:OPT_ARG_COUNT}") - - if [ ${#OPTARG_AS_ARRAY[@]} -ne "$OPT_ARG_COUNT" ]; then - abort "Command-line option \"--$OPTION_NAME\" needs $OPT_ARG_COUNT arguments." - fi - - process_command_line_argument - fi; - - ((OPTIND+=OPT_ARG_COUNT)) - fi - ;; - - *) # This processes only single-letter options. - # getopts knows all valid single-letter command-line options, see USER_SHORT_OPTIONS_SPEC above. - # If it encounters an unknown one, it returns an option name of '?'. - if [[ "$OPTION_NAME" = "?" ]]; then - abort "Unknown command-line option \"$OPTARG\"." - else - # Process a valid single-letter option. - OPTARG_AS_ARRAY=("") - process_command_line_argument - fi - ;; - esac - done - - shift $((OPTIND-1)) - ARGS=("$@") -} - - -escape_for_meson_string () -{ - local STR="$1" - local -r RESULT_VAR_NAME="$2" - - if [[ $STR =~ [[:cntrl:]] ]]; then - abort "The argument to escape for a meson string contains ASCII control characters." - fi - - STR="${STR//\\/\\\\}" # Replace \ with \\ - STR="${STR//\'/\\\'}" # Replace ' with \' - - printf -v "$RESULT_VAR_NAME" "%s" "$STR" -} - - -# Examples of the 3 types of output: -# -# c_args = [] -# -# c_args = [ '-O2' ] -# -# c_args = [ -# '-g', -# '-O2' -# ] - -generate_setting_as_meson_array () -{ - local SETTING_NAME="$1" - local -n ARRAY="$2" # Create a reference to the array passed by name. - - local -i ARRAY_LEN="${#ARRAY[@]}" - - SETTING_AS_MESON_ARRAY="$SETTING_NAME = [" - - if (( ARRAY_LEN == 0 )); then - SETTING_AS_MESON_ARRAY+="]"$'\n' - return - fi - - local ESCAPED_ARG - - if (( ARRAY_LEN == 1 )); then - escape_for_meson_string "${ARRAY[0]}" "ESCAPED_ARG" - SETTING_AS_MESON_ARRAY+=" '${ESCAPED_ARG}' ]"$'\n' - return - fi - - SETTING_AS_MESON_ARRAY+=$'\n' - - local -i BASE_INDENTATION_LEN="$(( ${#SETTING_NAME} + 3 ))" - local BASE_INDENTATION - printf -v BASE_INDENTATION "%*s" "$BASE_INDENTATION_LEN" "" - - local -r EXTRA_INDENTATION=" " - - local -i INDEX - - for ((INDEX=0; INDEX < ARRAY_LEN; INDEX++)); do - - escape_for_meson_string "${ARRAY[$INDEX]}" "ESCAPED_ARG" - - SETTING_AS_MESON_ARRAY+="${BASE_INDENTATION}${EXTRA_INDENTATION}'$ESCAPED_ARG'" - - if (( INDEX != ARRAY_LEN - 1 )); then - SETTING_AS_MESON_ARRAY+="," - fi - - SETTING_AS_MESON_ARRAY+=$'\n' - - done - - SETTING_AS_MESON_ARRAY+="${BASE_INDENTATION}]"$'\n' -} - - -# If the command argument array is empty, no setting is generated. - -generate_command_setting () -{ - local SETTING_NAME="$1" - local ARRAY_NAME="$2" - - local -n ARRAY="$ARRAY_NAME" # Create a reference to the array passed by name. - - local -i ARRAY_LEN="${#ARRAY[@]}" - - if (( ARRAY_LEN == 0 )); then - COMMAND_SETTING="" - return - fi - - if (( ARRAY_LEN == 1 )); then - - # We could generate an array with just one element, but a string looks nicer. - # Other sibling settings like 'ar' or 'strip' are usually given as strings too. - - local ESCAPED_ARG - escape_for_meson_string "${ARRAY[0]}" "ESCAPED_ARG" - - COMMAND_SETTING="$SETTING_NAME = '${ESCAPED_ARG}'"$'\n' - return - fi - - local SETTING_AS_MESON_ARRAY - - generate_setting_as_meson_array "$SETTING_NAME" "$ARRAY_NAME" - - COMMAND_SETTING="$SETTING_AS_MESON_ARRAY" -} - - -# ----- Entry point ----- - -USER_SHORT_OPTIONS_SPEC="" - -# Use an associative array to declare how many arguments every long option expects. -# All known options must be listed, even those with 0 arguments. -declare -A USER_LONG_OPTIONS_SPEC -USER_LONG_OPTIONS_SPEC+=( [help]=0 ) -USER_LONG_OPTIONS_SPEC+=( [version]=0 ) -USER_LONG_OPTIONS_SPEC+=( [license]=0 ) -USER_LONG_OPTIONS_SPEC+=( [target-arch]=1 ) -USER_LONG_OPTIONS_SPEC+=( [cpu-family]=1 ) -USER_LONG_OPTIONS_SPEC+=( [cpu]=1 ) -USER_LONG_OPTIONS_SPEC+=( [system]=1 ) -USER_LONG_OPTIONS_SPEC+=( [endianness]=1 ) -USER_LONG_OPTIONS_SPEC+=( [c-compiler]=1 ) -USER_LONG_OPTIONS_SPEC+=( [linker]=1 ) -USER_LONG_OPTIONS_SPEC+=( [cflag]=1 ) -USER_LONG_OPTIONS_SPEC+=( [lflag]=1 ) -USER_LONG_OPTIONS_SPEC+=( [exewrap]=1 ) -USER_LONG_OPTIONS_SPEC+=( [meson-compat]=1 ) - -declare -a C_COMPILER=() -declare -a LINKER=() -declare -a CFLAGS_FOR_TARGET=() -declare -a LINKER_FLAGS_FOR_TARGET=() -declare -a EXE_WRAPPER=() - -TARGET_ARCH="" -CPU_FAMILY_NAME="" -CPU_NAME="" -ENDIANNESS="" -MESON_COMPATIBILITY="" - -# The system name is not really used by Meson. -SYSTEM_NAME="unknown-system" - -# The CPU name is not really used by Meson, see: -# https://github.com/mesonbuild/meson/issues/7037 - -parse_command_line_arguments "$@" - -if (( ${#ARGS[@]} != 0 )); then - abort "Invalid number of command-line arguments. Run this tool with the --help option for usage information." -fi - -if [[ $TARGET_ARCH = "" ]]; then - abort "Option --target-arch is required." -fi - -if [[ $CPU_FAMILY_NAME = "" ]]; then - CPU_FAMILY_NAME=`expr "$TARGET_ARCH" : '\([^-]*\)-.*'` -fi - -if [[ $ENDIANNESS = "" ]]; then - case "$CPU_FAMILY_NAME" in - arm*|aarch*|x86*|riscv*) - ENDIANNESS=little - ;; - 68*|sparc*) - ENDIANNESS=big - ;; - *) - abort "Option --endianness is required." - ;; - esac -fi - -if (( ${#C_COMPILER[@]} == 0)); then - C_COMPILER+=("$TARGET_ARCH-gcc") -fi - -if [[ "$CPU_NAME" = "" ]]; then - CPU_NAME="$CPU_FAMILY_NAME" -fi - -escape_for_meson_string "$TARGET_ARCH" "ESCAPED_TARGET_ARCH" -escape_for_meson_string "$SYSTEM_NAME" "ESCAPED_SYSTEM_NAME" -escape_for_meson_string "$CPU_FAMILY_NAME" "ESCAPED_CPU_FAMILY_NAME" -escape_for_meson_string "$CPU_NAME" "ESCAPED_CPU_NAME" -escape_for_meson_string "$ENDIANNESS" "ESCAPED_ENDIANNESS" - - -FILE_CONTENTS="" - -FILE_CONTENTS+="[binaries]"$'\n' - - -generate_command_setting "c" "C_COMPILER" - -FILE_CONTENTS+="$COMMAND_SETTING" - - -generate_command_setting "c_ld" "LINKER" - -FILE_CONTENTS+="$COMMAND_SETTING" - - -set +o errexit # When 'read' reaches end of file, a non-zero status code is returned. - -read -r -d '' PART_1 < 0 )); then - FILE_CONTENTS+="needs_exe_wrapper = true"$'\n' -fi - - -case "$MESON_COMPATIBILITY" in - - '') FILE_CONTENTS+=$'\n'"[built-in options]"$'\n';; - - 0.55) # Since Meson version 0.56.0, released on 2020-10-30, you get the following warning: - # DEPRECATION: c_args in the [properties] section of the machine file is deprecated, use the [built-in options] section. - # See this commit: https://github.com/mesonbuild/meson/pull/6597 - ;; - - *) abort "Unsupported value of --meson-compat: $MESON_COMPATIBILITY";; -esac - - -if (( ${#CFLAGS_FOR_TARGET[@]} > 0 )); then - - generate_setting_as_meson_array "c_args" "CFLAGS_FOR_TARGET" - - FILE_CONTENTS+="$SETTING_AS_MESON_ARRAY" - -fi - - -if (( ${#LINKER_FLAGS_FOR_TARGET[@]} > 0 )); then - - generate_setting_as_meson_array "c_link_args" "LINKER_FLAGS_FOR_TARGET" - - FILE_CONTENTS+="$SETTING_AS_MESON_ARRAY" - -fi - -echo -n "$FILE_CONTENTS" diff --git a/scripts/import-upstream.sh b/scripts/import-upstream.sh new file mode 100755 index 0000000..1799fe8 --- /dev/null +++ b/scripts/import-upstream.sh @@ -0,0 +1,180 @@ +#!/bin/bash +# +# import-upstream.sh - Import upstream picolibc commits with copyleft files +# filtered out. +# +# Usage: +# scripts/import-upstream.sh +# +# Arguments should be upstream picolibc version tags (e.g., 1.8.11, 1.9.0). +# +# Cherry-picks each upstream commit, removing copyleft files listed in +# COPYLEFT_EXCLUSIONS. Copyleft-only commits are skipped. Known fork +# divergences (deleted copyleft files, renamed README) are auto-resolved. + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +UPSTREAM_REMOTE="upstream" +UPSTREAM_URL="https://github.com/picolibc/picolibc.git" + +# Read exclusion paths into an associative array for O(1) lookup +declare -A EXCLUDED +declare -a EXCLUDED_PATHS +while IFS= read -r line; do + case "$line" in + "#"* | "") continue ;; + esac + EXCLUDED["$line"]=1 + EXCLUDED_PATHS+=("$line") +done <"${REPO_ROOT}/COPYLEFT_EXCLUSIONS" + +# Build pathspec exclude args for git diff-tree +PATHSPEC_EXCLUDES=() +for path in "${EXCLUDED_PATHS[@]}"; do + PATHSPEC_EXCLUDES+=(":(exclude)${path}") +done + +# Check if a file path is in the exclusion list. +is_excluded() { + [[ -n "${EXCLUDED[$1]+x}" ]] +} + +# Remove all excluded files from the git index and working tree. +remove_excluded_files() { + for path in "${EXCLUDED_PATHS[@]}"; do + git rm -rf --quiet "$path" 2>/dev/null || true + done +} + +# Return true if a commit touches at least one non-excluded file. +has_non_excluded_files() { + [ -n "$(git diff-tree --no-commit-id --name-only -r "$1" -- . "${PATHSPEC_EXCLUDES[@]}" 2>/dev/null)" ] +} + +# If a cherry-pick modifies README.md, redirect the upstream change to +# README.upstream.md and keep our fork README intact. +redirect_readme() { + commit="$1" + git diff --cached --name-only | grep -qx "README.md" || return 0 + + staged=$(git show :README.md 2>/dev/null || true) + ours=$(git show HEAD:README.md 2>/dev/null || true) + if [ "$staged" != "$ours" ]; then + git show "${commit}:README.md" >README.upstream.md 2>/dev/null || return 0 + git checkout HEAD -- README.md 2>/dev/null || true + git add README.md README.upstream.md + fi +} + +# Try to auto-resolve cherry-pick conflicts caused by known fork +# divergences: excluded files are deleted, README.md changes are +# redirected. Returns 1 if any conflict requires manual resolution. +try_auto_resolve() { + commit="$1" + conflicts=$(git diff --name-only --diff-filter=U 2>/dev/null || true) + if [ -z "$conflicts" ]; then + return 0 + fi + + while IFS= read -r file; do + if is_excluded "$file"; then + git rm --quiet "$file" 2>/dev/null || true + elif [ "$file" = "README.md" ]; then + git show "${commit}:README.md" >README.upstream.md 2>/dev/null || return 1 + git checkout --ours README.md 2>/dev/null || true + git add README.md README.upstream.md + else + echo "Manual resolution needed: $file" >&2 + return 1 + fi + done <<<"$conflicts" +} + +# Resolve a user-supplied ref to a commit SHA. Tries tag, remote +# branch, and bare SHA in that order. +resolve_ref() { + git rev-parse --verify "refs/tags/${1}^{commit}" 2>/dev/null || + git rev-parse --verify "${UPSTREAM_REMOTE}/${1}" 2>/dev/null || + git rev-parse --verify "${1}^{commit}" 2>/dev/null || + { + echo "Cannot resolve ref '${1}'" >&2 + exit 1 + } +} + +# Cherry-pick each upstream commit in the given range, filtering out +# copyleft files and auto-resolving known divergences. +main() { + if [ $# -ne 2 ]; then + echo "Usage: $0 " >&2 + exit 1 + fi + + cd "${REPO_ROOT}" + + if ! git remote get-url "${UPSTREAM_REMOTE}" >/dev/null 2>&1; then + git remote add "${UPSTREAM_REMOTE}" "${UPSTREAM_URL}" + fi + + git fetch "${UPSTREAM_REMOTE}" --tags --quiet + + from_sha=$(resolve_ref "$1") + to_sha=$(resolve_ref "$2") + + echo "Range: $1 (${from_sha:0:12}) .. $2 (${to_sha:0:12})" + + mapfile -t commits < <(git log --reverse --format="%H" "${from_sha}..${to_sha}") + total=${#commits[@]} + if [ "$total" -eq 0 ]; then + echo "No commits found in range $1..$2" >&2 + exit 1 + fi + + echo "Found ${total} commits to process" + + imported=0 + skipped=0 + + for i in "${!commits[@]}"; do + commit="${commits[$i]}" + subject=$(git log --format="%s" -1 "$commit") + echo "--- [$((i + 1))/${total}] ${commit:0:12} ${subject}" + + if ! has_non_excluded_files "$commit"; then + echo " Skipping (copyleft-only)" + skipped=$((skipped + 1)) + continue + fi + + if ! git cherry-pick --no-commit "$commit" 2>/dev/null; then + if ! try_auto_resolve "$commit"; then + echo "Unresolvable conflict on ${commit:0:12}." >&2 + echo "Fix manually, then re-run with remaining range." >&2 + exit 1 + fi + fi + + remove_excluded_files + redirect_readme "$commit" + + if git diff --cached --quiet 2>/dev/null; then + echo " Skipping (empty after filtering)" + git cherry-pick --abort 2>/dev/null || git reset --hard HEAD 2>/dev/null || true + skipped=$((skipped + 1)) + continue + fi + + orig_msg=$(git log --format="%B" -1 "$commit") + footer="(cherry picked from commit ${commit})" + GIT_AUTHOR_NAME=$(git log --format="%an" -1 "$commit") \ + GIT_AUTHOR_EMAIL=$(git log --format="%ae" -1 "$commit") \ + GIT_AUTHOR_DATE=$(git log --format="%aI" -1 "$commit") \ + git commit -m "$orig_msg" -m "$footer" --allow-empty-message 2>/dev/null + + imported=$((imported + 1)) + done + + echo "" + echo "Done! Imported: ${imported}, Skipped: ${skipped}" +} + +main "$@" diff --git a/test/test-stdio/test-printf-testcases.h b/test/test-stdio/test-printf-testcases.h deleted file mode 100644 index 2176c7c..0000000 --- a/test/test-stdio/test-printf-testcases.h +++ /dev/null @@ -1,821 +0,0 @@ -/* - * This file was generated from printf-tests.txt included - * as a part of the printf test suite developed by - * Bart Massey: - * - * https://github.com/BartMassey/printf-tests - * - * printf-tests.txt carries the following Copyright, which - * probably extends to this file as well given the transformations - * are fairly mechanical: - * -# Various printf tests compiled from various sources -# Copyright © 2013 Bart Massey -# This program is licensed under the GPL version 2 or later. -# Please see the file COPYING.GPL2 in this distribution for -# license terms. - -*/ - -#ifndef __PICOLIBC__ -#define __IO_C99_FORMATS -#define __IO_LONG_LONG -#define __IO_POS_ARGS -#else -#ifdef _HAS_IO_PERCENT_B -#define BINARY_FORMAT -#endif -#ifdef _HAS_IO_DOUBLE -#if __SIZEOF_DOUBLE__ == 4 -#define LOW_FLOAT -#endif -#elif defined(_HAS_IO_FLOAT) -#define LOW_FLOAT -#define FLOAT float -#else -#define NO_FLOAT -#endif -#ifndef _HAS_IO_LONG_DOUBLE -#define NO_LONGDOUBLE -#endif -#ifndef _HAS_IO_LONG_LONG -#define NO_LONGLONG -#endif -#ifndef _HAS_IO_POS_ARGS -#define NO_POS_ARGS -#endif -#ifndef _HAS_IO_WCHAR -#define NO_WCHAR -#endif -#ifndef _HAS_IO_MBCHAR -#define NO_MBCHAR -#endif -#if _PICOLIBC_PRINTF == 'm' -#define NO_WIDTH_PREC -#define NO_CASE_HEX -#endif -#endif - -#ifndef FLOAT -#define FLOAT double -#endif - -#if __SIZEOF_INT__ < 4 -#define I(a, b) (b) -#else -#define I(a, b) (a) -#endif - -//{ -/* XXX This code generated automatically by gen-testcases.hs - from ../../printf-tests.txt . You probably do not want to - manually edit this file. */ -#ifndef NO_FLOAT -result |= test(__LINE__, "0", "%.7g", printf_float(0.0)); -result |= test(__LINE__, "0.33", "%.*f", 2, printf_float(0.33333333)); -#endif -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "foo", "%.3s", "foobar"); -result |= test(__LINE__, " 00004", "%10.5d", 4); -result |= test(__LINE__, " 42", "% d", 42); -#endif -result |= test(__LINE__, "-42", "% d", -42); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " 42", "% 5d", 42); -result |= test(__LINE__, " -42", "% 5d", -42); -result |= test(__LINE__, " 42", "% 15d", 42); -result |= test(__LINE__, " -42", "% 15d", -42); -result |= test(__LINE__, "+42", "%+d", 42); -result |= test(__LINE__, "-42", "%+d", -42); -result |= test(__LINE__, " +42", "%+5d", 42); -result |= test(__LINE__, " -42", "%+5d", -42); -result |= test(__LINE__, " +42", "%+15d", 42); -result |= test(__LINE__, " -42", "%+15d", -42); -#endif -result |= test(__LINE__, "42", "%0d", 42); -result |= test(__LINE__, "-42", "%0d", -42); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "00042", "%05d", 42); -result |= test(__LINE__, "-0042", "%05d", -42); -result |= test(__LINE__, "000000000000042", "%015d", 42); -result |= test(__LINE__, "-00000000000042", "%015d", -42); -#endif -result |= test(__LINE__, "42", "%-d", 42); -result |= test(__LINE__, "-42", "%-d", -42); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "42 ", "%-5d", 42); -result |= test(__LINE__, "-42 ", "%-5d", -42); -result |= test(__LINE__, "42 ", "%-15d", 42); -result |= test(__LINE__, "-42 ", "%-15d", -42); -#endif -result |= test(__LINE__, "42", "%-0d", 42); -result |= test(__LINE__, "-42", "%-0d", -42); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "42 ", "%-05d", 42); -result |= test(__LINE__, "-42 ", "%-05d", -42); -result |= test(__LINE__, "42 ", "%-015d", 42); -result |= test(__LINE__, "-42 ", "%-015d", -42); -#endif -result |= test(__LINE__, "42", "%0-d", 42); -result |= test(__LINE__, "-42", "%0-d", -42); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "42 ", "%0-5d", 42); -result |= test(__LINE__, "-42 ", "%0-5d", -42); -result |= test(__LINE__, "42 ", "%0-15d", 42); -result |= test(__LINE__, "-42 ", "%0-15d", -42); -#endif -#ifndef NO_FLOAT -result |= test(__LINE__, "42.90", "%.2f", printf_float(42.8952)); -result |= test(__LINE__, "42.90", "%.2F", printf_float(42.8952)); -#ifdef LOW_FLOAT -result |= test(__LINE__, "42.89520", "%.5f", printf_float(42.8952)); -#else -result |= test(__LINE__, "42.8952000000", "%.10f", printf_float(42.8952)); -#endif -result |= test(__LINE__, "42.90", "%1.2f", printf_float(42.8952)); -result |= test(__LINE__, " 42.90", "%6.2f", printf_float(42.8952)); -result |= test(__LINE__, "+42.90", "%+6.2f", printf_float(42.8952)); -#ifdef LOW_FLOAT -result |= test(__LINE__, "42.89520", "%5.5f", printf_float(42.8952)); -#else -result |= test(__LINE__, "42.8952000000", "%5.10f", printf_float(42.8952)); -#endif -#endif /* NO_FLOAT */ -/* 51: anti-test */ -/* 52: anti-test */ -/* 53: excluded for C */ -#if !defined(NO_POS_ARGS) -result |= test(__LINE__, "Hot Pocket", "%1$s %2$s", "Hot", "Pocket"); -result |= test(__LINE__, "Pocket Hot", "%2$s %1$s", "Hot", "Pocket"); -result |= test(__LINE__, "0002 1 hi", "%2$04d %1$*3$d %4$s", 1, 2, 3, "hi"); -result |= test(__LINE__, " ab", "%1$*2$.*3$s", "abc", 5, 2); -#ifndef NO_FLOAT -result - |= test(__LINE__, "12.0 Hot Pockets", "%1$.1f %2$s %3$ss", printf_float(12.0), "Hot", "Pocket"); -result |= test(__LINE__, "12.0 Hot Pockets", "%1$.*4$f %2$s %3$ss", printf_float(12.0), "Hot", - "Pocket", 1); -result |= test(__LINE__, " 12.0 Hot Pockets", "%1$*5$.*4$f %2$s %3$ss", printf_float(12.0), "Hot", - "Pocket", 1, 5); -result |= test(__LINE__, " 12.0 Hot Pockets 5", "%1$5.*4$f %2$s %3$ss %5$d", printf_float(12.0), - "Hot", "Pocket", 1, 5); -#if !defined(__PICOLIBC__) || defined(__IO_FLOAT_EXACT) -result |= test(__LINE__, - " 12345 1234 11145401322 321.765400 3.217654e+02 5 test-string", - "%1$*5$d %2$*6$hi %3$*7$lo %4$*8$f %9$*12$e %10$*13$g %11$*14$s", 12345, 1234, - 1234567890, printf_float(321.7654), 8, 5, 14, 14, printf_float(321.7654), - printf_float(5.0000001), "test-string", 14, 3, 14); -#endif -#endif -#endif -/* 58: anti-test */ -#ifdef __PICOLIBC__ -result |= test(__LINE__, "%(foo", "%(foo"); -#endif -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " foo", "%*s", 4, "foo"); -#endif -#ifndef NO_FLOAT -result |= test(__LINE__, " 3.14", "%*.*f", 10, 2, printf_float(3.14159265)); -result |= test(__LINE__, "3.14 ", "%-*.*f", 10, 2, printf_float(3.14159265)); -#if !(defined(__PICOLIBC__) && !defined(__IO_FLOAT_EXACT)) -#ifndef LOW_FLOAT -#ifdef __PICOLIBC__ -#define SQRT2_60 "1414213562373095000000000000000000000000000000000000000000000.000" -#else -#define SQRT2_60 "1414213562373095053224405813183213153460812619236586568024064.000" -#endif -result |= test(__LINE__, SQRT2_60, "%.3f", printf_float(1.4142135623730950e60)); -#endif -#endif -#endif -/* 64: anti-test */ -/* 65: anti-test */ -result |= test(__LINE__, "+hello+", "+%s+", "hello"); -result |= test(__LINE__, "+10+", "+%d+", 10); -result |= test(__LINE__, "a", "%c", 'a'); -result |= test(__LINE__, " ", "%c", 32); -result |= test(__LINE__, "$", "%c", 36); -result |= test(__LINE__, "10", "%d", 10); - -#ifndef __NANO_FORMATTED_IO -result |= test(__LINE__, I("1000000", "16960"), "%'d", 1000000); -#endif -/* 72: anti-test */ -/* 73: anti-test */ -/* 74: excluded for C */ -/* 75: excluded for C */ -#ifndef NO_FLOAT -#ifdef LOW_FLOAT -result |= test(__LINE__, " +7.894561e+08", "%+#22.6e", printf_float(7.89456123e8)); -result |= test(__LINE__, "7.894561e+08 ", "%-#22.6e", printf_float(7.89456123e8)); -result |= test(__LINE__, " 7.894561e+08", "%#22.6e", printf_float(7.89456123e8)); -#else -result |= test(__LINE__, "+7.894561230000000e+08", "%+#22.15e", printf_float(7.89456123e8)); -result |= test(__LINE__, "7.894561230000000e+08 ", "%-#22.15e", printf_float(7.89456123e8)); -result |= test(__LINE__, " 7.894561230000000e+08", "%#22.15e", printf_float(7.89456123e8)); -#endif -result |= test(__LINE__, "8.e+08", "%#1.1g", printf_float(7.89456123e8)); -#endif -#ifndef NO_LONGLONG -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " +100", "%+8lld", 100LL); -result |= test(__LINE__, " +100", "%+8Ld", 100LL); -result |= test(__LINE__, "+00000100", "%+.8lld", 100LL); -result |= test(__LINE__, " +00000100", "%+10.8lld", 100LL); -#endif -result |= test(__LINE__, "%_1lld", "%_1lld", 100LL); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "-00100", "%-1.5lld", -100LL); -result |= test(__LINE__, " 100", "%5lld", 100LL); -result |= test(__LINE__, " -100", "%5lld", -100LL); -result |= test(__LINE__, "100 ", "%-5lld", 100LL); -result |= test(__LINE__, "-100 ", "%-5lld", -100LL); -result |= test(__LINE__, "00100", "%-.5lld", 100LL); -result |= test(__LINE__, "-00100", "%-.5lld", -100LL); -result |= test(__LINE__, "00100 ", "%-8.5lld", 100LL); -result |= test(__LINE__, "-00100 ", "%-8.5lld", -100LL); -result |= test(__LINE__, "00100", "%05lld", 100LL); -result |= test(__LINE__, "-0100", "%05lld", -100LL); -result |= test(__LINE__, " 100", "% lld", 100LL); -result |= test(__LINE__, "-100", "% lld", -100LL); -result |= test(__LINE__, " 100", "% 5lld", 100LL); -result |= test(__LINE__, " -100", "% 5lld", -100LL); -result |= test(__LINE__, " 00100", "% .5lld", 100LL); -result |= test(__LINE__, "-00100", "% .5lld", -100LL); -result |= test(__LINE__, " 00100", "% 8.5lld", 100LL); -result |= test(__LINE__, " -00100", "% 8.5lld", -100LL); -result |= test(__LINE__, "", "%.0lld", 0LL); -result |= test(__LINE__, " 0x00ffffffffffffff9c", "%#+21.18llx", -100LL); -result |= test(__LINE__, "0001777777777777777777634", "%#.25llo", -100LL); -result |= test(__LINE__, " 01777777777777777777634", "%#+24.20llo", -100LL); -result |= test(__LINE__, "0X00000FFFFFFFFFFFFFF9C", "%#+18.21llX", -100LL); -result |= test(__LINE__, "001777777777777777777634", "%#+20.24llo", -100LL); -result |= test(__LINE__, " 0018446744073709551615", "%#+25.22llu", -1LL); -result |= test(__LINE__, " 0018446744073709551615", "%#+25.22llu", -1LL); -result |= test(__LINE__, " 0000018446744073709551615", "%#+30.25llu", -1LL); -result |= test(__LINE__, " -0000000000000000000001", "%+#25.22lld", -1LL); -result |= test(__LINE__, "00144 ", "%#-8.5llo", 100LL); -result |= test(__LINE__, "+00100 ", "%#-+ 08.5lld", 100LL); -result |= test(__LINE__, "+00100 ", "%#-+ 08.5lld", 100LL); -result |= test(__LINE__, "0000000000000000000000000000000000000001", "%.40lld", 1LL); -result |= test(__LINE__, " 0000000000000000000000000000000000000001", "% .40lld", 1LL); -#endif -#endif -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " 0000000000000000000000000000000000000001", "% .40d", 1); -#endif -/* 121: excluded for C */ -/* 124: excluded for C */ -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " 1", "% d", 1); -result |= test(__LINE__, "+1", "%+ d", 1); -result |= test(__LINE__, "0x0000000001", "%#012x", 1); -result |= test(__LINE__, "0x00000001", "%#04.8x", 1); -result |= test(__LINE__, "0x01 ", "%#-08.2x", 1); -result |= test(__LINE__, "00000001", "%#08o", 1); -#endif -result |= test(__LINE__, "0x39", "%p", (void *)57ULL); -result |= test(__LINE__, "0x39", "%p", (void *)57U); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "f", "%.1s", "foo"); -result |= test(__LINE__, "f", "%.*s", 1, "foo"); -result |= test(__LINE__, "foo ", "%*s", -5, "foo"); -#endif -result |= test(__LINE__, "hello", "hello"); -#if defined(__PICOLIBC__) && !defined(_HAS_IO_PERCENT_B) -result |= test(__LINE__, "%b", "%b"); -#endif -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " a", "%3c", 'a'); -#endif -result |= test(__LINE__, "1234", "%3d", 1234); -/* 150: excluded for C */ -result |= test(__LINE__, "2", "%-1d", 2); -#ifndef NO_FLOAT -result |= test(__LINE__, "8.6000", "%2.4f", printf_float(8.6)); -result |= test(__LINE__, "0.600000", "%0f", printf_float(0.6)); -result |= test(__LINE__, "1", "%.0f", printf_float(0.6)); -result |= test(__LINE__, "0", "%.0f", printf_float(0.45)); -result |= test(__LINE__, "8.6000e+00", "%2.4e", printf_float(8.6)); -result |= test(__LINE__, " 8.6000e+00", "% 2.4e", printf_float(8.6)); -result |= test(__LINE__, "-8.6000e+00", "% 2.4e", printf_float(-8.6)); -result |= test(__LINE__, "+8.6000e+00", "%+2.4e", printf_float(8.6)); -result |= test(__LINE__, "8.6", "%2.4g", printf_float(8.6)); -#endif -result |= test(__LINE__, "-1", "%-i", -1); -result |= test(__LINE__, "1", "%-i", 1); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "+1", "%+i", 1); -#endif -result |= test(__LINE__, "12", "%o", 10); -/* 166: excluded for C */ -/* 167: excluded for C */ -result |= test(__LINE__, "(null)", "%s", NULL); -result |= test(__LINE__, "%%%%", "%s", "%%%%"); -result |= test(__LINE__, I("4294967295", "65535"), "%u", -1); -#ifdef __PICOLIBC__ -result |= test(__LINE__, "%w", "%w", -1); -#endif -/* 172: excluded for C */ -/* 173: excluded for C */ -/* 174: excluded for C */ -#ifdef __PICOLIBC__ -result |= test(__LINE__, "%H", "%H", -1); -#endif -result |= test(__LINE__, "%0", "%%0"); -result |= test(__LINE__, "2345", "%hx", 74565); -result |= test(__LINE__, "61", "%hhx", 0x61); -result |= test(__LINE__, "61", "%hhx", 0x161); -result |= test(__LINE__, "97", "%hhd", 0x61); -result |= test(__LINE__, "97", "%hhd", 0x161); -result |= test(__LINE__, "-97", "%hhd", -0x61); -result |= test(__LINE__, "-97", "%hhd", -0x161); -result |= test(__LINE__, "Hallo heimur", "Hallo heimur"); -result |= test(__LINE__, "Hallo heimur", "%s", "Hallo heimur"); -result |= test(__LINE__, "1024", "%d", 1024); -result |= test(__LINE__, "-1024", "%d", -1024); -result |= test(__LINE__, "1024", "%i", 1024); -result |= test(__LINE__, "-1024", "%i", -1024); -result |= test(__LINE__, "1024", "%u", 1024); -result |= test(__LINE__, I("4294966272", "64512"), "%u", 4294966272U); -result |= test(__LINE__, "777", "%o", 511); -result |= test(__LINE__, I("37777777001", "177001"), "%o", 4294966785U); -result |= test(__LINE__, I("1234abcd", "abcd"), "%x", 305441741); -result |= test(__LINE__, I("edcb5433", "5433"), "%x", 3989525555U); -result |= test(__LINE__, I("1234ABCD", "ABCD"), "%X", 305441741); -result |= test(__LINE__, I("EDCB5433", "5433"), "%X", 3989525555U); -#ifdef BINARY_FORMAT -result |= test(__LINE__, I("10010001101001010101111001101", "1010101111001101"), "%b", 305441741); -result - |= test(__LINE__, I("11101101110010110101010000110011", "101010000110011"), "%b", 3989525555U); -result |= test(__LINE__, I("10010001101001010101111001101", "1010101111001101"), "%B", 305441741); -result - |= test(__LINE__, I("11101101110010110101010000110011", "101010000110011"), "%B", 3989525555U); -#endif -result |= test(__LINE__, "x", "%c", 'x'); -result |= test(__LINE__, "%", "%%"); -result |= test(__LINE__, "Hallo heimur", "%+s", "Hallo heimur"); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "+1024", "%+d", 1024); -#endif -result |= test(__LINE__, "-1024", "%+d", -1024); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "+1024", "%+i", 1024); -#endif -result |= test(__LINE__, "-1024", "%+i", -1024); -result |= test(__LINE__, "1024", "%+u", 1024); -result |= test(__LINE__, I("4294966272", "64512"), "%+u", 4294966272U); -result |= test(__LINE__, "777", "%+o", 511); -result |= test(__LINE__, I("37777777001", "177001"), "%+o", 4294966785U); -result |= test(__LINE__, I("1234abcd", "abcd"), "%+x", 305441741); -result |= test(__LINE__, I("edcb5433", "5433"), "%+x", 3989525555U); -result |= test(__LINE__, I("1234ABCD", "ABCD"), "%+X", 305441741); -result |= test(__LINE__, I("EDCB5433", "5433"), "%+X", 3989525555U); -result |= test(__LINE__, "x", "%+c", 'x'); -result |= test(__LINE__, "Hallo heimur", "% s", "Hallo heimur"); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " 1024", "% d", 1024); -#endif -result |= test(__LINE__, "-1024", "% d", -1024); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " 1024", "% i", 1024); -#endif -result |= test(__LINE__, "-1024", "% i", -1024); -result |= test(__LINE__, "1024", "% u", 1024); -result |= test(__LINE__, I("4294966272", "64512"), "% u", 4294966272U); -result |= test(__LINE__, "777", "% o", 511); -result |= test(__LINE__, I("37777777001", "177001"), "% o", 4294966785U); -result |= test(__LINE__, I("1234abcd", "abcd"), "% x", 305441741); -result |= test(__LINE__, I("edcb5433", "5433"), "% x", 3989525555U); -result |= test(__LINE__, I("1234ABCD", "ABCD"), "% X", 305441741); -result |= test(__LINE__, I("EDCB5433", "5433"), "% X", 3989525555U); -result |= test(__LINE__, "x", "% c", 'x'); -result |= test(__LINE__, "Hallo heimur", "%+ s", "Hallo heimur"); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "+1024", "%+ d", 1024); -#endif -result |= test(__LINE__, "-1024", "%+ d", -1024); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "+1024", "%+ i", 1024); -#endif -result |= test(__LINE__, "-1024", "%+ i", -1024); -result |= test(__LINE__, "1024", "%+ u", 1024); -result |= test(__LINE__, I("4294966272", "64512"), "%+ u", 4294966272U); -result |= test(__LINE__, "777", "%+ o", 511); -result |= test(__LINE__, I("37777777001", "177001"), "%+ o", 4294966785U); -result |= test(__LINE__, I("1234abcd", "abcd"), "%+ x", 305441741); -result |= test(__LINE__, I("edcb5433", "5433"), "%+ x", 3989525555U); -result |= test(__LINE__, I("1234ABCD", "ABCD"), "%+ X", 305441741); -result |= test(__LINE__, I("EDCB5433", "5433"), "%+ X", 3989525555U); -result |= test(__LINE__, "x", "%+ c", 'x'); -result |= test(__LINE__, "0777", "%#o", 511); -result |= test(__LINE__, I("037777777001", "0177001"), "%#o", 4294966785U); -result |= test(__LINE__, I("0x1234abcd", "0xabcd"), "%#x", 305441741); -result |= test(__LINE__, I("0xedcb5433", "0x5433"), "%#x", 3989525555U); -#ifndef NO_CASE_HEX -result |= test(__LINE__, I("0X1234ABCD", "0XABCD"), "%#X", 305441741); -result |= test(__LINE__, I("0XEDCB5433", "0X5433"), "%#X", 3989525555U); -#endif -#ifdef BINARY_FORMAT -result - |= test(__LINE__, I("0b10010001101001010101111001101", "0b1010101111001101"), "%#b", 305441741); -result |= test(__LINE__, I("0b11101101110010110101010000110011", "0b101010000110011"), "%#b", - 3989525555U); -result - |= test(__LINE__, I("0B10010001101001010101111001101", "0B1010101111001101"), "%#B", 305441741); -result |= test(__LINE__, I("0B11101101110010110101010000110011", "0B101010000110011"), "%#B", - 3989525555U); -#endif -result |= test(__LINE__, "0", "%#o", 0U); -result |= test(__LINE__, "0", "%#x", 0U); -result |= test(__LINE__, "0", "%#X", 0U); -result |= test(__LINE__, "Hallo heimur", "%1s", "Hallo heimur"); -result |= test(__LINE__, "1024", "%1d", 1024); -result |= test(__LINE__, "-1024", "%1d", -1024); -result |= test(__LINE__, "1024", "%1i", 1024); -result |= test(__LINE__, "-1024", "%1i", -1024); -result |= test(__LINE__, "1024", "%1u", 1024); -result |= test(__LINE__, I("4294966272", "64512"), "%1u", 4294966272U); -result |= test(__LINE__, "777", "%1o", 511); -result |= test(__LINE__, I("37777777001", "177001"), "%1o", 4294966785U); -result |= test(__LINE__, I("1234abcd", "abcd"), "%1x", 305441741); -result |= test(__LINE__, I("edcb5433", "5433"), "%1x", 3989525555U); -result |= test(__LINE__, I("1234ABCD", "ABCD"), "%1X", 305441741); -result |= test(__LINE__, I("EDCB5433", "5433"), "%1X", 3989525555U); -result |= test(__LINE__, "x", "%1c", 'x'); -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, " Hallo", "%20s", "Hallo"); -result |= test(__LINE__, " 1024", "%20d", 1024); -result |= test(__LINE__, " -1024", "%20d", -1024); -result |= test(__LINE__, " 1024", "%20i", 1024); -result |= test(__LINE__, " -1024", "%20i", -1024); -result |= test(__LINE__, " 1024", "%20u", 1024); -result |= test(__LINE__, I(" 4294966272", " 64512"), "%20u", 4294966272U); -result |= test(__LINE__, " 777", "%20o", 511); -result |= test(__LINE__, I(" 37777777001", " 177001"), "%20o", 4294966785U); -result |= test(__LINE__, I(" 1234abcd", " abcd"), "%20x", 305441741); -result |= test(__LINE__, I(" edcb5433", " 5433"), "%20x", 3989525555U); -result |= test(__LINE__, I(" 1234ABCD", " ABCD"), "%20X", 305441741); -result |= test(__LINE__, I(" EDCB5433", " 5433"), "%20X", 3989525555U); -result |= test(__LINE__, " x", "%20c", 'x'); -result |= test(__LINE__, "Hallo ", "%-20s", "Hallo"); -result |= test(__LINE__, "1024 ", "%-20d", 1024); -result |= test(__LINE__, "-1024 ", "%-20d", -1024); -result |= test(__LINE__, "1024 ", "%-20i", 1024); -result |= test(__LINE__, "-1024 ", "%-20i", -1024); -result |= test(__LINE__, "1024 ", "%-20u", 1024); -result |= test(__LINE__, I("4294966272 ", "64512 "), "%-20u", 4294966272U); -result |= test(__LINE__, "777 ", "%-20o", 511); -result |= test(__LINE__, I("37777777001 ", "177001 "), "%-20o", 4294966785U); -result |= test(__LINE__, I("1234abcd ", "abcd "), "%-20x", 305441741); -result |= test(__LINE__, I("edcb5433 ", "5433 "), "%-20x", 3989525555U); -result |= test(__LINE__, I("1234ABCD ", "ABCD "), "%-20X", 305441741); -result |= test(__LINE__, I("EDCB5433 ", "5433 "), "%-20X", 3989525555U); -result |= test(__LINE__, "x ", "%-20c", 'x'); -result |= test(__LINE__, "00000000000000001024", "%020d", 1024); -result |= test(__LINE__, "-0000000000000001024", "%020d", -1024); -result |= test(__LINE__, "00000000000000001024", "%020i", 1024); -result |= test(__LINE__, "-0000000000000001024", "%020i", -1024); -result |= test(__LINE__, "00000000000000001024", "%020u", 1024); -result |= test(__LINE__, I("00000000004294966272", "00000000000000064512"), "%020u", 4294966272U); -result |= test(__LINE__, "00000000000000000777", "%020o", 511); -result |= test(__LINE__, I("00000000037777777001", "00000000000000177001"), "%020o", 4294966785U); -result |= test(__LINE__, I("0000000000001234abcd", "0000000000000000abcd"), "%020x", 305441741); -result |= test(__LINE__, I("000000000000edcb5433", "00000000000000005433"), "%020x", 3989525555U); -result |= test(__LINE__, I("0000000000001234ABCD", "0000000000000000ABCD"), "%020X", 305441741); -result |= test(__LINE__, I("000000000000EDCB5433", "00000000000000005433"), "%020X", 3989525555U); -result |= test(__LINE__, " 0777", "%#20o", 511); -result |= test(__LINE__, I(" 037777777001", " 0177001"), "%#20o", 4294966785U); -result |= test(__LINE__, I(" 0x1234abcd", " 0xabcd"), "%#20x", 305441741); -result |= test(__LINE__, I(" 0xedcb5433", " 0x5433"), "%#20x", 3989525555U); -result |= test(__LINE__, I(" 0X1234ABCD", " 0XABCD"), "%#20X", 305441741); -result |= test(__LINE__, I(" 0XEDCB5433", " 0X5433"), "%#20X", 3989525555U); -result |= test(__LINE__, "00000000000000000777", "%#020o", 511); -result |= test(__LINE__, I("00000000037777777001", "00000000000000177001"), "%#020o", 4294966785U); -result |= test(__LINE__, I("0x00000000001234abcd", "0x00000000000000abcd"), "%#020x", 305441741); -result |= test(__LINE__, I("0x0000000000edcb5433", "0x000000000000005433"), "%#020x", 3989525555U); -result |= test(__LINE__, I("0X00000000001234ABCD", "0X00000000000000ABCD"), "%#020X", 305441741); -result |= test(__LINE__, I("0X0000000000EDCB5433", "0X000000000000005433"), "%#020X", 3989525555U); -result |= test(__LINE__, "Hallo ", "%0-20s", "Hallo"); -result |= test(__LINE__, "1024 ", "%0-20d", 1024); -result |= test(__LINE__, "-1024 ", "%0-20d", -1024); -result |= test(__LINE__, "1024 ", "%0-20i", 1024); -result |= test(__LINE__, "-1024 ", "%0-20i", -1024); -result |= test(__LINE__, "1024 ", "%0-20u", 1024); -result |= test(__LINE__, I("4294966272 ", "64512 "), "%0-20u", 4294966272U); -result |= test(__LINE__, "777 ", "%-020o", 511); -result |= test(__LINE__, I("37777777001 ", "177001 "), "%-020o", 4294966785U); -result |= test(__LINE__, I("1234abcd ", "abcd "), "%-020x", 305441741); -result |= test(__LINE__, I("edcb5433 ", "5433 "), "%-020x", 3989525555U); -result |= test(__LINE__, I("1234ABCD ", "ABCD "), "%-020X", 305441741); -result |= test(__LINE__, I("EDCB5433 ", "5433 "), "%-020X", 3989525555U); -result |= test(__LINE__, "x ", "%-020c", 'x'); -result |= test(__LINE__, " Hallo", "%*s", 20, "Hallo"); -result |= test(__LINE__, " 1024", "%*d", 20, 1024); -result |= test(__LINE__, " -1024", "%*d", 20, -1024); -result |= test(__LINE__, " 1024", "%*i", 20, 1024); -result |= test(__LINE__, " -1024", "%*i", 20, -1024); -result |= test(__LINE__, " 1024", "%*u", 20, 1024); -result |= test(__LINE__, I(" 4294966272", " 64512"), "%*u", 20, 4294966272U); -result |= test(__LINE__, " 777", "%*o", 20, 511); -result |= test(__LINE__, I(" 37777777001", " 177001"), "%*o", 20, 4294966785U); -result |= test(__LINE__, I(" 1234abcd", " abcd"), "%*x", 20, 305441741); -result |= test(__LINE__, I(" edcb5433", " 5433"), "%*x", 20, 3989525555U); -result |= test(__LINE__, I(" 1234ABCD", " ABCD"), "%*X", 20, 305441741); -result |= test(__LINE__, I(" EDCB5433", " 5433"), "%*X", 20, 3989525555U); -result |= test(__LINE__, " x", "%*c", 20, 'x'); -result |= test(__LINE__, "Hallo heimur", "%.20s", "Hallo heimur"); -result |= test(__LINE__, "00000000000000001024", "%.20d", 1024); -result |= test(__LINE__, "-00000000000000001024", "%.20d", -1024); -result |= test(__LINE__, "00000000000000001024", "%.20i", 1024); -result |= test(__LINE__, "-00000000000000001024", "%.20i", -1024); -result |= test(__LINE__, "00000000000000001024", "%.20u", 1024); -result |= test(__LINE__, I("00000000004294966272", "00000000000000064512"), "%.20u", 4294966272U); -result |= test(__LINE__, "00000000000000000777", "%.20o", 511); -result |= test(__LINE__, I("00000000037777777001", "00000000000000177001"), "%.20o", 4294966785U); -result |= test(__LINE__, I("0000000000001234abcd", "0000000000000000abcd"), "%.20x", 305441741); -result |= test(__LINE__, I("000000000000edcb5433", "00000000000000005433"), "%.20x", 3989525555U); -result |= test(__LINE__, I("0000000000001234ABCD", "0000000000000000ABCD"), "%.20X", 305441741); -result |= test(__LINE__, I("000000000000EDCB5433", "00000000000000005433"), "%.20X", 3989525555U); -result |= test(__LINE__, " Hallo", "%20.5s", "Hallo heimur"); -result |= test(__LINE__, " 01024", "%20.5d", 1024); -result |= test(__LINE__, " -01024", "%20.5d", -1024); -result |= test(__LINE__, " 01024", "%20.5i", 1024); -result |= test(__LINE__, " -01024", "%20.5i", -1024); -result |= test(__LINE__, " 01024", "%20.5u", 1024); -result |= test(__LINE__, I(" 4294966272", " 64512"), "%20.5u", 4294966272U); -result |= test(__LINE__, " 00777", "%20.5o", 511); -result |= test(__LINE__, I(" 37777777001", " 177001"), "%20.5o", 4294966785U); -result |= test(__LINE__, I(" 1234abcd", " 0abcd"), "%20.5x", 305441741); -result |= test(__LINE__, I(" 00edcb5433", " 0000005433"), "%20.10x", 3989525555U); -result |= test(__LINE__, I(" 1234ABCD", " 0ABCD"), "%20.5X", 305441741); -result |= test(__LINE__, I(" 00EDCB5433", " 0000005433"), "%20.10X", 3989525555U); -result |= test(__LINE__, " 01024", "%020.5d", 1024); -result |= test(__LINE__, " -01024", "%020.5d", -1024); -result |= test(__LINE__, " 01024", "%020.5i", 1024); -result |= test(__LINE__, " -01024", "%020.5i", -1024); -result |= test(__LINE__, " 01024", "%020.5u", 1024); -result |= test(__LINE__, I(" 4294966272", " 64512"), "%020.5u", 4294966272U); -result |= test(__LINE__, " 00777", "%020.5o", 511); -result |= test(__LINE__, I(" 37777777001", " 177001"), "%020.5o", 4294966785U); -result |= test(__LINE__, I(" 1234abcd", " 0abcd"), "%020.5x", 305441741); -result - |= test(__LINE__, I(" 00edcb5433", " 0000005433"), "%020.10x", 3989525555U); -result |= test(__LINE__, I(" 1234ABCD", " 0ABCD"), "%020.5X", 305441741); -result - |= test(__LINE__, I(" 00EDCB5433", " 0000005433"), "%020.10X", 3989525555U); -result |= test(__LINE__, "", "%.0s", "Hallo heimur"); -result |= test(__LINE__, " ", "%20.0s", "Hallo heimur"); -result |= test(__LINE__, "", "%.s", "Hallo heimur"); -result |= test(__LINE__, " ", "%20.s", "Hallo heimur"); -result |= test(__LINE__, " 1024", "%20.0d", 1024); -result |= test(__LINE__, " -1024", "%20.d", -1024); -result |= test(__LINE__, " ", "%20.d", 0); -result |= test(__LINE__, " 1024", "%20.0i", 1024); -result |= test(__LINE__, " -1024", "%20.i", -1024); -result |= test(__LINE__, " ", "%20.i", 0); -result |= test(__LINE__, " 1024", "%20.u", 1024); -result |= test(__LINE__, I(" 4294966272", " 64512"), "%20.0u", 4294966272U); -result |= test(__LINE__, " ", "%20.u", 0U); -result |= test(__LINE__, " 777", "%20.o", 511); -result |= test(__LINE__, I(" 37777777001", " 177001"), "%20.0o", 4294966785U); -result |= test(__LINE__, " ", "%20.o", 0U); -result |= test(__LINE__, I(" 1234abcd", " abcd"), "%20.x", 305441741); -result |= test(__LINE__, I(" edcb5433", " 5433"), "%20.0x", 3989525555U); -result |= test(__LINE__, " ", "%20.x", 0U); -result |= test(__LINE__, I(" 1234ABCD", " ABCD"), "%20.X", 305441741); -result |= test(__LINE__, I(" EDCB5433", " 5433"), "%20.0X", 3989525555U); -result |= test(__LINE__, " ", "%20.X", 0U); -result |= test(__LINE__, "Hallo ", "% -0+*.*s", 20, 5, "Hallo heimur"); -result |= test(__LINE__, "+01024 ", "% -0+*.*d", 20, 5, 1024); -result |= test(__LINE__, "-01024 ", "% -0+*.*d", 20, 5, -1024); -result |= test(__LINE__, "+01024 ", "% -0+*.*i", 20, 5, 1024); -result |= test(__LINE__, "-01024 ", "% 0-+*.*i", 20, 5, -1024); -result |= test(__LINE__, "01024 ", "% 0-+*.*u", 20, 5, 1024); -result |= test(__LINE__, I("4294966272 ", "64512 "), "% 0-+*.*u", 20, 5, - 4294966272U); -result |= test(__LINE__, "00777 ", "%+ -0*.*o", 20, 5, 511); -result |= test(__LINE__, I("37777777001 ", "177001 "), "%+ -0*.*o", 20, 5, - 4294966785U); -result |= test(__LINE__, I("1234abcd ", "0abcd "), "%+ -0*.*x", 20, 5, - 305441741); -result |= test(__LINE__, I("00edcb5433 ", "0000005433 "), "%+ -0*.*x", 20, 10, - 3989525555U); -result |= test(__LINE__, I("1234ABCD ", "0ABCD "), "% -+0*.*X", 20, 5, - 305441741); -result |= test(__LINE__, I("00EDCB5433 ", "0000005433 "), "% -+0*.*X", 20, 10, - 3989525555U); -result |= test(__LINE__, "hi x", "%*sx", -3, "hi"); -#endif -#ifndef NO_FLOAT -#ifndef NO_DENORM -result |= test(__LINE__, "1.000e-38", "%.3e", printf_float(1e-38)); -#ifndef LOW_FLOAT -result |= test(__LINE__, "1.000e-308", "%.3e", printf_float(1e-308)); -#endif -#endif -#endif -#ifndef __NANO_FORMATTED_IO -#ifndef NO_LONGLONG -result |= test(__LINE__, "1, 1", "%-*.llu, %-*.llu", 1, 1ULL, 1, 1ULL); -#endif -#endif -#ifndef NO_FLOAT -result |= test(__LINE__, "1e-09", "%g", printf_float(0.000000001)); -result |= test(__LINE__, "1e-08", "%g", printf_float(0.00000001)); -result |= test(__LINE__, "1e-07", "%g", printf_float(0.0000001)); -result |= test(__LINE__, "1e-06", "%g", printf_float(0.000001)); -result |= test(__LINE__, "0.0001", "%g", printf_float(0.0001)); -result |= test(__LINE__, "0.001", "%g", printf_float(0.001)); -result |= test(__LINE__, "0.01", "%g", printf_float(0.01)); -result |= test(__LINE__, "0.1", "%g", printf_float(0.1)); -result |= test(__LINE__, "1", "%g", printf_float(1.0)); -result |= test(__LINE__, "10", "%g", printf_float(10.0)); -result |= test(__LINE__, "100", "%g", printf_float(100.0)); -result |= test(__LINE__, "1000", "%g", printf_float(1000.0)); -result |= test(__LINE__, "10000", "%g", printf_float(10000.0)); -result |= test(__LINE__, "100000", "%g", printf_float(100000.0)); -result |= test(__LINE__, "1e+06", "%g", printf_float(1000000.0)); -result |= test(__LINE__, "1e+07", "%g", printf_float(10000000.0)); -result |= test(__LINE__, "1e+08", "%g", printf_float(100000000.0)); -result |= test(__LINE__, "10.0000", "%#.6g", printf_float(10.0)); -result |= test(__LINE__, "10", "%.6g", printf_float(10.0)); -result |= test(__LINE__, "10.00000000000000000000", "%#.22g", printf_float(10.0)); -#endif - -#ifndef NO_WIDTH_PREC -result |= test(__LINE__, "", "%.*s", 0, "123456"); -result |= test(__LINE__, "1234", "%.*s", 4, "123456"); -result |= test(__LINE__, "123456", "%.*s", -4, "123456"); -result |= test(__LINE__, "42", "%.*d", 0, 42); -result |= test(__LINE__, "000042", "%.*d", 6, 42); -result |= test(__LINE__, "42", "%.*d", -6, 42); -#endif -#ifndef NO_FLOAT -result |= test(__LINE__, "0", "%.*f", 0, printf_float(0.123)); -result |= test(__LINE__, "0.1", "%.*f", 1, printf_float(0.123)); -result |= test(__LINE__, "0.123000", "%.*f", -1, printf_float(0.123)); -#endif -#ifdef __IO_C99_FORMATS -{ - char c[64]; -#ifndef __IO_LONG_LONG - if (sizeof(intmax_t) <= sizeof(long)) -#endif -#ifndef __NANO_FORMATTED_IO -#ifndef NO_WIDTH_PREC - result |= test(__LINE__, " 42", "%4jd", (intmax_t)42L); -#endif - result |= test(__LINE__, "64", "%zu", sizeof c); - result |= test(__LINE__, "12", "%td", (c + 12) - c); -#else - (void)c; -#endif -#ifndef NO_FLOAT - result |= test(__LINE__, "0x1p+0", "%a", printf_float(0x1p+0)); - result |= test(__LINE__, "0x0p+0", "%a", printf_float(0.0)); - result |= test(__LINE__, "-0x0p+0", "%a", printf_float(-0.0)); - result |= test(__LINE__, "0x1.9p+4", "%.1a", printf_float(0x1.89p+4)); - result |= test(__LINE__, "0x1.8p+4", "%.1a", printf_float(0x1.88p+4)); - result |= test(__LINE__, "0x1.8p+4", "%.1a", printf_float(0x1.78p+4)); - result |= test(__LINE__, "0x1.7p+4", "%.1a", printf_float(0x1.77p+4)); - result |= test(__LINE__, "0x1.fffffep+126", "%a", printf_float(0x1.fffffep+126f)); - result |= test(__LINE__, "0x1.234564p-126", "%a", printf_float(0x1.234564p-126f)); - result |= test(__LINE__, "0x1.234566p-126", "%a", printf_float(0x1.234566p-126f)); - result |= test(__LINE__, "0X1.FFFFFEP+126", "%A", printf_float(0x1.fffffep+126f)); - result |= test(__LINE__, "0X1.234564P-126", "%A", printf_float(0x1.234564p-126f)); - result |= test(__LINE__, "0X1.234566P-126", "%A", printf_float(0x1.234566p-126f)); - result |= test(__LINE__, "0x1.6p+1", "%.1a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.68p+1", "%.2a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.679p+1", "%.3a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.678ap+1", "%.4a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.6789ap+1", "%.5a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.6789a0p+1", "%.6a", printf_float(0x1.6789ap+1f)); - result |= test(__LINE__, "0x1.ffp+1", "%.2a", printf_float(0x1.ffp+1f)); - result |= test(__LINE__, "0x2.0p+1", "%.1a", printf_float(0x1.ffp+1f)); - result |= test(__LINE__, "0x2p+4", "%.a", printf_float(24.0)); - result |= test(__LINE__, "0X2P+4", "%.A", printf_float(24.0)); - result |= test(__LINE__, "nan", "%a", printf_float(NAN)); - result |= test(__LINE__, "-nan", "%a", printf_float(-(FLOAT)NAN)); - result |= test(__LINE__, "inf", "%a", printf_float(INFINITY)); - result |= test(__LINE__, "-inf", "%a", printf_float(-INFINITY)); - result |= test(__LINE__, "NAN", "%A", printf_float(NAN)); - result |= test(__LINE__, "-NAN", "%A", printf_float(-(FLOAT)NAN)); - result |= test(__LINE__, "INF", "%A", printf_float(INFINITY)); - result |= test(__LINE__, "-INF", "%A", printf_float(-(FLOAT)INFINITY)); - -#ifndef NO_LONGDOUBLE -#if __LDBL_MANT_DIG__ == 64 - /* - * x86 and m68k 80-bit format fill the top - * hex digit so they generate a different result than - * regular formats - */ - result |= test(__LINE__, "0x8p-3", "%La", 0x1p+0l); - result |= test(__LINE__, "0x0p+0", "%La", 0x0p+0l); - result |= test(__LINE__, "-0x0p+0", "%La", -0x0p+0l); - result |= test(__LINE__, "0xc.4p+1", "%.1La", 0x1.89p+4l); - result |= test(__LINE__, "0xc.4p+1", "%.1La", 0x1.88p+4l); - result |= test(__LINE__, "0xb.cp+1", "%.1La", 0x1.78p+4l); - result |= test(__LINE__, "0xb.cp+1", "%.1La", 0x1.77p+4l); - result |= test(__LINE__, "0xf.fffffp+123", "%La", 0x1.fffffep+126l); - result |= test(__LINE__, "0x9.1a2b2p-129", "%La", 0x1.234564p-126l); - result |= test(__LINE__, "0x9.1a2b3p-129", "%La", 0x1.234566p-126l); - result |= test(__LINE__, "0XF.FFFFFP+123", "%LA", 0X1.FFFFFEP+126l); - result |= test(__LINE__, "0X9.1A2B2P-129", "%LA", 0X1.234564P-126l); - result |= test(__LINE__, "0X9.1A2B3P-129", "%LA", 0X1.234566P-126l); - result |= test(__LINE__, "0xb.4p-2", "%.1La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xb.3cp-2", "%.2La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xb.3c5p-2", "%.3La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xb.3c4dp-2", "%.4La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xb.3c4d0p-2", "%.5La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xb.3c4d00p-2", "%.6La", 0x1.6789ap+1l); - result |= test(__LINE__, "0xf.f8p-2", "%.2La", 0x1.ffp+1l); - result |= test(__LINE__, "0x1.0p+2", "%.1La", 0x1.ffp+1l); - result |= test(__LINE__, "0xcp+1", "%.La", 24.0l); - result |= test(__LINE__, "0XCP+1", "%.LA", 24.0l); -#else - result |= test(__LINE__, "0x1p+0", "%La", (long double)0x1p+0l); - result |= test(__LINE__, "0x0p+0", "%La", 0.0L); - result |= test(__LINE__, "-0x0p+0", "%La", -0.0L); - result |= test(__LINE__, "0x1.9p+4", "%.1La", 0x1.89p+4L); - result |= test(__LINE__, "0x1.8p+4", "%.1La", 0x1.88p+4L); - result |= test(__LINE__, "0x1.8p+4", "%.1La", 0x1.78p+4L); - result |= test(__LINE__, "0x1.7p+4", "%.1La", 0x1.77p+4L); - result |= test(__LINE__, "0x1.fffffep+126", "%La", (long double)0x1.fffffep+126); - result |= test(__LINE__, "0x1.234564p-126", "%La", (long double)0x1.234564p-126); - result |= test(__LINE__, "0x1.234566p-126", "%La", (long double)0x1.234566p-126); - result |= test(__LINE__, "0X1.FFFFFEP+126", "%LA", (long double)0x1.fffffep+126); - result |= test(__LINE__, "0X1.234564P-126", "%LA", (long double)0x1.234564p-126); - result |= test(__LINE__, "0X1.234566P-126", "%LA", (long double)0x1.234566p-126); - result |= test(__LINE__, "0x1.6p+1", "%.1La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.68p+1", "%.2La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.679p+1", "%.3La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.678ap+1", "%.4La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.6789ap+1", "%.5La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.6789a0p+1", "%.6La", (long double)0x1.6789ap+1); - result |= test(__LINE__, "0x1.ffp+1", "%.2La", (long double)0x1.ffp+1); - result |= test(__LINE__, "0x2.0p+1", "%.1La", (long double)0x1.ffp+1); - result |= test(__LINE__, "0x2p+4", "%.La", 24.0L); - result |= test(__LINE__, "0X2P+4", "%.LA", 24.0L); -#endif - result |= test(__LINE__, "nan", "%La", (long double)NAN); - result |= test(__LINE__, "-nan", "%La", (long double)-NAN); - result |= test(__LINE__, "inf", "%La", (long double)INFINITY); - result |= test(__LINE__, "-inf", "%La", (long double)-INFINITY); - result |= test(__LINE__, "NAN", "%LA", (long double)NAN); - result |= test(__LINE__, "-NAN", "%LA", (long double)-NAN); - result |= test(__LINE__, "INF", "%LA", (long double)INFINITY); - result |= test(__LINE__, "-INF", "%LA", (long double)-INFINITY); -#endif -#ifndef NO_DENORM -#ifdef LOW_FLOAT - result |= test(__LINE__, "0x0.000002p-126", "%a", printf_float(0x1p-149)); - result |= test(__LINE__, "0x0p-126", "%.a", printf_float(0x1p-127)); -#else - result |= test(__LINE__, "0x1.306efbp-98", "%a", printf_float(3752432815e-39)); - /* glibc and picolibc show denorms like this */ - result |= test(__LINE__, "0x0.0000000000001p-1022", "%a", printf_float(0x1p-1074)); - result |= test(__LINE__, "0x0p-1022", "%.a", printf_float(0x1p-1023)); - result - |= test(__LINE__, "0x1.fffffffffffffp+1022", "%a", printf_float(0x1.fffffffffffffp+1022)); - result - |= test(__LINE__, "0x1.23456789abcdep-1022", "%a", printf_float(0x1.23456789abcdep-1022)); - result - |= test(__LINE__, "0x1.23456789abcdfp-1022", "%a", printf_float(0x1.23456789abcdfp-1022)); - result - |= test(__LINE__, "0X1.FFFFFFFFFFFFFP+1022", "%A", printf_float(0x1.fffffffffffffp+1022)); - result - |= test(__LINE__, "0X1.23456789ABCDEP-1022", "%A", printf_float(0x1.23456789abcdep-1022)); - result - |= test(__LINE__, "0X1.23456789ABCDFP-1022", "%A", printf_float(0x1.23456789abcdfp-1022)); - result |= test(__LINE__, "0X1.D749096BB98C800P+8", "%.15A", printf_float(0x1.D749096BB98C8p+8)); -#endif -#endif -#endif - /* test %ls for wchar_t string */ - result |= testw(__LINE__, L"foo", L"%.3ls", L"foobar"); - /* test %s for mbchar string */ - result |= testw(__LINE__, L"foo", L"%.3s", "foobar"); - - wchar_t wc = 0x1234; - - /* test %lc for wchar_t */ - wchar_t wb[2] = { 0x1234, 0 }; - result |= testw(__LINE__, wb, L"%lc", wc); - - /* make sure %c truncates to char */ - wb[0] = 0x34; - result |= testw(__LINE__, wb, L"%c", wc); - -#ifndef NO_MBCHAR - wb[0] = 0x3330; - result |= testw(__LINE__, wb, L"%s", "㌰"); - result |= test(__LINE__, "$㌰$", "$%lc$", 0x3330); -#endif -#ifndef NO_WCHAR - result |= test(__LINE__, "foobar", "%ls", L"foobar"); - result |= test(__LINE__, "$c$", "$%lc$", L'c'); -#endif -} -#endif diff --git a/test/test-stdio/test-printf.c b/test/test-stdio/test-printf.c deleted file mode 100644 index 7425624..0000000 --- a/test/test-stdio/test-printf.c +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright © 2013 Bart Massey */ -/* This program is licensed under the GPL version 2 or later. - Please see the file COPYING.GPL2 in this distribution for - license terms. */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __PICOLIBC__ -#define printf_float(x) ((double)(x)) -#endif - -#define TEST_ASPRINTF - -#ifdef __PICOLIBC__ -#define TEST_ASNPRINTF -#endif - -#define PRINTF_BUF_SIZE 512 - -static char buf[PRINTF_BUF_SIZE]; -static wchar_t wbuf[PRINTF_BUF_SIZE]; - -static void -failmsg(int serial, char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - printf("test %d failed: ", serial); - vprintf(fmt, ap); - printf("\n"); - va_end(ap); -} - -#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __GNUC__ > 4) -#pragma GCC diagnostic ignored "-Wpragmas" -#pragma GCC diagnostic ignored "-Wunknown-warning-option" -/* 'bsize' is used directly with malloc/realloc which confuses -fanalyzer */ -#pragma GCC diagnostic ignored "-Wanalyzer-va-arg-type-mismatch" -#pragma GCC diagnostic ignored "-Wanalyzer-va-list-exhausted" -#endif - -static int -test(int serial, char *expect, char *fmt, ...) -{ - va_list ap; - char *abuf = NULL; - char *as = NULL; - va_start(ap, fmt); - int n; - int ret = 0; -#ifdef TEST_ASPRINTF - int an; - va_list aap; - va_copy(aap, ap); -#endif -#ifdef TEST_ASNPRINTF - static char as_buf[16]; - size_t as_len; - va_list aanp; - va_copy(aanp, ap); -#endif -#ifndef __IO_NO_FLOATING_POINT -#ifdef _HAS_IO_FLOAT - uint32_t dv; -#else - double dv; -#endif -#ifndef NO_LONG_DOUBLE - long double ldv; -#endif - char *star; - char *long_double; -#endif - switch (fmt[strlen(fmt) - 1]) { - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'a': - case 'A': -#ifdef __IO_NO_FLOATING_POINT - return 0; -#else - star = strchr(fmt, '*'); - long_double = strchr(fmt, 'L'); - if (star) { - if (strchr(star + 1, '*')) { - int iv1 = va_arg(ap, int); - int iv2 = va_arg(ap, int); -#ifndef NO_LONG_DOUBLE - if (long_double) { - ldv = va_arg(ap, long double); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, iv1, iv2, ldv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, iv1, iv2, ldv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, iv1, iv2, ldv); -#endif - } else -#endif - { - dv = va_arg(ap, __typeof(dv)); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, iv1, iv2, dv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, iv1, iv2, dv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, iv1, iv2, dv); -#endif - } - } else { - int iv = va_arg(ap, int); -#ifndef NO_LONG_DOUBLE - if (long_double) { - ldv = va_arg(ap, long double); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, iv, ldv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, iv, ldv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, iv, ldv); -#endif - } else -#endif - { - dv = va_arg(ap, __typeof(dv)); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, iv, dv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, iv, dv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, iv, dv); -#endif - } - } - } else { -#ifndef NO_LONG_DOUBLE - if (long_double) { - ldv = va_arg(ap, long double); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, ldv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, ldv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, ldv); -#endif - } else -#endif - { - dv = va_arg(ap, __typeof(dv)); - n = snprintf(buf, PRINTF_BUF_SIZE, fmt, dv); -#ifdef TEST_ASPRINTF - an = asprintf(&abuf, fmt, dv); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = asnprintf(as_buf, &as_len, fmt, dv); -#endif - } - } - break; -#endif - default: - n = vsnprintf(buf, PRINTF_BUF_SIZE, fmt, ap); -#ifdef TEST_ASPRINTF - an = vasprintf(&abuf, fmt, aap); -#endif -#ifdef TEST_ASNPRINTF - as_len = sizeof(as_buf); - as = vasnprintf(as_buf, &as_len, fmt, aanp); -#endif - break; - } - va_end(ap); - // printf("serial %d expect \"%s\" got \"%s\"\n", serial, expect, buf); - if (n >= PRINTF_BUF_SIZE) { - failmsg(serial, "buffer overflow"); - ret = 1; - } - if (n != (int)strlen(expect)) { - failmsg(serial, "expected \"%s\" (%d), got \"%s\" (%d)", expect, (int)strlen(expect), buf, - n); - ret = 1; - } - if (strcmp(buf, expect)) { - failmsg(serial, "expected \"%s\", got \"%s\"", expect, buf); - ret = 1; - } -#ifdef TEST_ASPRINTF - va_end(aap); - if (an != n) { - failmsg(serial, "asprintf return %d sprintf return %d", an, n); - ret = 1; - } - if (strcmp(abuf, buf)) { - failmsg(serial, "sprintf return %s asprintf return %s", buf, abuf); - ret = 1; - } -#endif -#ifdef TEST_ASNPRINTF - va_end(aanp); - if (as_len != (size_t)n) { - failmsg(serial, "asnprintf return %d sprintf return %d", as_len, n); - ret = 1; - } - if (strcmp(as, buf)) { - failmsg(serial, "sprintf return %s asnprintf return %s", buf, as); - ret = 1; - } - if (as_len + 1 <= sizeof(as_buf)) { - if (as != as_buf) - failmsg(serial, "asnprintf shouldn't have allocated at %d\n", n); - } else { - if (as == as_buf) - failmsg(serial, "asnprintf should have allocated at %d\n", n); - } - if (as == as_buf) - as = NULL; -#endif - free(as); - free(abuf); - return ret; -} - -static void -failmsgw(int serial, wchar_t *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - printf("test %d failed: ", serial); - static wchar_t f_wbuf[PRINTF_BUF_SIZE]; - static char f_buf[PRINTF_BUF_SIZE]; - vswprintf(f_wbuf, PRINTF_BUF_SIZE, fmt, ap); - wcstombs(f_buf, f_wbuf, PRINTF_BUF_SIZE); - printf("%s\n", f_buf); - va_end(ap); -} - -static int -testw(int serial, wchar_t *expect, wchar_t *fmt, ...) -{ - va_list ap; - wchar_t *abuf = NULL; - va_start(ap, fmt); - int n; -#ifndef __IO_NO_FLOATING_POINT -#ifdef _HAS_IO_FLOAT - uint32_t dv; -#else - double dv; -#endif - wchar_t *star; -#endif - switch (fmt[wcslen(fmt) - 1]) { - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'a': - case 'A': -#ifdef __IO_NO_FLOATING_POINT - return 0; -#else - star = wcschr(fmt, '*'); - if (star) { - if (wcschr(star + 1, '*')) { - int iv1 = va_arg(ap, int); - int iv2 = va_arg(ap, int); - dv = va_arg(ap, __typeof(dv)); - n = swprintf(wbuf, PRINTF_BUF_SIZE, fmt, iv1, iv2, dv); - } else { - int iv = va_arg(ap, int); - dv = va_arg(ap, __typeof(dv)); - n = swprintf(wbuf, PRINTF_BUF_SIZE, fmt, iv, dv); - } - } else { - dv = va_arg(ap, __typeof(dv)); - n = swprintf(wbuf, PRINTF_BUF_SIZE, fmt, dv); - } - break; -#endif - default: - n = vswprintf(wbuf, PRINTF_BUF_SIZE, fmt, ap); - break; - } - va_end(ap); - // printf("serial %d expect \"%s\" got \"%s\"\n", serial, expect, wbuf); - if (n >= PRINTF_BUF_SIZE) { - failmsgw(serial, L"buffer overflow"); - free(abuf); - return 1; - } - if (n != (int)wcslen(expect)) { - failmsgw(serial, L"expected \"%s\" (%d), got \"%s\" (%d)", expect, wcslen(expect), wbuf, n); - free(abuf); - return 1; - } - if (wcscmp(wbuf, expect)) { - failmsgw(serial, L"expected \"%ls\", got \"%ls\"", expect, wbuf); - free(abuf); - return 1; - } - return 0; -} - -int -main(void) -{ - int result = 0; -#if !defined(__PICOLIBC__) || defined(__MB_CAPABLE) - if (!setlocale(LC_CTYPE, "C.UTF-8")) { - printf("setlocale(LC_CTYPE, \"C.UTF-8\") failed\n"); - return 1; - } -#endif -#include "test-printf-testcases.h" - return result; -}