Commit graph

20 commits

Author SHA1 Message Date
Lenny Maiorani
fcee80dd69 Formatter: Remove extraneous char definition
Formatter is specialized in the header file. The definition in the
implementation file is extraneous and has no effect. Simply removing
it so that there is no confusion.
2020-10-08 09:54:56 +02:00
asynts
7c2cd81edb AK+Format: Exclude prefix from width calculation.
When we write the format specifier '{:#08x}' we are asking for eight
significant digits, zero padding and the prefix '0x'.

However, previously we got only six significant digits because the
prefix counted towards the width. (The number '8' here is the total
width and not the number of significant digits.)

Both fmtlib and printf shared this behaviour. However, I am introducing
a special case here because when we do zero padding we really only care
about the digits and not the width.

Notice that zero padding is a special case anyways, because zero padding
goes after the prefix as opposed to any other padding which goes before
it.
2020-10-06 15:28:39 +02:00
asynts
59e7ffa86d AK: Make the return type of dbgputstr consistent. 2020-10-04 19:18:32 +02:00
asynts
d5ffb51a83 AK: Don't add newline for outf/dbgf/warnf.
In the future all (normal) output should be written by any of the
following functions:

    out    (currently called new_out)
    outln
    dbg    (currently called new_dbg)
    dbgln
    warn   (currently called new_warn)
    warnln

However, there are still a ton of uses of the old out/warn/dbg in the
code base so the new functions are called new_out/new_warn/new_dbg. I am
going to rename them as soon as all the other usages are gone (this
might take a while.)

I also added raw_out/raw_dbg/raw_warn which don't do any escaping,
this should be useful if no formatting is required and if the input
contains tons of curly braces. (I am not entirely sure if this function
will stay, but I am adding it for now.)
2020-10-04 17:04:55 +02:00
asynts
6351a56d27 AK+Format: Do some housekeeping in the format implementation. 2020-10-02 20:48:19 +02:00
asynts
fb7a94c959 AK: Add formatter for pointer types. 2020-10-02 13:44:42 +02:00
asynts
ebafc5b4d2 AK: Add formatter for boolean values. 2020-10-02 13:44:42 +02:00
asynts
1175ecf1dd AK+Format: Add support for integer to character casts.
Now the following is possible:

    outf("{:c}", 75); // K
2020-09-29 16:14:58 +02:00
asynts
71b7ef0992 AK+Format: Support all format specifiers for strings.
The following is now possible:

    outf("{:.4}", "abcdef"); // abcd
    outf("{:*<8}", "abcdef"); // abcdef**
2020-09-29 16:14:58 +02:00
asynts
13ce24de13 AK+Format: Support default index in replacement field.
The following does now work:

    outf("{:0{}}", 1, 3);      // 001
2020-09-28 17:41:27 +02:00
asynts
56bfefabb6 AK+Format: Keep type information for integers in TypeErasedParameter.
It's now save to pass a signed integer as parameter and then use it as
replacement field (previously, this would just cast it to size_t which
would be bad.)
2020-09-28 10:53:16 +02:00
asynts
6a2f5f4522 AK+Format: Clean up format specifier parsing using GenericLexer.
Also adds support for replacement fields.
2020-09-28 10:53:16 +02:00
Benoît Lormeau
f0f6b09acb AK: Remove the ctype adapters and use the actual ctype functions instead
This finally takes care of the kind-of excessive boilerplate code that were the
ctype adapters. On the other hand, I had to link `LibC/ctype.cpp` to the Kernel
(for `AK/JsonParser.cpp` and `AK/Format.cpp`). The previous commit actually makes
sense now: the `string.h` includes in `ctype.{h,cpp}` would require to link more LibC
stuff to the Kernel when it only needs the `_ctype_` array of `ctype.cpp`, and there
wasn't any string stuff used in ctype.
Instead of all this I could have put static derivatives of `is_any_of()` in the
concerned AK files, however that would have meant more boilerplate and workarounds;
so I went for the Kernel approach.
2020-09-27 21:15:25 +02:00
asynts
01915a3027 AK+Format: Use the new format backend in the implementation. 2020-09-26 17:19:04 +02:00
asynts
2030084746 AK: Borrow exact format syntax form std::format.
Instead of just implementing format specifiers ad-hog this commit
implements the exact syntax std::format uses.

There are still a ton of features that are not supported by this
implementation, however, the format specifiers should be parsed
correctly.

In some cases however, the format specifiers aren't quite parsed
correctly, for example:

    String::formatted("{:{}}", 42, 4)

should produce the string "  42" however an (unrelated) assertion fails.
This is because vformat doesn't consider nested parentheses. I have to
spend some time coming up with a simple way of doing this, I don't feel
like doing that right now.

The fundamental code for this already exists, by limiting the number of
format arguments (arbitrarily) to 256 large widths are used to encode
that these should be taken from other format parameters.
2020-09-26 00:00:50 +02:00
asynts
5ed15a49f2 AK: Add outf, warnf and dbgf. 2020-09-23 21:45:28 +02:00
asynts
b7a4c4482f AK: Resolve format related circular dependencies properly.
With this commit, <AK/Format.h> has a more supportive role and isn't
used directly.

Essentially, there now is a public 'vformat' function ('v' for vector)
which takes already type erased parameters. The name is choosen to
indicate that this function behaves similar to C-style functions taking
a va_list equivalent.

The interface for frontend users are now 'String::formatted' and
'StringBuilder::appendff'.
2020-09-23 21:45:28 +02:00
asynts
90536a1558 AK: Consider long and unsigned long as integral types.
Two things I hate about C++:

 1. 'int', 'signed int' and 'unsigned int' are two distinct types while
    'char, 'signed char' and 'unsigned char' are *three* distinct types.

    This is because 'signed int' is an alias for 'int' but 'signed char'
    can't be an alias for 'char' because on some weird systems 'char' is
    unsigned.

    One might think why not do it the other way around, make 'int' an
    alias for 'signed int' and 'char' an alias for whatever that is on
    the platform, or make 'char' signed on all platforms. But who am I
    to ask?

 2. 'unsigned long' and 'unsigned long long' are always different types,
    even if both are 64 bit numbers.

This commit fixes a few bugs that coming from this.

See Also: 1b3169f405.
2020-09-22 15:06:40 +02:00
asynts
4fcdc19b14 AK: Remove strtoull dependency from format.
This function is not avaliable in the kernel.

In the future it would be nice to have some sort of <charconv> header
that does this for all integer types and then call it in strtoull and et
cetera.

The difference would be that this function say 'from_chars' would return
an Optional and not just interpret anything invalid as zero.
2020-09-22 15:06:40 +02:00
asynts
2bda21318c AK: Add format function like std::format or fmt::format. 2020-09-21 20:17:36 +02:00