shachaf@iodine:~/fmt$ cat main.c #include #include #define CUSTOM_FMT_TYPES \ FMT_TYPE(struct tm *, 123) #include "fmt.h" int custom_fmt_arg(char *buf, size_t size, FmtArg arg, FmtSpec spec) { if (arg.type == 123) { char timefmt_buf[spec.custom_len + 1]; char *timefmt = timefmt_buf; if (spec.custom_len > 0) { memcpy(timefmt_buf, spec.custom_start, spec.custom_len); timefmt[spec.custom_len] = '\0'; } else { timefmt = "%Y-%m-%d"; } struct tm *tm = *(struct tm **)arg.data; size_t len = strftime(buf, size, timefmt, tm); return len; } return -1; } int main(int argc, char **argv) { char x = 'x'; time_t now = time(0); struct tm *tm = localtime(&now); outfmt("hello {} {}\n", 123, "hi"); outfmt("hello {:c}\n", x); outfmt("hello {:05} 0x{:05x}\n", 123, 0xa66e); outfmt("no arguments\n"); outfmt("positional arguments: {1:c}{0:c}{2:c}{2:c}{3:c}\n", 'e', 'h', 'l', 'o'); outfmt("pointers: {:p} {:p}\n", "abc", (void *)0); outfmt("custom formatting: now is {|%Y-%m-%d %H:%M:%S} (default format: {0})\n", tm); outfmt("{} arguments\n", argc); for (int i = 0; i < argc; i++) { outfmt(" argument {}: {}\n", i, argv[i]); } return 0; } shachaf@iodine:~/fmt$ gcc -Wall -g -o main main.c && ./main test hello 123 hi hello x hello 00123 0x0a66e no arguments positional arguments: hello pointers: 0x55b8f93b83a1 (nil) custom formatting: now is 2019-04-21 22:06:09 (default format: 2019-04-21) 2 arguments argument 0: ./main argument 1: test