rpm  4.5
stringbuf.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include "stringbuf.h"
8 #include "debug.h"
9 
10 #define BUF_CHUNK 1024
11 
12 struct StringBufRec {
13 /*@owned@*/
14  char *buf;
15 /*@dependent@*/
16  char *tail; /* Points to first "free" char */
17  int allocated;
18  int free;
19 };
20 
24 /*@unused@*/ static inline int xisspace(int c) /*@*/ {
25  return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v');
26 }
27 
33 /*@unused@*/ static inline /*@null@*/ void *
34 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p) /*@modifies *p @*/
35 {
36  if (p != NULL) free((void *)p);
37  return NULL;
38 }
39 
41 {
42  StringBuf sb = xmalloc(sizeof(*sb));
43 
44  sb->free = sb->allocated = BUF_CHUNK;
45  sb->buf = xcalloc(sb->allocated, sizeof(*sb->buf));
46  sb->buf[0] = '\0';
47  sb->tail = sb->buf;
48 
49  return sb;
50 }
51 
53 {
54  if (sb) {
55  sb->buf = _free(sb->buf);
56  sb = _free(sb);
57  }
58  return sb;
59 }
60 
62 {
63 /*@-boundswrite@*/
64  sb->buf[0] = '\0';
65 /*@=boundswrite@*/
66  sb->tail = sb->buf;
67  sb->free = sb->allocated;
68 }
69 
71 {
72 /*@-bounds@*/
73  while (sb->free != sb->allocated) {
74  if (! xisspace(*(sb->tail - 1)))
75  break;
76  sb->free++;
77  sb->tail--;
78  }
79  sb->tail[0] = '\0';
80 /*@=bounds@*/
81 }
82 
84 {
85  return sb->buf;
86 }
87 
88 void appendStringBufAux(StringBuf sb, const char *s, int nl)
89 {
90  int l;
91 
92  l = strlen(s);
93  /* If free == l there is no room for NULL terminator! */
94  while ((l + nl + 1) > sb->free) {
95  sb->allocated += BUF_CHUNK;
96  sb->free += BUF_CHUNK;
97  sb->buf = xrealloc(sb->buf, sb->allocated);
98  sb->tail = sb->buf + (sb->allocated - sb->free);
99  }
100 
101 /*@-boundswrite@*/
102  /*@-mayaliasunique@*/ /* FIX: shrug */
103  strcpy(sb->tail, s);
104  /*@=mayaliasunique@*/
105  sb->tail += l;
106  sb->free -= l;
107  if (nl) {
108  sb->tail[0] = '\n';
109  sb->tail[1] = '\0';
110  sb->tail++;
111  sb->free--;
112  }
113 /*@=boundswrite@*/
114 }