diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libc/port/encodefmt.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libc/port/encodefmt.c')
-rwxr-xr-x | sys/src/libc/port/encodefmt.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/sys/src/libc/port/encodefmt.c b/sys/src/libc/port/encodefmt.c new file mode 100755 index 000000000..721a58c9f --- /dev/null +++ b/sys/src/libc/port/encodefmt.c @@ -0,0 +1,77 @@ +#include <u.h> +#include <libc.h> +#include <ctype.h> + +int +encodefmt(Fmt *f) +{ + char *out; + char *buf; + int len; + int ilen; + int rv; + uchar *b; + char *p; + char obuf[64]; // rsc optimization + + if(!(f->flags&FmtPrec) || f->prec < 1) + goto error; + + b = va_arg(f->args, uchar*); + if(b == 0) + return fmtstrcpy(f, "<nil>"); + + ilen = f->prec; + f->prec = 0; + f->flags &= ~FmtPrec; + switch(f->r){ + case '<': + len = (8*ilen+4)/5 + 3; + break; + case '[': + len = (8*ilen+5)/6 + 4; + break; + case 'H': + len = 2*ilen + 1; + break; + default: + goto error; + } + + if(len > sizeof(obuf)){ + buf = malloc(len); + if(buf == nil) + goto error; + } else + buf = obuf; + + // convert + out = buf; + switch(f->r){ + case '<': + rv = enc32(out, len, b, ilen); + break; + case '[': + rv = enc64(out, len, b, ilen); + break; + case 'H': + rv = enc16(out, len, b, ilen); + if(rv >= 0 && (f->flags & FmtLong)) + for(p = buf; *p; p++) + *p = tolower(*p); + break; + default: + rv = -1; + break; + } + if(rv < 0) + goto error; + + fmtstrcpy(f, buf); + if(buf != obuf) + free(buf); + return 0; + +error: + return fmtstrcpy(f, "<encodefmt>"); +} |