diff --git a/.github/workflows/cpack-multi-platform.yml b/.github/workflows/cpack-multi-platform.yml index d90316a..0178565 100644 --- a/.github/workflows/cpack-multi-platform.yml +++ b/.github/workflows/cpack-multi-platform.yml @@ -5,16 +5,15 @@ on: branches: [ "main" ] jobs: - build: + package: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - build_type: [Release] - c_compiler: [gcc-13, clang, cl] + os: [ ubuntu-latest, windows-latest, macos-latest ] + c_compiler: [ gcc-13, clang, cl ] include: - os: windows-latest c_compiler: cl @@ -63,46 +62,32 @@ jobs: if [[ "${{ runner.os }}" == "Windows" ]]; then echo "generator='Visual Studio 17 2022'" >> "$GITHUB_OUTPUT" elif [[ "${{ runner.os }}" == "macOS" ]]; then - echo "generator='Xcode'" >> "$GITHUB_OUTPUT" + echo "generator=Xcode" >> "$GITHUB_OUTPUT" else - echo "generator='Ninja'" >> "$GITHUB_OUTPUT" + echo "generator=Ninja" >> "$GITHUB_OUTPUT" fi - - name: Configure CMake for Static Build + - name: Configure CMake run: > cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -S ${{ github.workspace }} -G ${{ steps.set-generator.outputs.generator }} - -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF - - - name: Build Static Library - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} -j 4 - - - name: Configure CMake for Shared Build - if: matrix.os != 'windows-latest' - run: > - cmake -B ${{ steps.strings.outputs.build-output-dir }} - -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} - -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -S ${{ github.workspace }} -G ${{ steps.set-generator.outputs.generator }} + -DCMAKE_BUILD_TYPE=Release -S ${{ github.workspace }} + -G ${{ steps.set-generator.outputs.generator }} -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF - - name: Build Shared Library - if: matrix.os != 'windows-latest' - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} -j 4 + - name: Build Shared Libraries + run: | + cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release -j 4 - name: Package working-directory: ${{ steps.strings.outputs.build-output-dir }} run: cpack - name: Upload Release Artifacts - if: matrix.build_type == 'Release' uses: actions/upload-artifact@v4 with: - name: "${{ matrix.os }}-${{ matrix.c_compiler }}-release" + name: "${{ runner.os }}-${{ matrix.c_compiler }}-release" path: "${{ steps.strings.outputs.build-output-dir }}/Packages" overwrite: true - if-no-files-found: 'warn' + if-no-files-found: 'error' diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f1517..ceb92cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,137 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +## [v1.0.0](https://github.com/dr8co/LiteString/compare/v0.1.0...v1.0.0) - 2024-05-01 + +### Commits + +- Apply function attributes [`510c822`](https://github.com/dr8co/LiteString/commit/510c82208eb7ce833265dac1875707b47531decc) +- Update the documentation [`14e378e`](https://github.com/dr8co/LiteString/commit/14e378e22e3bf1a8296ae6e7b144029c0c21734a) +- Update the installation prefix in the pkgConfig file [`7040d43`](https://github.com/dr8co/LiteString/commit/7040d437118804458f42fa50cef4bc01426b91b1) +- ci: Merge static and shared build [`36dff5e`](https://github.com/dr8co/LiteString/commit/36dff5eef59e230925136ebb55f04e114fd91ee9) +- Build shared libraries only [`9f3af74`](https://github.com/dr8co/LiteString/commit/9f3af743b0a830a8ff8b4694fe13e954122ae9fc) +- ci: Isolate Windows build [`3114404`](https://github.com/dr8co/LiteString/commit/3114404f46e29e9ba6f9382b1cb84189048e0492) +- ci: Static build on Windows [`4decb7d`](https://github.com/dr8co/LiteString/commit/4decb7ded878147c2f7ed30670975d5ee08a3173) +- build: Reconfigure optional builds [`f415fc8`](https://github.com/dr8co/LiteString/commit/f415fc84ae7eb9866dedfce16fc13cdaae0c1ff9) +- ci: Disable shared build on Windows [`23dc4b9`](https://github.com/dr8co/LiteString/commit/23dc4b90c3d683f36d988294efa270bad76c9c30) +- Configure MSVC Runtime Library [`3d61e75`](https://github.com/dr8co/LiteString/commit/3d61e75d77db1bf4f1af1509df6a8c9c017c9b6a) +- Update changelog [`e7a3fbc`](https://github.com/dr8co/LiteString/commit/e7a3fbc26d1fb26ad21f2be03641d7ba8483d774) +- ci: Build shared libraries on all platforms [`33cad8f`](https://github.com/dr8co/LiteString/commit/33cad8f8387de65369f2a5b7e362b4729d589eb0) +- Update build instructions [`d70fd59`](https://github.com/dr8co/LiteString/commit/d70fd59b21f1506b995d20f0744e6fd48661e0a5) +- Organize input files [`dec0c80`](https://github.com/dr8co/LiteString/commit/dec0c80eb37dc14565a1a5d6949848a21610e1bb) +- ci: Test the cpack workflow [`2214cf5`](https://github.com/dr8co/LiteString/commit/2214cf5931ccfe648f79e169a68d8af71130b6c1) +- Test Packaging [`1e1a7c5`](https://github.com/dr8co/LiteString/commit/1e1a7c5212b86df158a7b3d4ca46161533e4df53) +- Disable unreleased versions [`c04225c`](https://github.com/dr8co/LiteString/commit/c04225cff5b20f2d4184ef6d3539398edd913b33) +- ci: Disable shared build on Windows [`dc6340c`](https://github.com/dr8co/LiteString/commit/dc6340c57f793f7bd6bcf7421cdd4b178dfa8497) +- Update the table of contents [`19ba0d3`](https://github.com/dr8co/LiteString/commit/19ba0d383f25001e7ef70fb41896abe79ebb7aa2) +- Fix a typo in the pcfonfig template file [`c7625a1`](https://github.com/dr8co/LiteString/commit/c7625a1aca84ff429cd4b4e16413d57393923281) +- ci: Build shared libraries only [`7017605`](https://github.com/dr8co/LiteString/commit/701760534cd1d8e179b58f34e2e0600da8bf369a) +- Diagnostics [`e3acf0d`](https://github.com/dr8co/LiteString/commit/e3acf0db808b2da37132a4865624f81606370b29) +- doc: fix typo in README.md [`d530060`](https://github.com/dr8co/LiteString/commit/d530060047cb40d4be2f2b21f3041e6d0b0c7301) +- Disable shared build on Windows [`1b32881`](https://github.com/dr8co/LiteString/commit/1b32881fbe2624b05942a15cefe691adc4ba178b) + ## v0.1.0 - 2024-04-29 -Initial Pre-Release. +### Commits + +- Break down the tests [`198d410`](https://github.com/dr8co/LiteString/commit/198d410313bf348eb3a6bdf2d02d1fef0f3f5c57) +- Regress back to a normal library [`7d806f5`](https://github.com/dr8co/LiteString/commit/7d806f554e3bc290716f06540480c7478c5c4316) +- Make the library header-only [`162a0a8`](https://github.com/dr8co/LiteString/commit/162a0a8ae231ff9b94ab6c87a820af583f54e780) +- Import initial code from https://github.com/dr8co/Cachetron [`0fa6f8b`](https://github.com/dr8co/LiteString/commit/0fa6f8b4e3501da0d309d05b6a95b5d9e8400c10) +- Use Google Test Suite for testing [`56a2a9e`](https://github.com/dr8co/LiteString/commit/56a2a9efa34410a80aa790c871ec4550665d196d) +- Add a README.md for examples [`1a5b15a`](https://github.com/dr8co/LiteString/commit/1a5b15af2d21ff5d6e93ea5007429c4c909505fe) +- Initialize the project [`c513c43`](https://github.com/dr8co/LiteString/commit/c513c43000ca4aaebd56ce4e83bdc96da26d3be1) +- Add conversion functions [`56ea64b`](https://github.com/dr8co/LiteString/commit/56ea64b01b4a3dfc4f89c4612ecb40f081577241) +- Test the newly added methods [`3a24fa4`](https://github.com/dr8co/LiteString/commit/3a24fa4e5bca1b0b4220f577ff37856a560fb1cd) +- Update the library documentation [`1e12748`](https://github.com/dr8co/LiteString/commit/1e127480ba21547b4ea85c52396fedb3d9e60be0) +- Refactor tests [`e8739ab`](https://github.com/dr8co/LiteString/commit/e8739abf268d7bb27b0eff06231322142bd09cdd) +- Add tests for untested functions [`75853de`](https://github.com/dr8co/LiteString/commit/75853de13a04263667ee385ac24f6922e6a9927d) +- Match substrings using the Knuth-Morris-Pratt algorithm [`2506f5e`](https://github.com/dr8co/LiteString/commit/2506f5e1facfd46c6452fb2b300019c64b45c03b) +- Mark functions with attributes [`7067b12`](https://github.com/dr8co/LiteString/commit/7067b1233c6dc9e3853ee910893607e472d74442) +- Outline the contribution guidelines [`76c4592`](https://github.com/dr8co/LiteString/commit/76c45927896862792926458906aad37b5444c5e3) +- Add new methods [`d3c73e4`](https://github.com/dr8co/LiteString/commit/d3c73e4931a664cef10c3ec55ec76c0967698e56) +- Document the API [`5e87c54`](https://github.com/dr8co/LiteString/commit/5e87c5416c39abbc7d45d6ef9cda97987930fbc5) +- Declare the functions inline [`0f6d106`](https://github.com/dr8co/LiteString/commit/0f6d106cc6c9cbc392aceab7344ee2f309e49665) +- Update library information [`cf0d8f7`](https://github.com/dr8co/LiteString/commit/cf0d8f70e3f35163e30e3726edc2c4356e890bb5) +- Rename the modifiers test suite [`d52d092`](https://github.com/dr8co/LiteString/commit/d52d0929e7413c493df9073945d121dd25a6b93b) +- Add more specialized search functions [`104c87c`](https://github.com/dr8co/LiteString/commit/104c87c07fdddfdeaa758948720a55f5fa34af67) +- Add the community code of conduct [`3adf6ce`](https://github.com/dr8co/LiteString/commit/3adf6ce502d1a1723e485bbbb907de518685ab26) +- Rename the conversion test suite [`64c3c23`](https://github.com/dr8co/LiteString/commit/64c3c23c9c7cef6479138cd646bd3eb2304c1566) +- Optimize search methods [`12c3d65`](https://github.com/dr8co/LiteString/commit/12c3d65a207f4f2ccada4949530f11f1750654fe) +- Bugfix: Fix attribute availability detection [`32f28e8`](https://github.com/dr8co/LiteString/commit/32f28e83c1d01e4a68fa88e40b373049e26d8dee) +- Configure project packaging [`034d507`](https://github.com/dr8co/LiteString/commit/034d5076ba5a79c40fd307b72ea332a5cf770430) +- Update function signatures [`95eb806`](https://github.com/dr8co/LiteString/commit/95eb80697d8d866858ee651e31da3fd62df3d5ae) +- Add package generation CI [`0bead51`](https://github.com/dr8co/LiteString/commit/0bead5142b1ac8ef21d71fbfbe69f36a8499ff82) +- Reconfigure CPack settings [`ca068e0`](https://github.com/dr8co/LiteString/commit/ca068e0a9132b2f85094f0ab0fd6c8ed4deadb72) +- Rename functions appropriately [`da8c344`](https://github.com/dr8co/LiteString/commit/da8c3444968ccb4cb7e84e2d49d28263ebb65c12) +- Add a C++ example: simple grep [`4accd1a`](https://github.com/dr8co/LiteString/commit/4accd1ababcdc489d38bf54f0139fafdbb715532) +- Add a C example [`f31e937`](https://github.com/dr8co/LiteString/commit/f31e93700368f82cf22dfe4b00edcfbc448d60e4) +- Configure installation of the library [`2358bb7`](https://github.com/dr8co/LiteString/commit/2358bb711ac08fe7fe64c4eec9597b30f3219a2c) +- Disable testing with Homebrew GCC on macOS [`e3a6886`](https://github.com/dr8co/LiteString/commit/e3a688626420f58948d5e23d83836e66a050f8dd) +- Upgrade attributes' compatibility with pre-C23 stds [`4551940`](https://github.com/dr8co/LiteString/commit/455194069c98edec59801c8274becb978b868258) +- Create cmake multi-platform CI workflow [`49fc9ba`](https://github.com/dr8co/LiteString/commit/49fc9ba9a9fd06a67fe47f6251a24516c4cbf769) +- Rename the operations test suite [`488d18a`](https://github.com/dr8co/LiteString/commit/488d18a477672bad89472494e79e974ae11aea3c) +- Update the CI workflow [`ea08c96`](https://github.com/dr8co/LiteString/commit/ea08c96b388065fb0a1c6e25a8b341eae7ff1c4e) +- Use smart pointers to manage `lite_string` resources [`b079f38`](https://github.com/dr8co/LiteString/commit/b079f383fe98bf83e8f3a9ae5e1bcb417a64b3dc) +- Refactor for MSVC compatibility [`1bd6dc6`](https://github.com/dr8co/LiteString/commit/1bd6dc6497b9d06cd5dd046d4eb46a82c02eecb4) +- Refactor CMakeLists.txt [`485e9c2`](https://github.com/dr8co/LiteString/commit/485e9c202286227bc00dc5b02dd6c12697b4f79f) +- Eliminate redundant memory allocation by `string_cstr()` [`275d3a7`](https://github.com/dr8co/LiteString/commit/275d3a7ea3f8015f79f1242b10bf0ff52eaff1d0) +- Update README.md sections [`91a16df`](https://github.com/dr8co/LiteString/commit/91a16df8b7d2d9af6361c8086b854eaf8dbbd75c) +- Reserve enough space for null termination [`34b10d3`](https://github.com/dr8co/LiteString/commit/34b10d3d33b2fb071ad17145b0e5be3489edf32e) +- Update README.md [`a957419`](https://github.com/dr8co/LiteString/commit/a9574199230c51430b6be8da0be937a554fc5f9f) +- Update search tests [`0542dee`](https://github.com/dr8co/LiteString/commit/0542dee8a89ee59c20d2d3c21de8a463ca5befbf) +- MSVC and Clang-cl compatibility [`01fc49f`](https://github.com/dr8co/LiteString/commit/01fc49fb9305a144f7b778ad9ed7b0ac9cacffe0) +- Update behavior to always find empty strings in valid strings [`bf335cc`](https://github.com/dr8co/LiteString/commit/bf335cce3e53dad7796393ece8980ad8958fab63) +- Hide the `lite_string` structure from the user [`3eb9395`](https://github.com/dr8co/LiteString/commit/3eb9395fffc40630417c17c4882ec570663abdf0) +- Refactor examples [`460ad82`](https://github.com/dr8co/LiteString/commit/460ad826429ef166b6103c646a4a12a44d3a6f21) +- Configure InnoSetup installer [`11ad197`](https://github.com/dr8co/LiteString/commit/11ad197ff68a49e0008af7e4a219861191c064e5) +- Update the copyright notice [`d546fa9`](https://github.com/dr8co/LiteString/commit/d546fa96b7c1035562a90f30b4f2f13e211c9494) +- Add an option to disable the 'restrict' keyword [`217227d`](https://github.com/dr8co/LiteString/commit/217227d92d7027c66f56c70a82b8a3127361f9ab) +- Add README table of contents [`da4ef2b`](https://github.com/dr8co/LiteString/commit/da4ef2b7315351100a0ab517b3852e58bc4d2f71) +- Refactor CMakeLists.txt [`0ad9231`](https://github.com/dr8co/LiteString/commit/0ad92311b6c9e45c158fafdd8a45f208d5d48bbf) +- Set up tests [`c2d084c`](https://github.com/dr8co/LiteString/commit/c2d084c42f1ae429c9426f22724a8497c1bd4ec7) +- Rename and refactor the general test suite [`7bc2df9`](https://github.com/dr8co/LiteString/commit/7bc2df9570d5575d33a93b819acc7e52d2ef0e2a) +- Update examples' compatibility with MSVC [`d5a63eb`](https://github.com/dr8co/LiteString/commit/d5a63ebbf762fa0ae6893ca2e2219f2bf34d23d9) +- Set up component install [`6d71fa1`](https://github.com/dr8co/LiteString/commit/6d71fa1e9dfe9105198aef784d360e8f58c83fa5) +- Rename the search test suite [`622383c`](https://github.com/dr8co/LiteString/commit/622383c792135b304e72d38c9bc4a3f0ade27c0b) +- Configure installation of version_info.txt [`2119ce1`](https://github.com/dr8co/LiteString/commit/2119ce1e7eb1e0673da59d89c5d9bdb2866beb07) +- Rename the compiled library [`6a06f58`](https://github.com/dr8co/LiteString/commit/6a06f589be4a244cff5dba66ea9a9baf552a7605) +- Update MSVC compatibility [`3097c3d`](https://github.com/dr8co/LiteString/commit/3097c3dc2640709f41f7d86a70fe7bd93ba9b0e7) +- License the library under the MIT license [`121cf67`](https://github.com/dr8co/LiteString/commit/121cf67497ebef014d220980c911e964b0eb062c) +- Apply appropriate function attributes [`fdfe4ed`](https://github.com/dr8co/LiteString/commit/fdfe4ed0d96cf5c0947402974d9babe570aa1c2d) +- Eliminate redundant packaging in tests CI [`542e7e6`](https://github.com/dr8co/LiteString/commit/542e7e626e75d30a8cd354a8e47ab85579a45db2) +- Fix CI workflow errors [`1b927b0`](https://github.com/dr8co/LiteString/commit/1b927b0cf22f65590b4f1ec5a14894b0706cb25a) +- Refactor examples [`785ddca`](https://github.com/dr8co/LiteString/commit/785ddca1055c5303e55afb28e40b8a260c38b542) +- Add README.md [`58f99e7`](https://github.com/dr8co/LiteString/commit/58f99e72b6fc0e3d286a35eabab83c439114f01e) +- Refactor `string_new_cstr()` [`bc0757a`](https://github.com/dr8co/LiteString/commit/bc0757ac52d70d6abae0f4c82cb0833271b81cfd) +- Enable sanitizers [`9a8000b`](https://github.com/dr8co/LiteString/commit/9a8000b9940fb94efdc31d5d1c7e00da9ceb369d) +- Purge NSIS settings [`94ed4b0`](https://github.com/dr8co/LiteString/commit/94ed4b094fe4f07979464bae74a18fc60f361093) +- Use bit manipulation to transform characters [`f6e1d3a`](https://github.com/dr8co/LiteString/commit/f6e1d3a1bd32228befe22f44c49e7cc7c3095e58) +- Use logos with rounded corners [`6661584`](https://github.com/dr8co/LiteString/commit/66615844930d380609083ada9827412e7863b8ba) +- Update examples' README.md [`d2ec3f2`](https://github.com/dr8co/LiteString/commit/d2ec3f256ae8e76db8074a16a1eb5f81ae7af5a8) +- Expose GNU extensions [`07b4a3f`](https://github.com/dr8co/LiteString/commit/07b4a3ffb576127a9cce296fe0c1396687cd3449) +- Configure examples [`22ca474`](https://github.com/dr8co/LiteString/commit/22ca4745e95304785369e486036d415311989ae3) +- Rename the structure [`67d4e6b`](https://github.com/dr8co/LiteString/commit/67d4e6b8e33e2946ba10097764a3bbb269badd6d) +- Update compatibility with MSVC [`dc2e5a4`](https://github.com/dr8co/LiteString/commit/dc2e5a403517fe975b3959653c7aa94e7c40bee7) +- Update the examples' README.md [`64e6967`](https://github.com/dr8co/LiteString/commit/64e69673e5685a18dbe37f533e82311421f6987b) +- Fix typos for optional execution paths [`fe97d66`](https://github.com/dr8co/LiteString/commit/fe97d66df68c1341292d8c8dc4d2fe6e2b621b01) +- Update macro names [`36c2ed5`](https://github.com/dr8co/LiteString/commit/36c2ed564220c8d8efba348e173ca5ff7e728e9e) +- Configure auto-changelog [`832a494`](https://github.com/dr8co/LiteString/commit/832a49455bd321522d53078646bab1c37b08ab9b) +- Configure imgbot to optimize images [`8c4022d`](https://github.com/dr8co/LiteString/commit/8c4022d2219d360a60b2bb65312403b259ab82fd) +- Fix -Wstatic-in-inline issues [`b2a55e2`](https://github.com/dr8co/LiteString/commit/b2a55e2596214e91b52cca3725a6a588fe9326dc) +- Typecast pointers for C++ compatibility [`8a32290`](https://github.com/dr8co/LiteString/commit/8a322908e7ee171af4e8c7b81cf023c72e69a74f) +- Add badges to README.md [`a30809a`](https://github.com/dr8co/LiteString/commit/a30809a6c250cbd07e29b487b836c4ef05f90ae8) +- Enable testing with Homebrew GCC on macOS [`e00bf72`](https://github.com/dr8co/LiteString/commit/e00bf728c1a1e2241d0c34b58ea61a488afde1b1) +- Update tests to conform with API changes [`30ba18f`](https://github.com/dr8co/LiteString/commit/30ba18fd1c40c64fcd2b1ece21e281894a2b4fb3) +- Update boolean definitions [`18bbfc6`](https://github.com/dr8co/LiteString/commit/18bbfc6a7fe7f68763192462bab7c719877b1d3d) +- Update compilation flags [`99d0a8a`](https://github.com/dr8co/LiteString/commit/99d0a8ad007e0bc7b9b5eee083e0f50911dc2aa6) +- Ignore the build directory and the Doxyfile [`a88da48`](https://github.com/dr8co/LiteString/commit/a88da487372bec97fd77064afcdcd99f8a57f6bc) +- Refactor sources for C++ and GTest compatibility [`1ef6f53`](https://github.com/dr8co/LiteString/commit/1ef6f5399f2c0e3e43c6651670c007026ac79dd2) +- Use clang++-15 for CI C++ compilation [`ad8238e`](https://github.com/dr8co/LiteString/commit/ad8238e71c090798d1c5588828f250a371723581) +- Define 'nullptr' for non-c23 compilers [`0d37ae5`](https://github.com/dr8co/LiteString/commit/0d37ae5167cd0a45ebda35cd98b230ab8697d653) +- Update packing options [`db729ff`](https://github.com/dr8co/LiteString/commit/db729ff7aef2304a14830cbb7aefc1b3556240c7) +- Update assets [`5a879b5`](https://github.com/dr8co/LiteString/commit/5a879b5ff71c8aaeffdcb34ca3a75e09a97b6ace) +- Fix a typo [`d4baa9d`](https://github.com/dr8co/LiteString/commit/d4baa9d9a689a68fabaf346c922f3b833671194e) +- Fix overflow issues [`20c2a84`](https://github.com/dr8co/LiteString/commit/20c2a848d164c2226cd22b6530f99a28eff07d60) +- Add the project changelog [`96d4fa6`](https://github.com/dr8co/LiteString/commit/96d4fa67ca3613fd21661a39aa936e94239ced75) +- Add additional media assets [`d58defb`](https://github.com/dr8co/LiteString/commit/d58defb5e56bae8d5b7c8bff59c0a3237b129753) diff --git a/CMakeLists.txt b/CMakeLists.txt index e45e532..75e4363 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.28) project(LiteString - VERSION 0.1.0 + VERSION 1.0.0 DESCRIPTION "A lightweight byte string library for C" HOMEPAGE_URL "https://github.com/dr8co/LiteString" LANGUAGES C CXX) @@ -20,7 +20,17 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Options option(BUILD_SHARED_LIBS "Build shared libraries" OFF) option(BUILD_EXAMPLES "Build examples" ON) -option(BUILD_TESTS "Build tests" ON) +option(BUILD_TESTING "Build tests" OFF) + +# MSVC Runtime Library and other settings +if (MSVC) + if (BUILD_SHARED_LIBS) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + else () + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif () +endif () # Additional compile options for the Debug build if (NOT MSVC AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang") @@ -60,7 +70,8 @@ if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang") endif () endif () -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +# Add the CMake module path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") add_library(lite-string) target_sources(lite-string PRIVATE lite_string.c) @@ -102,7 +113,7 @@ install(EXPORT LiteStringTargets include(CMakePackageConfigHelpers) -configure_package_config_file(LiteStringConfig.cmake.in +configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/input_files/LiteStringConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/LiteStringConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/LiteString") @@ -118,7 +129,8 @@ install(FILES COMPONENT CMakeConfig ) -configure_file(liblite-string.pc.in liblite-string.pc @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/input_files/liblite-string.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/liblite-string.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/liblite-string.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" @@ -139,7 +151,8 @@ string(TOUPPER "${FLAGS_VAR}" FLAGS_VAR) string(CONFIGURE "@${FLAGS_VAR}@" BUILD_FLAGS) # Configure the version_info.txt file -configure_file(version_info.txt.in "${CMAKE_CURRENT_BINARY_DIR}/version_info.txt" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/input_files/version_info.txt.in" + "${CMAKE_CURRENT_BINARY_DIR}/version_info.txt" @ONLY) # Install the version_info.txt file install(FILES "${CMAKE_CURRENT_BINARY_DIR}/version_info.txt" @@ -153,7 +166,7 @@ if (BUILD_EXAMPLES) endif () # Testing -if (BUILD_TESTS) +if (BUILD_TESTING) include(FetchContent) FetchContent_Declare( googletest diff --git a/ConfigurePkgConfig.pas b/ConfigurePkgConfig.pas new file mode 100644 index 0000000..0ab17d5 --- /dev/null +++ b/ConfigurePkgConfig.pas @@ -0,0 +1,43 @@ +var + AppPath: string; + +procedure ReplacePlaceholderInPkgConfig; +var + PkgConfigFile: TStringList; + Index: Integer; + ModifiedAppPath: string; +begin + // Read the contents of the liblite-string.pc file + PkgConfigFile := TStringList.Create; + try + PkgConfigFile.LoadFromFile(ExpandConstant('{app}\lib\pkgconfig\liblite-string.pc')); + + // Modify the installation prefix to match the chosen installation destination + if PkgConfigFile.Count > 0 then + begin + // Replace backslashes with forward slashes + ModifiedAppPath := ''; + for Index := 1 to Length(AppPath) do + begin + if AppPath[Index] = '\' then + ModifiedAppPath := ModifiedAppPath + '/' + else + ModifiedAppPath := ModifiedAppPath + AppPath[Index]; + end; + // Update the prefix + PkgConfigFile[0] := 'prefix = "' + ModifiedAppPath + '"'; + end; + + // Write the modified contents back to the file + PkgConfigFile.SaveToFile(ExpandConstant('{app}\lib\pkgconfig\liblite-string.pc')); + finally + PkgConfigFile.Free; + end; +end; + +// Run after the installation has completed +procedure DeinitializeSetup(); +begin + AppPath := ExpandConstant('{app}'); + ReplacePlaceholderInPkgConfig; +end; diff --git a/README.md b/README.md index 9bacc2a..3c554cc 100644 --- a/README.md +++ b/README.md @@ -101,14 +101,15 @@ cmake --build build --config Release -j 4 Replace `Ninja` with `"Unix Makefiles"` or another generator if Ninja is not available. The `-G` option can be omitted to use the default generator. -To skip building tests and examples, add `-DBUILD_TESTS=OFF` and `-DBUILD_EXAMPLES=OFF` +To skip building tests and examples, add `-DBUILD_TESTING=OFF` and `-DBUILD_EXAMPLES=OFF` to the Configuration step: ```bash -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -G Ninja +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -G Ninja ``` -The library will be built in the `build` directory. +The library will be built in the `build` directory +(or `Release` subdirectory of the `build` directory, if using a multi-configuration generator). ### Building Manually @@ -136,8 +137,8 @@ or use the full path to the MinGW `gcc` and `ar` executables. For Visual Studio, use the Developer Command Prompt or Powershell: ```cmd -cl /c /O2 /std:clatest lite_string.c -lib /OUT:liblite-string.lib lite_string.obj +cl /c /O2 lite_string.c +lib /OUT:lite-string.lib lite_string.obj ``` `clang-cl` can be used instead of `cl` if available. @@ -163,7 +164,7 @@ or [MSYS2](https://www.msys2.org/ "MSYS2"), follow the [UNIX instructions](#unix For Visual Studio, use the Developer Command Prompt or Powershell: ```cmd -cl /c /O2 /std:clatest /LD lite_string.c +cl /c /O2 /LD lite_string.c link /DLL /OUT:lite-string.dll lite_string.obj ``` @@ -171,7 +172,7 @@ link /DLL /OUT:lite-string.dll lite_string.obj ### Installation -Pre-built binaries are available for Windows, Linux, and macOS are available on the +Pre-built binaries for Windows, Linux, and macOS are available on the [Releases](https://github.com/dr8co/LiteString/releases "LiteString Releases") page. The following packages are available: @@ -180,10 +181,12 @@ The following packages are available: |:--------------:|:-----------------------:|---------------------------------------| | win64.exe | Windows 64-bit | Self installing executable | | win64.zip | Windows 64-bit | Extraction to appropriate directories | -| x86_64.rpm | RPM-based Linux 64-bit | rpm installers, such as apt and dpkg | -| amd64.deb | DEB-based Linux 64-bit | deb installers, such as yum and dnf | +| minGW64.exe | MinGW-w64 Windows | Self installing executable | +| minGW64.zip | MinGW-w64 Windows | Extraction to appropriate directories | +| x86_64.rpm | RPM-based Linux, 64-bit | rpm installers, such as apt and dpkg | +| amd64.deb | DEB-based Linux, 64-bit | deb installers, such as yum and dnf | | Linux.tar.gz | Linux 64-bit | Extraction to appropriate directories | -| Darwin.dmg | macOS 64-bit | Drag and Drop | +| Darwin.dmg | macOS 64-bit | Drag and Drop to Applications | | Darwin.tar.gz | macOS 64-bit | Extraction to appropriate directories | SHA-256 checksums are provided for each package to verify the integrity of the files. @@ -192,12 +195,12 @@ Alternatively, you can install the library directly after [building with CMake](#building-with-cmake-recommended): ```bash -# Install from the build directory. +# Install from the build directory. Run this from the project root directory. cmake --install build --config Release ``` Escalation of privileges may be required to install the library system-wide. -Use `sudo` on UNIX or run the command prompt (or powershell) as an administrator on Windows. +Use `sudo` on UNIX or run the command prompt/PowerShell/Windows Terminal as an administrator on Windows. ### Uninstallation @@ -210,7 +213,7 @@ For UNIX, use the following command: ```bash # In the build directory, run: -xargs rm -f < install_manifest.txt # May require sudo +xargs rm -f < install_manifest.txt # May require sudo/escalation of privileges ``` For Windows, use the following command in the build directory: @@ -235,7 +238,7 @@ To use the library, include the header file in your source code: #include // or: #include "lite_string.h" -// Depending on whether the library was installed or not. +// Depending on the location of the header file. ... ``` @@ -247,6 +250,12 @@ To link the library with a CMake project, include the following lines in the `CM ```cmake ########### If the library was installed: ########### +# For Windows only: Update CMake module path. +list(APPEND CMAKE_MODULE_PATH "C:/path/to/LiteString/cmake") +# The path should point to the directory containing the LiteStringConfig.cmake file, depending on the installation. + +# In UNIX, the library installation path is usually scanned automatically. + # Locate the required files. find_package(LiteString REQUIRED) @@ -256,6 +265,7 @@ target_link_libraries(yourTarget LiteString::lite-string) ######## If the library was built manually, or is not installed: ######## # Add the library to the project. add_library(LiteString STATIC IMPORTED) +# Set the path to the library. For Windows, use the .lib file. set_target_properties(LiteString PROPERTIES IMPORTED_LOCATION /path/to/libLiteString.a) # Link the library to the target. @@ -288,10 +298,10 @@ On Windows: ```powershell # C -cl /O2 /std:clatest example.c /OUT:example.exe /link /LIBPATH:"C:\path\to\built\library" liblite-string.lib +cl /O2 example.c /OUT:example.exe /link /LIBPATH:"C:\path\to\built\library" lite-string.lib # C++ -cl /O2 /std:c++20 example.cpp /OUT:example.exe /link /LIBPATH:"C:\path\to\built\library" liblite-string.lib +cl /O2 /std:c++20 /EHsc example.cpp /OUT:example.exe /link /LIBPATH:"C:\path\to\built\library" lite-string.lib ``` ## API diff --git a/cmake/Packing.cmake b/cmake/Packing.cmake index d7f8da0..cb4bd11 100644 --- a/cmake/Packing.cmake +++ b/cmake/Packing.cmake @@ -54,7 +54,7 @@ set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Headers") set(CPACK_COMPONENT_HEADERS_DESCRIPTION "Header files for LiteString.") set(CPACK_COMPONENT_HEADERS_REQUIRED ON) -set(CPACK_COMPONENT_DATA_DISPLAY_NAME "Data") +set(CPACK_COMPONENT_DATA_DISPLAY_NAME "Version Info") set(CPACK_COMPONENT_DATA_DESCRIPTION "Information about this build of LiteString.") # Resource files @@ -129,5 +129,6 @@ set(CPACK_INNOSETUP_SETUP_DisableWelcomePage OFF) set(CPACK_INNOSETUP_SETUP_AppCopyright "Copyright (C) 2024 Ian Duncan") set(CPACK_INNOSETUP_SETUP_AppComments "For more information, visit https://github.com/dr8co/LiteString") set(CPACK_INNOSETUP_SETUP_VersionInfoVersion "${CPACK_PACKAGE_VERSION}") +set(CPACK_INNOSETUP_CODE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ConfigurePkgConfig.pas") include(CPack) diff --git a/examples/README.md b/examples/README.md index 703d414..6a023f1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -13,12 +13,12 @@ For building the LiteString library, refer to the The text file should not be bigger than 1MB. -```bash +```console # Compile and link the example -gcc -std=c2x -o word_stats word_stats.c -L /path/to/built/lite-string/library -llite-string +ian@github:examples$ gcc -std=c2x -o word_stats word_stats.c -L /path/to/built/lite-string/library -llite-string # Run the example -./word_stats blindtext.txt +ian@github:examples$ ./word_stats blindtext.txt # Expected output: Word count: 5800 Character count: 33355 @@ -29,15 +29,15 @@ Average word length: 5.75 [grep clone](./cheap_grep.cpp) - A simple clone of the `grep` command. -```bash +```console # Compile and link the example -g++ -std=c++20 -o cheap_grep cheap_grep.cpp -L /path/to/built/lite-string/library -llite-string +ian@github:examples$ g++ -std=c++20 -o cheap_grep cheap_grep.cpp -L /path/to/built/lite-string/library -llite-string # Run the example -./cheap_grep -i "ipsum dolor" blindtext.txt +ian@github:examples$ ./cheap_grep -i "ipsum dolor" blindtext.txt # The program can also read from standard input, when the file name is replaced with a hyphen -cat blindtext.txt | ./cheap_grep -i "ipsum dolor" - +ian@github:examples$ cat blindtext.txt | ./cheap_grep -i "ipsum dolor" - ./cheap_grep -i "lorem ipsum dolor sit amet consectetur adipiscing" - < blindtext.txt ``` @@ -52,7 +52,9 @@ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -G Ninja cmake --build build --config Release -j 4 ``` -The examples can be found in the `build` directory. +The examples can be run from the `build` directory. +(Or, from the `Release` subdirectory of `build` directory, +if you have built with a multi-configuration generator, like Visual Studio.) ```bash # From this directory (examples), run: diff --git a/LiteStringConfig.cmake.in b/input_files/LiteStringConfig.cmake.in similarity index 100% rename from LiteStringConfig.cmake.in rename to input_files/LiteStringConfig.cmake.in diff --git a/liblite-string.pc.in b/input_files/liblite-string.pc.in similarity index 89% rename from liblite-string.pc.in rename to input_files/liblite-string.pc.in index 65c648b..3aea225 100644 --- a/liblite-string.pc.in +++ b/input_files/liblite-string.pc.in @@ -1,4 +1,4 @@ -prefix="@CMAKE_INSTALL_PREFIX@ +prefix="@CMAKE_INSTALL_PREFIX@" exec_prefix="${prefix}" libdir="${prefix}/@CMAKE_INSTALL_LIBDIR@" includedir="${prefix}/@CMAKE_INSTALL_INCLUDEDIR@" diff --git a/version_info.txt.in b/input_files/version_info.txt.in similarity index 100% rename from version_info.txt.in rename to input_files/version_info.txt.in diff --git a/lite_string.c b/lite_string.c index 65c22ae..d0243ad 100644 --- a/lite_string.c +++ b/lite_string.c @@ -281,9 +281,10 @@ bool string_push_back(lite_string *const restrict s, const char c) { * * @param s A pointer to the string. * @param index The index of the character to be retrieved. - * @return The character at the given index, or the null character if the index is out of bounds or the string is invalid. + * @return The character at the given index, or the null character + * if the index is out of bounds or the string is invalid. */ -char string_at(const lite_string *const restrict s, const size_t index) { +LITE_ATTR_REPRODUCIBLE char string_at(const lite_string *const restrict s, const size_t index) { if (s && index < s->size) return s->data[index]; @@ -308,7 +309,7 @@ void string_pop_back(lite_string *const restrict s) { * @param s A pointer to the string. * @return true if the string is empty or invalid, false otherwise. */ -bool string_empty(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE bool string_empty(const lite_string *const restrict s) { return s == nullptr || s->size == 0; } @@ -318,7 +319,7 @@ bool string_empty(const lite_string *const restrict s) { * @param s A pointer to the string. * @return The last character of the string if the string is valid and not empty, or the null character otherwise. */ -char string_back(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE char string_back(const lite_string *const restrict s) { return s && s->size ? s->data[s->size - 1] : '\0'; } @@ -328,7 +329,7 @@ char string_back(const lite_string *const restrict s) { * @param s A pointer to the string. * @return The first character of the string if the string is valid and not empty, or the null character otherwise. */ -char string_front(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE char string_front(const lite_string *const restrict s) { return s && s->size ? s->data[0] : '\0'; } @@ -390,7 +391,7 @@ bool string_erase(lite_string *const restrict s, const size_t index) { * @param s2 A pointer to the second string. * @return true if the strings are equal, false otherwise. */ -bool string_compare(const lite_string *const restrict s1, const lite_string *const restrict s2) { +LITE_ATTR_REPRODUCIBLE bool string_compare(const lite_string *const restrict s1, const lite_string *const restrict s2) { if (s1 == nullptr || s2 == nullptr || s1->size != s2->size) return false; @@ -404,7 +405,8 @@ bool string_compare(const lite_string *const restrict s1, const lite_string *con * @param s2 A pointer to the second string. * @return true if the strings are equal (ignoring case), false otherwise. */ -bool string_case_compare(const lite_string *const restrict s1, const lite_string *const restrict s2) { +LITE_ATTR_REPRODUCIBLE bool string_case_compare(const lite_string *const restrict s1, + const lite_string *const restrict s2) { if (s1 == nullptr || s2 == nullptr || s1->size != s2->size) return false; @@ -417,7 +419,7 @@ bool string_case_compare(const lite_string *const restrict s1, const lite_string * @param s A pointer to the string. * @return The length of the string, or 0 if the string is invalid. */ -LITE_ATTR_HOT size_t string_length(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_length(const lite_string *const restrict s) { return s ? s->size : 0; } @@ -427,7 +429,7 @@ LITE_ATTR_HOT size_t string_length(const lite_string *const restrict s) { * @param s A pointer to the string. * @return The length of the string, or 0 if the string is invalid. */ -LITE_ATTR_HOT size_t string_size(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_size(const lite_string *const restrict s) { return string_length(s); } @@ -437,7 +439,7 @@ LITE_ATTR_HOT size_t string_size(const lite_string *const restrict s) { * @param s A pointer to the string. * @return The capacity of the string, or 0 if the string is invalid. */ -size_t string_capacity(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE size_t string_capacity(const lite_string *const restrict s) { return s ? s->capacity : 0; } @@ -531,6 +533,14 @@ void string_set(const lite_string *const restrict s, const size_t index, const c s->data[index] = c; } +/** + * @brief Inserts a string into another string at a specified index. + * + * @param s A pointer to the string where the new string will be inserted. + * @param sub A pointer to the string that will be inserted into the first string. + * @param index The position in the first string where the second string will be inserted. + * @return true if the string was successfully inserted, false otherwise. + */ bool string_insert_string(lite_string *const restrict s, const lite_string *const restrict sub, const size_t index) { return sub && string_insert_range(s, sub, index, sub->size); @@ -546,8 +556,8 @@ string_insert_string(lite_string *const restrict s, const lite_string *const res * * @note The returned pointer must be freed by the caller, using \p string_free */ -LITE_ATTR_NODISCARD lite_string *string_substr(const lite_string *const restrict s, const size_t start, - const size_t len) { +LITE_ATTR_NODISCARD lite_string * +string_substr(const lite_string *const restrict s, const size_t start, const size_t len) { if (s) { // The requested substring must be within the bounds of the string if (len == 0 || start >= s->size || len > s->size || start + len - 1 > s->size) return nullptr; @@ -578,8 +588,8 @@ LITE_ATTR_NODISCARD lite_string *string_substr(const lite_string *const restrict * or nullptr if the strings could not be concatenated. * @note The returned pointer must be freed by the caller, using \p string_free */ -LITE_ATTR_NODISCARD lite_string *string_concat(const lite_string *const restrict s1, - const lite_string *const restrict s2) { +LITE_ATTR_NODISCARD lite_string * +string_concat(const lite_string *const restrict s1, const lite_string *const restrict s2) { if (s1 && s2) { lite_string *s = string_new(); if (s) { @@ -704,7 +714,7 @@ LITE_ATTR_HOT char *string_cstr(const lite_string *const restrict s) { * @note The returned pointer is not guaranteed to be null-terminated. * Use \p string_cstr() to get a null-terminated C-string. */ -LITE_ATTR_HOT char *string_data(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT char *string_data(const lite_string *const restrict s) { return s ? s->data : nullptr; } @@ -715,7 +725,7 @@ LITE_ATTR_HOT char *string_data(const lite_string *const restrict s) { * @param cstr The C-string to be compared with the string. * @return true if the string and the C-string are equal, false otherwise. */ -bool string_compare_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE bool string_compare_cstr(const lite_string *const restrict s, const char *const restrict cstr) { if (s && cstr) { if (s->size == strlen(cstr)) return memcmp(s->data, cstr, s->size) == 0; @@ -730,7 +740,8 @@ bool string_compare_cstr(const lite_string *const restrict s, const char *const * @param cstr The C-string to be compared with the string. * @return true if the string and the C-string are equal (ignoring case), false otherwise. */ -bool string_case_compare_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE bool +string_case_compare_cstr(const lite_string *const restrict s, const char *const restrict cstr) { if (s && cstr) { if (s->size == strlen(cstr)) { #if HAS_STRNCASECMP @@ -812,7 +823,7 @@ bool string_swap(lite_string *const restrict s1, lite_string *const restrict s2) * @return The index of the last occurrence of the character in the string, * or \p lite_string_npos if the character was not found. */ -size_t string_find_last_of(const lite_string *const restrict s, const char c) { +LITE_ATTR_REPRODUCIBLE size_t string_find_last_of(const lite_string *const restrict s, const char c) { if (s && s->size && c != '\0') { #if defined(_GNU_SOURCE) && !(defined(_WIN32) || defined(WIN32) || _MSC_VER) const char *found = (const char *) memrchr(s->data, c, s->size); @@ -835,7 +846,7 @@ size_t string_find_last_of(const lite_string *const restrict s, const char c) { * @return The index of the last occurrence of a character that does not match the specified character in the string, * or \p lite_string_npos if all characters match or the string is invalid. */ -size_t string_find_last_not_of(const lite_string *const restrict s, const char c) { +LITE_ATTR_REPRODUCIBLE size_t string_find_last_not_of(const lite_string *const restrict s, const char c) { if (s && s->size && c != '\0') { for (size_t i = s->size; i > 0; --i) { if (s->data[i - 1] != c) @@ -854,7 +865,8 @@ size_t string_find_last_not_of(const lite_string *const restrict s, const char c * @return The index of the first occurrence of the character in the string, * or \p lite_string_npos if the character was not found. */ -size_t string_find_first_from(const lite_string *const restrict s, const char c, const size_t start) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_first_from(const lite_string *const restrict s, const char c, const size_t start) { if (s && s->size && c != '\0' && start < s->size) { const char *found = (const char *) memchr(s->data + start, c, s->size - start); if (found) return found - s->data; @@ -870,7 +882,7 @@ size_t string_find_first_from(const lite_string *const restrict s, const char c, * @return The index of the first occurrence of the character in the string, * or \p lite_string_npos if the character was not found. */ -size_t string_find_first_of(const lite_string *const restrict s, const char c) { +LITE_ATTR_REPRODUCIBLE size_t string_find_first_of(const lite_string *const restrict s, const char c) { return string_find_first_from(s, c, 0); } @@ -882,7 +894,7 @@ size_t string_find_first_of(const lite_string *const restrict s, const char c) { * @return The index of the first occurrence of a character that does not match the specified character in the string, * or \p lite_string_npos if all characters match or the string is invalid. */ -size_t string_find_first_not_of(const lite_string *const restrict s, const char c) { +LITE_ATTR_REPRODUCIBLE size_t string_find_first_not_of(const lite_string *const restrict s, const char c) { if (s && s->size && c != '\0') { for (size_t i = 0; i < s->size; ++i) { if (s->data[i] != c) @@ -900,7 +912,8 @@ size_t string_find_first_not_of(const lite_string *const restrict s, const char * @return The index of the first occurrence of any character from the C-string in the string, * or \p lite_string_npos if no character was found. */ -size_t string_find_first_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_first_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { if (s && s->size && cstr) { const size_t len = strlen(cstr); if (len) { @@ -929,7 +942,8 @@ size_t string_find_first_of_chars(const lite_string *const restrict s, const cha * @return The index of the first occurrence of any character not present in the C-string in the string, * or \p lite_string_npos if all characters match or the string is invalid. */ -size_t string_find_first_not_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_first_not_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { if (s && s->size && cstr) { const size_t len = strlen(cstr); if (len) { @@ -958,7 +972,8 @@ size_t string_find_first_not_of_chars(const lite_string *const restrict s, const * @return The index of the last occurrence of any character from the C-string in the string, * or \p lite_string_npos if no character was found. */ -size_t string_find_last_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_last_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { if (s && s->size && cstr) { const size_t len = strlen(cstr); if (len) { @@ -987,7 +1002,8 @@ size_t string_find_last_of_chars(const lite_string *const restrict s, const char * @return The index of the last occurrence of any character not present in the C-string in the string, * or \p lite_string_npos if all characters match or the string is invalid. */ -size_t string_find_last_not_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_last_not_of_chars(const lite_string *const restrict s, const char *const restrict cstr) { if (s && s->size && cstr) { const size_t len = strlen(cstr); if (len) { @@ -1015,7 +1031,7 @@ size_t string_find_last_not_of_chars(const lite_string *const restrict s, const * @param c The character to be found. * @return True if the string contains the character, false otherwise. */ -bool string_contains_char(const lite_string *const restrict s, const char c) { +LITE_ATTR_REPRODUCIBLE bool string_contains_char(const lite_string *const restrict s, const char c) { return string_find_first_of(s, c) != lite_string_npos; } @@ -1029,8 +1045,8 @@ bool string_contains_char(const lite_string *const restrict s, const char c) { * @param len The length of the pattern string. * @param lps The LPS array which is to be filled. */ -LITE_ATTR_MAYBE_UNUSED static void compute_lps(const char *const restrict pattern, - const size_t len, size_t *const restrict lps) { +LITE_ATTR_MAYBE_UNUSED static void +compute_lps(const char *const restrict pattern, const size_t len, size_t *const restrict lps) { size_t len_lps = 0; // Length of the previous longest prefix suffix lps[0] = 0; // lps[0] is always 0 size_t i = 1; @@ -1066,8 +1082,8 @@ LITE_ATTR_MAYBE_UNUSED static void compute_lps(const char *const restrict patter * @return The index of the first occurrence of the pattern string in the main text string, * or \p lite_string_npos if the pattern string is not found. */ -LITE_ATTR_MAYBE_UNUSED static size_t kmp_search(const char *const restrict s, const size_t s_size, - const char *const restrict sub, const size_t sub_size) { +LITE_ATTR_REPRODUCIBLE LITE_ATTR_MAYBE_UNUSED static size_t +kmp_search(const char *const restrict s, const size_t s_size, const char *const restrict sub, const size_t sub_size) { size_t i = 0; // Index for the string size_t j = 0; // Index for the substring @@ -1117,8 +1133,8 @@ LITE_ATTR_MAYBE_UNUSED static size_t kmp_search(const char *const restrict s, co * @return The index of the first occurrence of the substring in the string, * or \p lite_string_npos if the substring was not found. */ -size_t string_find_from(const lite_string *const restrict s, const lite_string *const restrict sub, - const size_t start) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_from(const lite_string *const restrict s, const lite_string *const restrict sub, const size_t start) { if (s && sub && start < s->size) { if (sub->size == 0) return start; if (sub->size > s->size) return lite_string_npos; @@ -1142,7 +1158,7 @@ size_t string_find_from(const lite_string *const restrict s, const lite_string * * @return The index of the first occurrence of the substring in the string, * or \p lite_string_npos if the substring was not found. */ -size_t string_find(const lite_string *const restrict s, const lite_string *const restrict sub) { +LITE_ATTR_REPRODUCIBLE size_t string_find(const lite_string *const restrict s, const lite_string *const restrict sub) { return string_find_from(s, sub, 0); } @@ -1154,7 +1170,7 @@ size_t string_find(const lite_string *const restrict s, const lite_string *const * @return The index of the last occurrence of the substring in the string, * or \p lite_string_npos if the substring was not found. */ -size_t string_rfind(const lite_string *const restrict s, const lite_string *const restrict sub) { +LITE_ATTR_REPRODUCIBLE size_t string_rfind(const lite_string *const restrict s, const lite_string *const restrict sub) { if (s && sub) { if (sub->size == 0) return s->size; if (sub->size > s->size) return lite_string_npos; @@ -1207,8 +1223,8 @@ size_t string_rfind(const lite_string *const restrict s, const lite_string *cons * @return The index of the first occurrence of the C-string in the string, * or \p lite_string_npos if the C-string was not found. */ -size_t string_find_cstr_from(const lite_string *const restrict s, const char *const restrict cstr, - const size_t start) { +LITE_ATTR_REPRODUCIBLE size_t +string_find_cstr_from(const lite_string *const restrict s, const char *const restrict cstr, const size_t start) { // The string and the C-string must be valid if (s && cstr) { const size_t len = strlen(cstr); @@ -1242,7 +1258,7 @@ size_t string_find_cstr_from(const lite_string *const restrict s, const char *co * @return The index of the last occurrence of the C-string in the string, * or \p lite_string_npos if the C-string was not found. */ -size_t string_rfind_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t string_rfind_cstr(const lite_string *const restrict s, const char *const restrict cstr) { if (s && cstr) { const size_t len = strlen(cstr); if (len == 0) return s->size; @@ -1294,7 +1310,7 @@ size_t string_rfind_cstr(const lite_string *const restrict s, const char *const * @return The index of the first occurrence of the C-string in the string, * or \p lite_string_npos if the C-string was not found. */ -size_t string_find_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE size_t string_find_cstr(const lite_string *const restrict s, const char *const restrict cstr) { return string_find_cstr_from(s, cstr, 0); } @@ -1305,7 +1321,8 @@ size_t string_find_cstr(const lite_string *const restrict s, const char *const r * @param sub A pointer to the substring to be found. * @return True if the string contains the substring, false otherwise. */ -bool string_contains(const lite_string *const restrict s, const lite_string *const restrict sub) { +LITE_ATTR_REPRODUCIBLE bool +string_contains(const lite_string *const restrict s, const lite_string *const restrict sub) { return string_find(s, sub) != lite_string_npos; } @@ -1316,7 +1333,7 @@ bool string_contains(const lite_string *const restrict s, const lite_string *con * @param cstr The C-string to be found. * @return True if the string contains the C-string, false otherwise. */ -bool string_contains_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE bool string_contains_cstr(const lite_string *const restrict s, const char *const restrict cstr) { return string_find_cstr(s, cstr) != lite_string_npos; } @@ -1327,7 +1344,8 @@ bool string_contains_cstr(const lite_string *const restrict s, const char *const * @param sub A pointer to the substring to be checked. * @return True if the string starts with the substring, false otherwise. */ -bool string_starts_with(const lite_string *const restrict s, const lite_string *const restrict sub) { +LITE_ATTR_REPRODUCIBLE bool +string_starts_with(const lite_string *const restrict s, const lite_string *const restrict sub) { return string_find(s, sub) == 0; } @@ -1338,7 +1356,8 @@ bool string_starts_with(const lite_string *const restrict s, const lite_string * * @param cstr The C-string to be checked. * @return True if the string starts with the C-string, false otherwise. */ -bool string_starts_with_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE bool +string_starts_with_cstr(const lite_string *const restrict s, const char *const restrict cstr) { return string_find_cstr(s, cstr) == 0; } @@ -1349,7 +1368,8 @@ bool string_starts_with_cstr(const lite_string *const restrict s, const char *co * @param sub A pointer to the substring to be checked. * @return True if the string ends with the substring, false otherwise. */ -bool string_ends_with(const lite_string *const restrict s, const lite_string *const restrict sub) { +LITE_ATTR_REPRODUCIBLE bool +string_ends_with(const lite_string *const restrict s, const lite_string *const restrict sub) { return s && sub && string_rfind(s, sub) == s->size - sub->size; } @@ -1360,7 +1380,8 @@ bool string_ends_with(const lite_string *const restrict s, const lite_string *co * @param cstr The C-string to be checked. * @return True if the string ends with the C-string, false otherwise. */ -bool string_ends_with_cstr(const lite_string *const restrict s, const char *const restrict cstr) { +LITE_ATTR_REPRODUCIBLE bool +string_ends_with_cstr(const lite_string *const restrict s, const char *const restrict cstr) { return s && cstr && string_rfind_cstr(s, cstr) == s->size - strlen(cstr); } @@ -1569,7 +1590,7 @@ void string_reverse(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The long long integer representation of the string, or 0 if the string is nullptr. */ -long long string_to_ll(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE long long string_to_ll(const lite_string *const restrict s) { long long result = 0; if (s) result = strtoll(string_cstr(s), nullptr, 10); return result; @@ -1581,7 +1602,7 @@ long long string_to_ll(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The unsigned long long integer representation of the string, or 0 if the string is nullptr. */ -unsigned long long string_to_ull(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE unsigned long long string_to_ull(const lite_string *const restrict s) { unsigned long long result = 0; if (s) result = strtoull(string_cstr(s), nullptr, 10); return result; @@ -1593,7 +1614,7 @@ unsigned long long string_to_ull(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The long integer representation of the string, or 0 if the string is nullptr. */ -long string_to_l(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE long string_to_l(const lite_string *const restrict s) { long result = 0; if (s) result = strtol(string_cstr(s), nullptr, 10); return result; @@ -1605,7 +1626,7 @@ long string_to_l(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The unsigned long integer representation of the string, or 0 if the string is nullptr. */ -unsigned long string_to_ul(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE unsigned long string_to_ul(const lite_string *const restrict s) { unsigned long result = 0; if (s) result = strtoul(string_cstr(s), nullptr, 10); return result; @@ -1617,7 +1638,7 @@ unsigned long string_to_ul(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The integer representation of the string, or 0 if the string is nullptr. */ -int string_to_int(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE int string_to_int(const lite_string *const restrict s) { return (int) string_to_l(s); } @@ -1627,7 +1648,7 @@ int string_to_int(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The unsigned integer representation of the string, or 0 if the string is nullptr. */ -unsigned int string_to_uint(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE unsigned int string_to_uint(const lite_string *const restrict s) { return (unsigned int) string_to_ul(s); } @@ -1637,7 +1658,7 @@ unsigned int string_to_uint(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The double representation of the string, or 0.0 if the string is nullptr. */ -double string_to_double(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE double string_to_double(const lite_string *const restrict s) { double result = 0.0; if (s) result = strtod(string_cstr(s), nullptr); return result; @@ -1649,7 +1670,7 @@ double string_to_double(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The float representation of the string, or 0.0f if the string is nullptr. */ -float string_to_float(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE float string_to_float(const lite_string *const restrict s) { float result = 0.0f; if (s) result = strtof(string_cstr(s), nullptr); return result; @@ -1661,7 +1682,7 @@ float string_to_float(const lite_string *const restrict s) { * @param s A pointer to the string to be converted. * @return The long double representation of the string, or 0.0 if the string is nullptr. */ -long double string_to_ldouble(const lite_string *const restrict s) { +LITE_ATTR_REPRODUCIBLE long double string_to_ldouble(const lite_string *const restrict s) { long double result = 0.0; if (s) result = strtold(string_cstr(s), nullptr); return result; @@ -1688,7 +1709,8 @@ LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ll(const long * @brief Converts an unsigned long long integer to a string. * * @param value The unsigned long long integer to be converted. - * @return A pointer to the new string containing the unsigned long long integer, or nullptr if the string creation failed. + * @return A pointer to the new string containing the unsigned long long integer, + * or nullptr if the string creation failed. * @note The returned pointer must be freed by the caller, using \p string_free() */ LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ull(const unsigned long long value) { diff --git a/lite_string.h b/lite_string.h index cdd796e..f90e446 100644 --- a/lite_string.h +++ b/lite_string.h @@ -21,8 +21,8 @@ #pragma once // Library version -#define _lite_string_major 0L ///< LiteString major version. -#define _lite_string_minor 1L ///< LiteString minor version. +#define _lite_string_major 1L ///< LiteString major version. +#define _lite_string_minor 0L ///< LiteString minor version. #define _lite_string_patch 0L ///< LiteString patch version. /// The LiteString version as a single integer. @@ -194,25 +194,25 @@ LITE_ATTR_HOT bool string_reserve(lite_string *restrict s, size_t size); bool string_push_back(lite_string *restrict s, char c); -char string_at(const lite_string *restrict s, size_t index); +LITE_ATTR_REPRODUCIBLE char string_at(const lite_string *restrict s, size_t index); void string_pop_back(lite_string *restrict s); -bool string_empty(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE bool string_empty(const lite_string *restrict s); bool string_erase(lite_string *restrict s, size_t index); -char string_back(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE char string_back(const lite_string *restrict s); -char string_front(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE char string_front(const lite_string *restrict s); -bool string_compare(const lite_string *restrict s1, const lite_string *restrict s2); +LITE_ATTR_REPRODUCIBLE bool string_compare(const lite_string *restrict s1, const lite_string *restrict s2); -LITE_ATTR_HOT size_t string_length(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_length(const lite_string *restrict s); -LITE_ATTR_HOT size_t string_size(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_size(const lite_string *restrict s); -size_t string_capacity(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE size_t string_capacity(const lite_string *restrict s); void string_clear(lite_string *restrict s); @@ -232,9 +232,9 @@ bool string_append_cstr(lite_string *restrict s, const char *restrict cstr); LITE_ATTR_HOT char *string_cstr(const lite_string *restrict s); -LITE_ATTR_HOT char *string_data(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT char *string_data(const lite_string *restrict s); -bool string_compare_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE bool string_compare_cstr(const lite_string *restrict s, const char *restrict cstr); bool string_insert_cstr(lite_string *restrict s, const char *restrict cstr, size_t index); @@ -244,9 +244,9 @@ bool string_copy_buffer(const lite_string *restrict s, char *buf); bool string_copy(const lite_string *restrict src, lite_string *restrict dest); -bool string_case_compare(const lite_string *restrict s1, const lite_string *restrict s2); +LITE_ATTR_REPRODUCIBLE bool string_case_compare(const lite_string *restrict s1, const lite_string *restrict s2); -bool string_case_compare_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE bool string_case_compare_cstr(const lite_string *restrict s, const char *restrict cstr); bool string_swap(lite_string *restrict s1, lite_string *restrict s2); @@ -256,49 +256,49 @@ bool string_insert_range(lite_string *restrict s, const lite_string *restrict su bool string_insert_string(lite_string *restrict s, const lite_string *restrict sub, size_t index); -size_t string_find_last_of(const lite_string *restrict s, char c); +LITE_ATTR_REPRODUCIBLE size_t string_find_last_of(const lite_string *restrict s, char c); -size_t string_find_last_not_of(const lite_string *restrict s, char c); +LITE_ATTR_REPRODUCIBLE size_t string_find_last_not_of(const lite_string *restrict s, char c); -size_t string_find_first_from(const lite_string *restrict s, char c, size_t start); +LITE_ATTR_REPRODUCIBLE size_t string_find_first_from(const lite_string *restrict s, char c, size_t start); -size_t string_find_first_of(const lite_string *restrict s, char c); +LITE_ATTR_REPRODUCIBLE size_t string_find_first_of(const lite_string *restrict s, char c); -size_t string_find_first_not_of(const lite_string *restrict s, char c); +LITE_ATTR_REPRODUCIBLE size_t string_find_first_not_of(const lite_string *restrict s, char c); -size_t string_find_first_of_chars(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_find_first_of_chars(const lite_string *restrict s, const char *restrict cstr); -size_t string_find_first_not_of_chars(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_find_first_not_of_chars(const lite_string *restrict s, const char *restrict cstr); -size_t string_find_last_of_chars(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_find_last_of_chars(const lite_string *restrict s, const char *restrict cstr); -size_t string_find_last_not_of_chars(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_find_last_not_of_chars(const lite_string *restrict s, const char *restrict cstr); -size_t string_find_from(const lite_string *restrict s, const lite_string *restrict sub, size_t start); +LITE_ATTR_REPRODUCIBLE size_t string_find_from(const lite_string *restrict s, const lite_string *restrict sub, size_t start); -size_t string_find(const lite_string *restrict s, const lite_string *restrict sub); +LITE_ATTR_REPRODUCIBLE size_t string_find(const lite_string *restrict s, const lite_string *restrict sub); -size_t string_rfind(const lite_string *restrict s, const lite_string *restrict sub); +LITE_ATTR_REPRODUCIBLE size_t string_rfind(const lite_string *restrict s, const lite_string *restrict sub); -size_t string_find_cstr_from(const lite_string *restrict s, const char *restrict cstr, size_t start); +LITE_ATTR_REPRODUCIBLE size_t string_find_cstr_from(const lite_string *restrict s, const char *restrict cstr, size_t start); -size_t string_rfind_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_rfind_cstr(const lite_string *restrict s, const char *restrict cstr); -size_t string_find_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE size_t string_find_cstr(const lite_string *restrict s, const char *restrict cstr); -bool string_contains_char(const lite_string *restrict s, char c); +LITE_ATTR_REPRODUCIBLE bool string_contains_char(const lite_string *restrict s, char c); -bool string_contains(const lite_string *restrict s, const lite_string *restrict sub); +LITE_ATTR_REPRODUCIBLE bool string_contains(const lite_string *restrict s, const lite_string *restrict sub); -bool string_contains_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE bool string_contains_cstr(const lite_string *restrict s, const char *restrict cstr); -bool string_starts_with(const lite_string *restrict s, const lite_string *restrict sub); +LITE_ATTR_REPRODUCIBLE bool string_starts_with(const lite_string *restrict s, const lite_string *restrict sub); -bool string_starts_with_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE bool string_starts_with_cstr(const lite_string *restrict s, const char *restrict cstr); -bool string_ends_with(const lite_string *restrict s, const lite_string *restrict sub); +LITE_ATTR_REPRODUCIBLE bool string_ends_with(const lite_string *restrict s, const lite_string *restrict sub); -bool string_ends_with_cstr(const lite_string *restrict s, const char *restrict cstr); +LITE_ATTR_REPRODUCIBLE bool string_ends_with_cstr(const lite_string *restrict s, const char *restrict cstr); bool string_shrink(lite_string *restrict s, size_t size); @@ -326,23 +326,23 @@ LITE_ATTR_NODISCARD lite_string *string_duplicate(const lite_string *restrict s) void string_reverse(const lite_string *restrict s); -long long string_to_ll(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE long long string_to_ll(const lite_string *restrict s); -unsigned long long string_to_ull(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE unsigned long long string_to_ull(const lite_string *restrict s); -long string_to_l(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE long string_to_l(const lite_string *restrict s); -unsigned long string_to_ul(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE unsigned long string_to_ul(const lite_string *restrict s); -int string_to_int(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE int string_to_int(const lite_string *restrict s); -unsigned int string_to_uint(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE unsigned int string_to_uint(const lite_string *restrict s); -double string_to_double(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE double string_to_double(const lite_string *restrict s); -float string_to_float(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE float string_to_float(const lite_string *restrict s); -long double string_to_ldouble(const lite_string *restrict s); +LITE_ATTR_REPRODUCIBLE long double string_to_ldouble(const lite_string *restrict s); LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_l(long value);