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