<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/84244>84244</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Add strfrom<float> functions to LLVM-libc
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            good first issue,
            libc
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          michaelrj-google
      </td>
    </tr>
</table>

<pre>
    Specified in C23 on page 370 of this PDF: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf

C23 adds a new family of functions to convert floating point numbers to strings: `strfromf`, `strfromd`, and `strfroml`. The interface is set up to piggyback on the existing printf interface, so no floating point knowledge is needed for this implementation. Since this involves adding a new public function there will be a lot of files that need to be touched, but each individual piece should be simple. Below is a (hopefully complete) list of tasks to add these functions. Feel free to reach out if you need help, you can find me as michaelrj on discord, or you can just leave a comment on this bug.

### Build System

In [entrypoints.txt](https://github.com/llvm/llvm-project/blob/main/libc/config/linux/x86_64/entrypoints.txt)
- [ ] Add the new functions to the list of entrypoints for stdlib.h (you need to do this before it will build)
- [ ] (Optional) Add the functions to the list of entrypoints for platforms other than linux/x86_64

In [stdlib/CMakeLists.txt](https://github.com/llvm/llvm-project/blob/main/libc/src/stdlib/CMakeLists.txt)
- [ ] Add new entrypoint objects to the list (they will need dependencies on printf components, which are found in [printf_core](https://github.com/llvm/llvm-project/tree/main/libc/src/stdio/printf_core))

In [stdc.td](https://github.com/llvm/llvm-project/blob/main/libc/spec/stdc.td#L923)
- [ ] Add the functions to the list of functions for stdlib.h (this can be confusing, ask for help if you're stuck).

### Code

Create `stdlib/strfromf.h`
- [ ] look at [strtof.h](https://github.com/llvm/llvm-project/blob/main/libc/src/stdlib/strtof.h) for an example of how this should be laid out (copying the whole file and modifying it is fine).
- [ ] Remember to add `#include <stddef.h>` since this function takes a `size_t`

Create `stdlib/strfromf.cpp`
- [ ] Again, look at look at [strtof.cpp](https://github.com/llvm/llvm-project/blob/main/libc/src/stdlib/strtof.cpp) for an example.
The plan is to have a shared utility function for all of the variants of these functions, so don't worry about filling this file out yet.

Create matching files for `strfromd` and `strfroml`
- [ ] Same as above.

Create a shared utility file (suggested path: `stdlib/str_from_util.h`) for the actual implementation
- [ ] Implement a function that takes the simplified format string and converts it into a FormatSection (defined in [core_structs.h](https://github.com/llvm/llvm-project/blob/main/libc/src/stdio/printf_core/core_structs.h))
 - [ ] How to handle things outside of the format the standard specifies is up to you, but make sure to leave a comment explaining your decision.
- [ ] Implement a templated function that takes the arguments from strto<float> that...
  - [ ] calls the parsing function mentioned above, then fills in the `conv_val_raw` argument in the FormatSection (you'll need to use a `cpp::bit_cast`, like how [parser.h](https://github.com/llvm/llvm-project/blob/main/libc/src/stdio/printf_core/parser.h#L59) does)
  - [ ] Creates a `Writer` object (like how [snprintf](https://github.com/llvm/llvm-project/blob/main/libc/src/stdio/snprintf.cpp) does)
  - [ ] Passes the completed FormatSection and writer to the appropriate converter (like how [converter.cpp](https://github.com/llvm/llvm-project/blob/main/libc/src/stdio/printf_core/converter.cpp) does)
  - [ ] Finally, return the result.

### Testing

Create `test/src/stdlib/strfromf_test.cpp`
- [ ] This will be similar to [snprintf_test.cpp](https://github.com/llvm/llvm-project/blob/main/libc/test/src/stdio/snprintf_test.cpp)
- [ ] Write tests to check the various parts of your implementation
  - [ ] Make sure to test your parser thoroughly, but you don't need to test the existing printf pieces as hard since they already have tests.
  - [ ] If you want complete floating point tests, look at [sprintf_test.cpp](https://github.com/llvm/llvm-project/blob/main/libc/test/src/stdio/sprintf_test.cpp#L1083)

Create similar files for `strfromd` and `strfroml`
- [ ] In the test for `strfroml` make sure to check which `long double` type you're working with, since it can be 64, 80, or 128 bits, and that will effect your results.
- [ ] (optional) Make all of these tests come from the same file, like how [StrtolTest.h](https://github.com/llvm/llvm-project/blob/main/libc/test/src/stdlib/StrtolTest.h) is implemented.

Add your tests to [test/src/stdlib/CMakeLists.txt](https://github.com/llvm/llvm-project/blob/main/libc/test/src/stdlib/CMakeLists.txt)
- [ ] Hopefully self-explanatory
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8WN9v47gR_muYl0EMh7Id58EP-XHGLZBDD82ifQwociRxTZMCScVx__piSMmWHed6bTcHLLKwRHFmvvlmviFFCLq2iCs2f2DzpyvRxcb51VbLRqDxP65r52qDV6VT-9VLi1JXGhVoC4-8AGehFTVCcTsFV0FsdIDfn9asuIcmxjaw4p7xNePr3W43cS3a6xDVxPma8fWPKG8YXwfJOS2ob2Z5HeNr5WRgfG0LzqeTVlVs-sSm9_kvmRVKBRBgcQeV2GqzJ-NVZ2XUzgaIDqSzb-gjVMaJqG0NrdM2gu22Jfq0IkSvbU0eAltMQ_SVd9uKLaaMP46eqP6JsGr01LDFdALfGwRtI_pKSAQdIGCErqXdW13X-1LIDUEUGwR81yE74rWN1fE72jw4sO7c1411O4OqTjtbRIUKKuczyHrbGtyijYJCnsCLthL7V_bNmTcMhBLtlnFqu9JoeQCJfPIIO20MlAgCjIsJRG0wQGxETCYplBIhuk42qMjVsouAQjagrdJvWnXCQKtRIoTGdUbR8pC8m8ADGrcj7wUwvmxci1VnzB6ko_cRGb8Do0MyHEXYpLwIpci5gMeETmCNaKDySK6AT_ZdF0FXsHdd9rRB05KD9EAKC5W2CrYIIsCBzJQMpYN0PsXi_GH1jy5EMCjeCAvptgRtTp0OUHb1ZExBxov8Dx46bRS87EPE7XjFNwts_oA2-n1KZpjE98jmTwTDSV3UOjZdOZFuy_jamLfhv-vWux8oI-Pr0riS8fVWaEsvdSkZX0tnK12n37Z7Z3z9vly8LqiCzo3yu-zSNXkEbP4E9xnhXD7joqGHQz5G2yTWhaiMLicNZfKAeXSgXI8RVs4j6NhzioC5YJvx5d9aMigMZX9w5U-70RoRK-e3ARwxmJhq4QyDD3nIvjO-fvxNbPBZh5-fj-DT308MXc4B4X-MD1xJBk4RYHwZG9xnTBPkClu0Cq3UGFL7ze2ESspZtDEQsXeNlg0Ij1C5zqZuzeYPeemrdB7_x9CjR_w8dO0YX4-N8LtD5GfpkJOofir8LfZOpJ158XxHBfop9T_l2_HFOekTy6lVlEjqUnVB2zopQ9ikxdSA-o7E-K1HCLGTG8bvPukdj07hibB5FBGzyPQ0GlRp0pAKncVinNuAiBlRHx2t-jpGH0zwuxStsIDvgvo4wda4XW4DRxEwQqvUpBlfStfuSYoI6V3jDCadSZq6dUpX6aWOJBWVtnjE7Bjt33GLpN2DRCRZLrSVplMIrHgMUSkkB4tf2GIK4SiIR80TG0xitJgG_S98jQdU_3MGZNteyMF9nTB7PCTjY1Lowy9PCxn5kJgeQ5pSWiMsoRsdNFnjQiM8KuiiNjrujxilLYzJ0xzCm_BaUPPNv8eq3A8uylnGbyPsnPd7ECWlvNLG5HynjBJHugh7jJMLcG9FlA2tzrMHOXA6fl2Yvc7z8CKy0ovSveElIx8DJq8YX4aurjFEVNCK2BymwSO8r2TzlT7LVdjDTOAIGWn8OZ3Fzl37NrwFMZ6-ROzpSBulgSkP1iRuIvbTaYq8H2VDKhBL9Id1WvSCeTPGlwqpboZGT833NUTfyRi-qCl87PXrM6uj5g9HNH6lRkEktMqk8rR1IHIErXDgXA9BAiYKq4RXEPqTRyAW5xE79dk8kG7FBiF0Po2H51McvrdGaEtw7l3nQaHUgYbmP8pUxC2NGpSQT3ImfN3R4gBEEEiFyIrHNMSz4pe0fDLpjcAIAimMyVu0wodE_MEE7acdJTIRmcKLDdpUTzTYp6_YYkqUeH0T5tWLXSqQ3pdhyQd-ZE0aZojooAuYGyF1juKeFfeljq9ShNifd4zeYGrrNDgIH9D_dUw62OPF85xoBMphONJpBGYu776p_9PriJ4AybMURT6OI9hs5-viGCwMDflTv38XIfREGk5D6ixtVPu7FNEwpIi29a71mhpa3xXQnwd5ePFlynOx9sdG_yjwtbbCmD1RzGPsfCasx9CZ-Mmg9B3TyfmyUkcM8aIsJtl-pdefaPd3EqfhABz0VhuRkB4R5fj5T8Tx3OMT4hwtfhxeE72BFuQrjgbl5iDSrgvUT7JSpz53SZbGmfht3DRp1_xZLj6IjfOuq5ucKmqydOobxH5oI-mzS9cb6UogkCQ3qX330xjuQRiPQu3zHJKCudAjv-WD_U7YeKiP8_uR9O149qLE_eV5-5C24vlmuizODj49XweW_R-TzrdcMAn40w1o9akSZobkwyBbTI2zNSjXlQZpady3eDys7JzfELY7HZs02aWM6TgceRYzerqc9vcmN3wJpc74k9NJHFMxYVVR601cymUdPigt40s3ugVITDwOnWEguXRbzOqaZgGa8Qi5c3l6Iek11CV-rkRdbi0n1vgdjC_jUJ20MDptJhwONcvmD5d3_bqbiT9l72Oz-fVwWxfQVNdpiLIiOr-_UqtC3RV34gpXN7fTu9tFcTu9uWpW1XIuCiFmM3k7q26q5Y264aoscFnx23LBb6_0ik_5bFpMF5zzm9nNZKbmy7lUKPl8tpwtCjab4lZoM6HAJs7XVzqEDlfLGZ_Nrowo0YR0Uc157ZyCSvtAp8bQIeOc8UfGeQ6bs_nTlV8lgMquDmw2NSnaw85RR4MrSlFfP-Ph7eR-4Pn5H79d07ZXnTer_zoryb3A-DpF8e8AAAD__wS7vS8">