xref: /plan9/sys/src/libc/fmt/runevsmprint.c (revision 9b7bf7df4595c26f1e9b67beb0c6e44c9876fb05)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include "fmtdef.h"
49a747e4fSDavid du Colombier 
59a747e4fSDavid du Colombier static int
runeFmtStrFlush(Fmt * f)69a747e4fSDavid du Colombier runeFmtStrFlush(Fmt *f)
79a747e4fSDavid du Colombier {
89a747e4fSDavid du Colombier 	Rune *s;
99a747e4fSDavid du Colombier 	int n;
109a747e4fSDavid du Colombier 
1165fa3f8bSDavid du Colombier 	if(f->start == nil)
1265fa3f8bSDavid du Colombier 		return 0;
1374f16c81SDavid du Colombier 	n = (int)(uintptr)f->farg;
1465fa3f8bSDavid du Colombier 	n *= 2;
159a747e4fSDavid du Colombier 	s = f->start;
1641eff910SDavid du Colombier 	f->start = realloc(s, sizeof(Rune)*n);
179a747e4fSDavid du Colombier 	if(f->start == nil){
1865fa3f8bSDavid du Colombier 		f->farg = nil;
1965fa3f8bSDavid du Colombier 		f->to = nil;
2065fa3f8bSDavid du Colombier 		f->stop = nil;
2165fa3f8bSDavid du Colombier 		free(s);
229a747e4fSDavid du Colombier 		return 0;
239a747e4fSDavid du Colombier 	}
2465fa3f8bSDavid du Colombier 	f->farg = (void*)n;
259a747e4fSDavid du Colombier 	f->to = (Rune*)f->start + ((Rune*)f->to - s);
269a747e4fSDavid du Colombier 	f->stop = (Rune*)f->start + n - 1;
279a747e4fSDavid du Colombier 	return 1;
289a747e4fSDavid du Colombier }
299a747e4fSDavid du Colombier 
309a747e4fSDavid du Colombier int
runefmtstrinit(Fmt * f)319a747e4fSDavid du Colombier runefmtstrinit(Fmt *f)
329a747e4fSDavid du Colombier {
339a747e4fSDavid du Colombier 	int n;
349a747e4fSDavid du Colombier 
35bedadc12SDavid du Colombier 	memset(f, 0, sizeof *f);
369a747e4fSDavid du Colombier 	f->runes = 1;
379a747e4fSDavid du Colombier 	n = 32;
389a747e4fSDavid du Colombier 	f->start = malloc(sizeof(Rune)*n);
399a747e4fSDavid du Colombier 	if(f->start == nil)
409a747e4fSDavid du Colombier 		return -1;
41*9b7bf7dfSDavid du Colombier 	setmalloctag(f->start, getcallerpc(&f));
429a747e4fSDavid du Colombier 	f->to = f->start;
439a747e4fSDavid du Colombier 	f->stop = (Rune*)f->start + n - 1;
449a747e4fSDavid du Colombier 	f->flush = runeFmtStrFlush;
459a747e4fSDavid du Colombier 	f->farg = (void*)n;
469a747e4fSDavid du Colombier 	f->nfmt = 0;
479a747e4fSDavid du Colombier 	return 0;
489a747e4fSDavid du Colombier }
499a747e4fSDavid du Colombier 
509a747e4fSDavid du Colombier /*
519a747e4fSDavid du Colombier  * print into an allocated string buffer
529a747e4fSDavid du Colombier  */
539a747e4fSDavid du Colombier Rune*
runevsmprint(char * fmt,va_list args)549a747e4fSDavid du Colombier runevsmprint(char *fmt, va_list args)
559a747e4fSDavid du Colombier {
569a747e4fSDavid du Colombier 	Fmt f;
579a747e4fSDavid du Colombier 	int n;
589a747e4fSDavid du Colombier 
599a747e4fSDavid du Colombier 	if(runefmtstrinit(&f) < 0)
609a747e4fSDavid du Colombier 		return nil;
619a747e4fSDavid du Colombier 	f.args = args;
629a747e4fSDavid du Colombier 	n = dofmt(&f, fmt);
63*9b7bf7dfSDavid du Colombier 	if(f.start == nil)		/* realloc failed? */
649a747e4fSDavid du Colombier 		return nil;
6565fa3f8bSDavid du Colombier 	if(n < 0){
6665fa3f8bSDavid du Colombier 		free(f.start);
6765fa3f8bSDavid du Colombier 		return nil;
6865fa3f8bSDavid du Colombier 	}
69*9b7bf7dfSDavid du Colombier 	setmalloctag(f.start, getcallerpc(&fmt));
709a747e4fSDavid du Colombier 	*(Rune*)f.to = '\0';
719a747e4fSDavid du Colombier 	return f.start;
729a747e4fSDavid du Colombier }
73