xref: /inferno-os/libkern/vsmprint.c (revision 5d0c4cf3fc288434c41cba52dd998ab1d7375a7b)
1  /*
2   * The authors of this software are Rob Pike and Ken Thompson.
3   *              Copyright (c) 2002 by Lucent Technologies.
4   * Permission to use, copy, modify, and distribute this software for any
5   * purpose without fee is hereby granted, provided that this entire notice
6   * is included in all copies of any software which is or includes a copy
7   * or modification of this software and in all copies of the supporting
8   * documentation for such software.
9   * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10   * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
11   * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12   * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13   */
14  #include "lib9.h"
15  #include "fmtdef.h"
16  
17  static int
18  fmtStrFlush(Fmt *f)
19  {
20  	char *s;
21  	int n;
22  
23  	if(f->start == nil)
24  		return 0;
25  	n = (int)f->farg;
26  	n += 256;
27  	f->farg = (void*)n;
28  	s = f->start;
29  	f->start = realloc(s, n);
30  	if(f->start == nil){
31  		free(s);
32  		f->to = nil;
33  		f->stop = nil;
34  		return 0;
35  	}
36  	f->to = (char*)f->start + ((char*)f->to - s);
37  	f->stop = (char*)f->start + n - 1;
38  	return 1;
39  }
40  
41  int
42  fmtstrinit(Fmt *f)
43  {
44  	int n;
45  
46  	memset(f, 0, sizeof(*f));
47  	n = 32;
48  	f->start = malloc(n);
49  	if(f->start == nil)
50  		return -1;
51  	f->to = f->start;
52  	f->stop = (char*)f->start + n - 1;
53  	f->flush = fmtStrFlush;
54  	f->farg = (void*)n;
55  	f->nfmt = 0;
56  	return 0;
57  }
58  
59  /*
60   * print into an allocated string buffer
61   */
62  char*
63  vsmprint(char *fmt, va_list args)
64  {
65  	Fmt f;
66  	int n;
67  
68  	if(fmtstrinit(&f) < 0)
69  		return nil;
70  	va_copy(f.args, args);
71  	n = dofmt(&f, fmt);
72  	va_end(f.args);
73  	if(n < 0){
74  		free(f.start);
75  		f.start = nil;
76  		return nil;
77  	}
78  	return fmtstrflush(&f);
79  }
80