9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

vsmprint.c (1393B)


      1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
      2 /*
      3  * Plan 9 port version must include libc.h in order to 
      4  * get Plan 9 debugging malloc, which sometimes returns
      5  * different pointers than the standard malloc. 
      6  */
      7 #ifdef PLAN9PORT
      8 #include <u.h>
      9 #include <libc.h>
     10 #include "fmtdef.h"
     11 #else
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include "plan9.h"
     15 #include "fmt.h"
     16 #include "fmtdef.h"
     17 #endif
     18 
     19 static int
     20 fmtStrFlush(Fmt *f)
     21 {
     22 	char *s;
     23 	int n;
     24 
     25 	if(f->start == nil)
     26 		return 0;
     27 	n = (uintptr)f->farg;
     28 	n *= 2;
     29 	s = (char*)f->start;
     30 	f->start = realloc(s, n);
     31 	if(f->start == nil){
     32 		f->farg = nil;
     33 		f->to = nil;
     34 		f->stop = nil;
     35 		free(s);
     36 		return 0;
     37 	}
     38 	f->farg = (void*)(uintptr)n;
     39 	f->to = (char*)f->start + ((char*)f->to - s);
     40 	f->stop = (char*)f->start + n - 1;
     41 	return 1;
     42 }
     43 
     44 int
     45 fmtstrinit(Fmt *f)
     46 {
     47 	int n;
     48 
     49 	memset(f, 0, sizeof *f);
     50 	f->runes = 0;
     51 	n = 32;
     52 	f->start = malloc(n);
     53 	if(f->start == nil)
     54 		return -1;
     55 	f->to = f->start;
     56 	f->stop = (char*)f->start + n - 1;
     57 	f->flush = fmtStrFlush;
     58 	f->farg = (void*)(uintptr)n;
     59 	f->nfmt = 0;
     60 	fmtlocaleinit(f, nil, nil, nil);
     61 	return 0;
     62 }
     63 
     64 /*
     65  * print into an allocated string buffer
     66  */
     67 char*
     68 vsmprint(char *fmt, va_list args)
     69 {
     70 	Fmt f;
     71 	int n;
     72 
     73 	if(fmtstrinit(&f) < 0)
     74 		return nil;
     75 	VA_COPY(f.args,args);
     76 	n = dofmt(&f, fmt);
     77 	VA_END(f.args);
     78 	if(n < 0){
     79 		free(f.start);
     80 		return nil;
     81 	}
     82 	return fmtstrflush(&f);
     83 }