xref: /plan9/sys/src/cmd/unix/drawterm/libc/encodefmt.c (revision 1a4050f5b2ddf426a278e3233ccd7b6bcb0639b8)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 
5 int
encodefmt(Fmt * f)6 encodefmt(Fmt *f)
7 {
8 	char *out;
9 	char *buf;
10 	int len;
11 	int ilen;
12 	int rv;
13 	uchar *b;
14 	char *p;
15 	char obuf[64];	// rsc optimization
16 
17 	if(!(f->flags&FmtPrec) || f->prec < 1)
18 		goto error;
19 
20 	b = va_arg(f->args, uchar*);
21 	if(b == 0)
22 		return fmtstrcpy(f, "<nil>");
23 
24 	ilen = f->prec;
25 	f->prec = 0;
26 	f->flags &= ~FmtPrec;
27 	switch(f->r){
28 	case '<':
29 		len = (8*ilen+4)/5 + 3;
30 		break;
31 	case '[':
32 		len = (8*ilen+5)/6 + 4;
33 		break;
34 	case 'H':
35 		len = 2*ilen + 1;
36 		break;
37 	default:
38 		goto error;
39 	}
40 
41 	if(len > sizeof(obuf)){
42 		buf = malloc(len);
43 		if(buf == nil)
44 			goto error;
45 	} else
46 		buf = obuf;
47 
48 	// convert
49 	out = buf;
50 	switch(f->r){
51 	case '<':
52 		rv = enc32(out, len, b, ilen);
53 		break;
54 	case '[':
55 		rv = enc64(out, len, b, ilen);
56 		break;
57 	case 'H':
58 		rv = enc16(out, len, b, ilen);
59 		if(rv >= 0 && (f->flags & FmtLong))
60 			for(p = buf; *p; p++)
61 				*p = tolower(*p);
62 		break;
63 	default:
64 		rv = -1;
65 		break;
66 	}
67 	if(rv < 0)
68 		goto error;
69 
70 	fmtstrcpy(f, buf);
71 	if(buf != obuf)
72 		free(buf);
73 	return 0;
74 
75 error:
76 	return fmtstrcpy(f, "<encodefmt>");
77 }
78