| #include <lib9.h> |
| |
| int |
| encodefmt(Fmt *f) |
| { |
| char *out; |
| char *buf, *p; |
| int len; |
| int ilen; |
| int rv; |
| uchar *b; |
| char obuf[64]; /* rsc optimization */ |
| |
| b = va_arg(f->args, uchar*); |
| if(b == 0) |
| return fmtstrcpy(f, "<nil>"); |
| |
| ilen = f->prec; |
| f->prec = 0; |
| |
| if(!(f->flags&FmtPrec) || ilen < 0) |
| goto error; |
| |
| 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((uchar)*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>"); |
| } |