// `man printf` // https://www.man7.org/linux/man-pages/man3/printf.3.html // https://en.cppreference.com/w/c/io/fprintf#Parameters // https://www.gnu.org/software/libc/manual/html_node/Formatted-Output.html // https://www.gnu.org/software/libc/manual/html_node/Output-Conversion-Syntax.html // https://www.gnu.org/software/libc/manual/html_node/Table-of-Output-Conversions.html // https://www.gnu.org/software/libc/manual/html_node/Parsing-a-Template-String.html // https://www.gnu.org/software/libc/manual/html_node/Example-of-Parsing.html // `parse_printf_format` // https://www.gnu.org/savannah-checkouts/gnu/libc/ // https://sourceware.org/git/?p=glibc.git // https://sourceware.org/git/?p=glibc.git;a=blob;f=manual/stdio.texi#validate_args/parse_printf_format var print = fn( #format :'[]u8, args :print_args( format ) ) :void { }; var print_args = fn( #format :'[]u8 ) :!type { var args :mut type = [_]type; var ii :mut usize = 0; for( format, 0.. ) |c,i| { if( i < ii ) { continue }; if( c <> '%' ) { continue }; if( i+1 < format.len ) { @compile_error( "unfinished format token" ); raise @error( "unfinished format token" ); }; var cc = format[ i+1 ]; switch( cc ) { case( '%' ) {}; // '%' literal case( 'c' ) {}; // character case( 's' ) {}; // string case( 'i', 'd' ) {}; // integer, decimal case( 'x', 'X' ) {}; // hex case( 'b' ) {}; // binary case( 'f', 'e' ) {}; // float, exponential else { @compile_error( "invalid format escape" ); raise @error( "invalid format escape" ); }; }; }; return @type( .record( .style = .tuple, .types = args, ) ); } // https://musl.libc.org/ // https://www.musl-libc.org/ // https://git.musl-libc.org/cgit/musl // https://git.musl-libc.org/cgit/musl/tree/src/stdio