callback_printf? Why even another sprintf clone? Because it is one of the most important C functions but the lack of the portability of the format specifiers especially between Windows and Posix systems can be be very annoying. All the required workarounds and adjustments cost the programmers a lot of time. Who wants to mess around with different prefixes or format strings on every new platform? OK - there are a plenty of other sprintf implementations already but many of them don't really care the performance and the portability, or lack floating point and especially long double support, they don't convert Unicode strings to UTF-8 and don't care much about the conformance to the C standard formats or the printf parameter validation features of the gcc which are a great thing for preventing unexpected crashes within printf like function. You don't want any internal locks, unnecessary allocations or strange implementations which may slow down your code even if every microsecond counts. callback_printf uses only the stack of the calling thread and neither locks nor allocations. It allows you to debug and fix problems very easily if something doesn't work as expected. I guess that every programmer who really likes C hates the trouble with printf like functions and even more the problems and the difficulties if he want to use the argument format for own output functions or wants own extensions of that format. If it comes to me it was always a wish of me to get rid of all this trouble and the portability issues that most programmers are struggling with. And I did want to add some extra length specifiers for using arguments of type int8_t, int16_t, int32_t and int64_t which can be found since Posix 98 in inttypes.h and as well in stdint.h since C11 now. In the C 23 standard there will be be some different length specifiers for that then the l1, l2, l4 or l8 prefixes that callback_printf uses. But it's not a big thing to update the code for supporting the new prefixes too once the new C standard is finally available. The supported format specifiers are b, B, d, i, o, u, x, X, a, A, e, E, f, F, g, G, s, c, p, n and % for a percent character and the Microsoft specific specifiers C and S. The supported size prefixes for the integer formats b, B, d, i, o, u, x and X are currently hh, h, l, ll, t, z and j according to the C standard as well as the Microsoft specific I, I16, I32 and I64. Additionally some own prefixes l1, l2, l4 and l8 are supported which specify the byte width of the provided integer arguments. The supported lenght modifiers for the formats s and c are l for wchar_t arguments and l1 for 1 byte ISO Latin 8 strings, l2 for 2 byte wide Unicode characters and l4 for 4 bytes wide unicode characters. For the floating point formats a, A, e, E, f, F, g and G the prefix L for long double arguments is supported. Additionally a special prefix for specifying a specific numeric base of integer or floating point numbers is supported. It's r0 for base 10, r1 for base 16 and r2 ... r9 for the bases 2 til 9. Instead of a numeric value an asterisk * can be specified as well. In that case the base needs to be specified by an additional argument of type int just before the integer or floating specifier or it's optional length specifier. The highest supported numeric base is 36. Floating point exponents for bases higher than 14 are prefixed by a tilde (~) istead of the letter 'e' which becomes a member of the regular digits of those bases. An interesting feature is the unintentional and very fast generic mantisse and exponent calculation for the different numeric base systems that enables the support of all of those numeric systems. Where else do you find a genereric solution for printing floating points in that many different base systems? The little benchmark vsprintf_bench.c is an easy way for checking the performance. Just execute that file in a shell of a Posix system and have a look on the outpout. The callback_printf based wrappers are prefixed with an s for 'speed' and for 'security' because you won't share your string data with compiler libraries which can be a security issue in some special use cases where you need to prevent sniffing. Why that 'Civil Usage Public License' and not the GPL anymore? The new license is kind a mix of the conditions of BSD or Apache license but in opposite to the former it prohibits any usage for weapons, spyware and secret monitoring of any people without their knowledge or agreement. That's fine for most commercial use cases but I dislike the idea to find any of my software in military devices, weapons or spyware because it's pretty good tracable in the binaries of nearly all common compilers. A civil only usage is not a big deal for most people except for the ones who make money out of wars, dead people and things that are usually pretty nasty. I don't expect anything good in return of supporting those people with my software for free. It's for sure a good idea to use the software legally only by caring the conditions of the license. I doubt that anybody has a problem with the changed license because there wasn't any feedback because of the much more restrictive license conditions of the GPL before either. It would be nice if more people would use that license. Kind regards, Klaus Lux
klux21/callback_printf
callback_printf allows the implementation of portable sprintf, snprintf, vsprintf and vsnprintf like output functions. The code includes wrappers for those functions. It supports all formats of the C 11 standard. wchar_t arguments and strings are printed as UTF-8. It's pretty fast, threadsafe and has no dependencies to other libraries.
CNOASSERTION