vlprint.c (1132B)
1 /* Copyright ©2010 Kris Maglione <maglione.k at Gmail> 2 * Copyright ©2002 by Lucent Technologies. 3 * See LICENSE file for license details. 4 */ 5 #include "fmtdef.h" 6 #include <unistd.h> 7 8 static int 9 fmtlfdflush(Fmt *f) { 10 mbstate_t state; 11 char buf[256]; 12 Rune *rp, *rend; 13 char *sp, *send; 14 int res; 15 16 sp = buf; 17 send = buf + sizeof buf - UTFmax; 18 rend = f->to; 19 state = (mbstate_t){0}; 20 for(rp=(Rune*)f->start; rp < rend; rp++) { 21 res = wcrtomb(sp, *rp, &state); 22 if(res == -1) 23 *sp++ = '?'; /* Fixme? */ 24 else 25 sp += res; 26 if(sp >= send || rp == rend - 1) { 27 if(write((uintptr_t)f->farg, buf, sp - buf) != sp - buf) 28 return 0; 29 sp = buf; 30 } 31 } 32 f->to = f->start; 33 return 1; 34 } 35 36 int 37 vlprint(int fd, const char *fmt, va_list args) { 38 Fmt f; 39 Rune buf[256]; 40 int res; 41 42 if(utf8locale()) 43 return vfprint(fd, fmt, args); 44 45 f.runes = 1; 46 f.start = (char*)buf; 47 f.to = (char*)buf; 48 f.stop = (char*)(buf + nelem(buf) - 1); 49 f.flush = fmtlfdflush; 50 f.farg = (void*)(uintptr_t)fd; 51 f.nfmt = 0; 52 53 va_copy(f.args, args); 54 res = dofmt(&f, fmt); 55 va_end(f.args); 56 if(res > 0 && fmtlfdflush(&f) == 0) 57 return -1; 58 return res; 59 } 60