Mirrored from: http://www.quanstro.net/plan9/pctv.html
A small illustration of how to use typeof in ken's c compiler to implement %v.
A small change to the compiler's varadic function checking is required to allow a single verb to use more than one argument. For brevity this change is excluded.
#include <u.h> #include <libc.h> int fmtv(Fmt *f) { ulong sign; extern int _ifmt(Fmt*); extern int _strfmt(Fmt*); extern int _runesfmt(Fmt*); sign = va_arg(f->args, ulong); switch(sign){ case signof(uchar): f->flags |= FmtUnsigned; case signof(char): f->flags |= FmtByte; f->r = f->flags&FmtSharp? 'x': 'd'; return _ifmt(f); case signof(ushort): f->flags |= FmtUnsigned; case signof(short): f->flags |= FmtShort; f->r = f->flags&FmtSharp? 'x': 'd'; return _ifmt(f); case signof(uint): f->flags |= FmtUnsigned; case signof(int): f->r = f->flags&FmtSharp? 'x': 'd'; return _ifmt(f); case signof(ulong): f->flags |= FmtUnsigned; case signof(long): f->r = f->flags&FmtSharp? 'x': 'd'; f->flags |= FmtLong; return _ifmt(f); case signof(vlong): f->flags |= FmtUnsigned; case signof(uvlong): f->r = f->flags&FmtSharp? 'x': 'd'; f->flags |= FmtVLong; return _ifmt(f); case signof(char*): case signof(char[]): return _strfmt(f); case signof(Rune*): case signof(Rune[]): return _runesfmt(f); default: return fmtprint(f, "<%%v>"); } } #pragma varargck type "v" ulong,char #pragma varargck type "v" ulong,short #pragma varargck type "v" ulong,int #pragma varargck type "v" ulong,long #pragma varargck type "v" ulong,vlong #pragma varargck type "v" ulong,uchar #pragma varargck type "v" ulong,ushort #pragma varargck type "v" ulong,uint #pragma varargck type "v" ulong,ulong #pragma varargck type "v" ulong,uvlong #pragma varargck type "v" ulong,char* #define V(x) signof(x), (x) void main(void) { u32int x; fmtinstall('v', fmtv); print("%v\n", V(1)); print("%v\n", V("abc")); x = 32; print("%v\n", V(x)); print("%#v\n", V(x)); print("%v\n", V((char)x)); print("%v\n", V((int)x)); print("%v\n", V((long)x)); print("%v\n", V((vlong)x)); exits(""); }