printbuf.c
Go to the documentation of this file.
1 /*
2  * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
3  *
4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5  * Michael Clark <michael@metaparadigm.com>
6  *
7  * This library is free software; you can redistribute it and/or modify
8  * it under the terms of the MIT license. See COPYING for details.
9  *
10  */
11 
12 #include "config.h"
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #if HAVE_STDARG_H
19 # include <stdarg.h>
20 #else /* !HAVE_STDARG_H */
21 # error Not enough var arg support!
22 #endif /* HAVE_STDARG_H */
23 
24 #include "bits.h"
25 #include "debug.h"
26 #include "printbuf.h"
27 
29 {
30  struct printbuf *p;
31 
32  if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
33  p->size = 32;
34  p->bpos = 0;
35  if(!(p->buf = malloc( (size_t) p->size))) {
36  free(p);
37  return NULL;
38  }
39  return p;
40 }
41 
42 
43 int printbuf_memappend(struct printbuf *p, const char *buf, int size)
44 {
45  char *t;
46  if(p->size - p->bpos <= size) {
47  int new_size = max(p->size * 2, p->bpos + size + 8);
48 #ifdef PRINTBUF_DEBUG
49  mc_debug("printbuf_memappend: realloc "
50  "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
51  p->bpos, size, p->size, new_size);
52 #endif /* PRINTBUF_DEBUG */
53  if(!(t = realloc(p->buf, (size_t) new_size))) return -1;
54  p->size = new_size;
55  p->buf = t;
56  }
57  memcpy(p->buf + p->bpos, buf, (size_t) size);
58  p->bpos += size;
59  p->buf[p->bpos]= '\0';
60  return size;
61 }
62 
63 #if !HAVE_VSNPRINTF && defined(WIN32)
64 # define vsnprintf _vsnprintf
65 #elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */
66 # error Need vsnprintf!
67 #endif /* !HAVE_VSNPRINTF && defined(WIN32) */
68 
69 #if !HAVE_VASPRINTF
70 /* CAW: compliant version of vasprintf */
71 static int vasprintf(char **buf, const char *fmt, va_list ap)
72 {
73 #ifndef WIN32
74  static char _T_emptybuffer = '\0';
75 #endif /* !defined(WIN32) */
76  int chars;
77  char *b;
78 
79  if(!buf) { return -1; }
80 
81 #ifdef WIN32
82  chars = _vscprintf(fmt, ap)+1;
83 #else /* !defined(WIN32) */
84  /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
85  our buffer like on some 64bit sun systems.... but hey, its time to move on */
86  chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
87  if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
88 #endif /* defined(WIN32) */
89 
90  b = (char*)malloc(sizeof(char)*chars);
91  if(!b) { return -1; }
92 
93  if((chars = vsprintf(b, fmt, ap)) < 0)
94  {
95  free(b);
96  } else {
97  *buf = b;
98  }
99 
100  return chars;
101 }
102 #endif /* !HAVE_VASPRINTF */
103 
104 int sprintbuf(struct printbuf *p, const char *msg, ...)
105 {
106  va_list ap;
107  char *t;
108  int size;
109  char buf[128];
110 
111  /* user stack buffer first */
112  va_start(ap, msg);
113  size = vsnprintf(buf, 128, msg, ap);
114  va_end(ap);
115  /* if string is greater than stack buffer, then use dynamic string
116  with vasprintf. Note: some implementation of vsnprintf return -1
117  if output is truncated whereas some return the number of bytes that
118  would have been writen - this code handles both cases. */
119  if(size == -1 || size > 127) {
120  int ret;
121  va_start(ap, msg);
122  if((size = vasprintf(&t, msg, ap)) == -1) return -1;
123  va_end(ap);
124  ret = printbuf_memappend(p, t, size);
125  free(t);
126  return ret;
127  } else {
128  return printbuf_memappend(p, buf, size);
129  }
130 }
131 
132 void printbuf_reset(struct printbuf *p)
133 {
134  p->buf[0] = '\0';
135  p->bpos = 0;
136 }
137 
138 void printbuf_free(struct printbuf *p)
139 {
140  if(p) {
141  free(p->buf);
142  free(p);
143  }
144 }
int bpos
Definition: printbuf.h:19
char * buf
Definition: printbuf.h:18
void mc_debug(const char *msg,...)
Definition: debug.c:58
#define max(a, b)
Definition: bits.h:20
struct printbuf * printbuf_new()
Definition: printbuf.c:28
struct @0 p
void printbuf_free(struct printbuf *p)
Definition: printbuf.c:138
static int vasprintf(char **buf, const char *fmt, va_list ap)
Definition: printbuf.c:71
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
Definition: printbuf.c:43
int sprintbuf(struct printbuf *p, const char *msg,...)
Definition: printbuf.c:104
void printbuf_reset(struct printbuf *p)
Definition: printbuf.c:132
int size
Definition: printbuf.h:20
char buf[100]
Definition: ld_recover.c:87


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23