Skip to content

Commit d8c07bb

Browse files
committed
chore(readme): updated readme
1 parent 5a1780b commit d8c07bb

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

README.md

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@
77
[![Github Releases](https://img.shields.io/github/release/mpaland/printf.svg)](https://github.com/mpaland/printf/releases)
88
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/mpaland/avl_array/master/LICENSE)
99

10-
This is a tiny but **fully loaded** printf, sprintf and snprintf implementation.
10+
This is a tiny but **fully loaded** printf, sprintf and (v)snprintf implementation.
1111
Primarily designed for usage in embedded systems, where printf is not available due to memory issues or in avoidance of linking against libc.
1212
Using the standard libc printf may pull **a lot** of unwanted library stuff and can bloat code size about 20k or is not 100% thread safe. In this cases the following implementation can be used.
13-
Absolutely **NO dependencies** are required, *printf.c* brings all necessary routines, even its own fast `ftoa`, `ntoa` conversion.
13+
Absolutely **NO dependencies** are required, *printf.c* brings all necessary routines, even its own fast `ftoa` (float), `ntoa` (decimal) conversion.
1414

1515
If memory footprint is really a critical issue, floating point and 'long long' support and can be turned off via the `PRINTF_FLOAT_SUPPORT` and `PRINTF_LONG_LONG_SUPPORT` compiler switches.
16-
When using printf (instead of sprintf) you have to provide your own `_putchar()` low level function as console/serial output.
16+
When using printf (instead of sprintf/snprintf) you have to provide your own `_putchar()` low level function as console/serial output.
1717

1818

1919
## Highligths and design goals
2020

2121
There is a boatload of so called 'tiny' printf implementations around. So why this one?
22-
I've tested many implementations, but most of them have very limited flag/specifier support, a lot of other dependencies or are just not standard compliant and failing the test suite.
23-
Therefore I decided to write an own implementation which meets the following items:
22+
I've tested many implementations, but most of them have very limited flag/specifier support, a lot of other dependencies or are just not standard compliant and failing most of the test suite.
23+
Therefore I decided to write an own, final implementation which meets the following items:
2424

25-
- Very small implementation (< 500 code lines)
25+
- Very small implementation (around 500 code lines)
2626
- NO dependencies, no libs, just one module file
2727
- Support of all important flags, width and precision sub-specifiers (see below)
28-
- Support of dec/float number representation (with an own fast itoa/ftoa)
28+
- Support of decimal/floating number representation (with an own fast itoa/ftoa)
2929
- Reentrant and thread-safe, malloc free
30-
- LINT and compiler L4 warning free, coverity clean, automotive ready
31-
- Extensive test suite (> 280 test cases) passing
30+
- LINT and compiler L4 warning free, mature, coverity clean, automotive ready
31+
- Extensive test suite (> 300 test cases) passing
3232
- Simply the best *printf* around the net
3333
- MIT license
3434

@@ -49,10 +49,11 @@ Usage is 1:1 like the according stdio.h library version:
4949
int printf(const char* format, ...);
5050
int sprintf(char* buffer, const char* format, ...);
5151
int snprintf(char* buffer, size_t count, const char* format, ...);
52+
int vsnprintf(char* buffer, size_t count, const char* format, va_list va);
5253
```
5354

54-
**Due to genaral security reasons it is highly recommended to use `snprintf` (with the max buffer size as `count` parameter) only.**
55-
`sprintf` has no buffer limitation, so when necessary - use it with care!
55+
**Due to genaral security reasons it is highly recommended to use `snprintf` (with the max buffer size as `count` parameter) instead of `sprintf`.**
56+
`sprintf` has no buffer limitation, so when needed - use it really with care!
5657

5758

5859
## Format specifiers
@@ -69,10 +70,9 @@ The following format specifiers are supported:
6970
| u | Unsigned decimal integer |
7071
| b | Unsigned binary |
7172
| o | Unsigned octal |
72-
| x | Unsigned hexadecimal integer |
73+
| x | Unsigned hexadecimal integer (lowercase) |
7374
| X | Unsigned hexadecimal integer (uppercase) |
74-
| f | Decimal floating point, lowercase |
75-
| F | Decimal floating point, uppercase |
75+
| f or F | Decimal floating point |
7676
| c | Single character |
7777
| s | String of characters |
7878
| p | Pointer address |
@@ -90,14 +90,6 @@ The following format specifiers are supported:
9090
| 0 | Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier). |
9191

9292

93-
### Supported precision
94-
95-
| Precision | Description |
96-
|-----------|-------------|
97-
| .number | For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0.<br>For f and F specifiers: this is the number of digits to be printed after the decimal point. By default, this is 6, maximum is 9.<br>For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered.<br>If the period is specified without an explicit value for precision, 0 is assumed. |
98-
| .* | The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
99-
100-
10193
### Supported width
10294

10395
| Width | Description |
@@ -106,6 +98,14 @@ The following format specifiers are supported:
10698
| * | The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
10799

108100

101+
### Supported precision
102+
103+
| Precision | Description |
104+
|-----------|-------------|
105+
| .number | For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0.<br>For f and F specifiers: this is the number of digits to be printed after the decimal point. By default, this is 6, maximum is 9.<br>For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered.<br>If the period is specified without an explicit value for precision, 0 is assumed. |
106+
| .* | The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
107+
108+
109109
### Supported length
110110

111111
The length sub-specifier modifies the length of the data type.
@@ -114,38 +114,52 @@ The length sub-specifier modifies the length of the data type.
114114
|--------|------|---------|
115115
| (none) | int | unsigned int |
116116
| l | long int | unsigned long int |
117-
| ll | long long int | unsigned long long int |
117+
| ll | long long int | unsigned long long int (if PRINTF_LONG_LONG_SUPPORT is defined) |
118118
| z | size_t int | unsigned size_t int |
119119

120120

121+
### Return value
122+
Upon successful return, all functions return the number of characters _written_, _excluding_ the null byte used to end the string.
123+
Functions `snprintf()` and `vsnprintf()` don't write more than `count` bytes, _including_ the terminating null byte ('\0'). If the output was truncated
124+
due to this limit, the return value is `count`, which indicates any truncation.
125+
If an output error (invalid buffer etc.) is encountered, `-1` is returned.
126+
127+
128+
## Caveats
129+
Currently `snprintf()` and `vsnprintf()` don't support `(v)snprintf(nullptr, 0, "Some text")` to get the length of the formatted string only. An error value of `-1` is returned.
130+
131+
121132
## Compiler switches/defines
122133

123134
| Name | Default value | Description |
124135
|------|---------------|-------------|
125-
| PRINTF_BUFFER_SIZE | 128 | The buffer size used for printf |
126-
| NTOA_BUFFER_SIZE | 32 | ntoa (integer) conversion buffer size. This must be big enough to hold one converted numeric number, normally 32 is a sufficient value. |
127-
| FTOA_BUFFER_SIZE | 32 | ftoa (float) conversion buffer size. This must be big enough to hold one converted float number, normally 32 is a sufficient value. |
128-
| PRINTF_FLOAT_SUPPORT | defined | Define this to enable floating point (%f) support |
129-
| PRINTF_LONG_LONG_SUPPORT | defined | Define this to enable long long (%ll) support |
136+
| PRINTF_BUFFER_SIZE | 128 | The buffer size used for the printf() function (not for sprintf/snprintf). Set to 0 if the printf() function is unused (just using sprintf/snprintf) |
137+
| PRINTF_NTOA_BUFFER_SIZE | 32 | ntoa (integer) conversion buffer size. This must be big enough to hold one converted numeric number _including_ leading zeros, normally 32 is a sufficient value |
138+
| PRINTF_FTOA_BUFFER_SIZE | 32 | ftoa (float) conversion buffer size. This must be big enough to hold one converted float number _including_ leading zeros, normally 32 is a sufficient value |
139+
| PRINTF_FLOAT_SUPPORT | undefined | Define this to enable floating point (%f) support |
140+
| PRINTF_LONG_LONG_SUPPORT | undefined | Define this to enable long long (%ll) support |
130141

131142

132143
## Test suite
133-
For testing just compile, build and run the test suite located in `test/test_suite.cpp`. This uses the [catch](https://github.com/philsquared/Catch) framework for unit-tests, which is auto-adding main().
144+
For testing just compile, build and run the test suite located in `test/test_suite.cpp`. This uses the [catch](https://github.com/catchorg/Catch2) framework for unit-tests, which is auto-adding main().
145+
Running with the `--wait-for-keypress exit` option waits for the enter key after test end.
134146

135147

136148
## Projects using printf
137-
- [turnkey-board](https://github.com/mpaland/turnkey-board) uses printf as log and generic display formatting/output.
149+
- [turnkey-board](https://github.com/mpaland/turnkey-board) uses printf as log and generic display formatting/output.
150+
(Just send me a mail/issue to get your project listed here)
138151

139152

140153
## Contributing
141154

155+
0. Give this project a :star:
142156
1. Create an issue and describe your idea
143157
2. [Fork it](https://github.com/mpaland/printf/fork)
144158
3. Create your feature branch (`git checkout -b my-new-feature`)
145159
4. Commit your changes (`git commit -am 'Add some feature'`)
146160
5. Publish the branch (`git push origin my-new-feature`)
147161
6. Create a new pull request
148-
7. Profit! :white_check_mark:
162+
7. Profit! :heavy_check_mark:
149163

150164

151165
## License

0 commit comments

Comments
 (0)