Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New sprintf implementation #7612

Draft
wants to merge 41 commits into
base: master
Choose a base branch
from
Draft

New sprintf implementation #7612

wants to merge 41 commits into from

Conversation

headius
Copy link
Member

@headius headius commented Feb 1, 2023

Created to track #6913 and work from 2021 on the new_sprintf branch. Still in progress.

The goal of this new design is to make it much simpler to modify
and update when we find a bug or have to add a new identifier.  A
secondary longer goal is to decouple processing of the format string
from the generation of the final string when executing sprintf.  The
value of this decoupling is we can push the format parsing phase into
the sprintf callsite so we only have to process the format once.  In
fact once we get to that point we can potentially just bytecode generate
the string building piece.

The current point of this work is we can completely parse the format
string into a sequence of tokens.  It is done sans bugs or decisions to
add/change any fields based on work on the interpreter.

At this point to use it you need to set the env var SPRINTF=anything
to enable new runtime and it will only work with %i, %d, and %u.

Future work will be to keep adding new directives but not be trying
very hard to make one method process to many directives.  In the case
of the three (i,d,u) 'i' is an alias of 'd' and 'u' processes unsigned
values a little differently when setting up the value.   Any more complexity
and u would have been its own method.
May need to unit test byteListUpto but for now this passes more tests.
indexed args in sprintf were still also using that index as its
width.
getArg will now get named parameters.
Implement argument errors for mixed format specifiers.
The parser assumed width and arg index would occur in the same order:

  %*1$2$d

but it can also be:

  %2$*1$d

I also changed some naming.
I fixed another incompatibility and realized hasWidth is the right
name.  This commit also fixed asking for next arg if hasWidth for
an unnumbered format field.
%#o with a negative values does not prefix with a '0'.  Strange but true.
"%*10d" is mixing numbered '*' with 10d unnumbered.
… succ.

Lots of random fixes to the sprintf parser.  A grab bag of smaller fixes.
Telling between explictly supplied precision and an argument provided one
is still messy but it should be working now.  I will try and circle back
to simplify FormatToken since the other two (index, width) are not as
complex.

Also removed dead parameter in processDigits.
%5.0d was zero padding and asking for an extra argument before this change.
We now pass more specs and tests with new code and we also want
to see mistakes made with the new code during CI runs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

format and sprintf do not support '%a' and '%A'
3 participants