A tiling window manager
1/*
2 * Functions for handling string buffers.
3 * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA.
18 */
19
20#include <string.h>
21
22#include "sdorfehs.h"
23#include "sbuf.h"
24
25struct sbuf *
26sbuf_new(size_t initsz)
27{
28 struct sbuf *b = xmalloc(sizeof(struct sbuf));
29
30 if (initsz < 1)
31 initsz = 1;
32
33 b->data = xmalloc(initsz);
34 b->maxsz = initsz;
35
36 b->data[0] = '\0';
37 b->len = 0;
38
39 return b;
40}
41
42void
43sbuf_free(struct sbuf *b)
44{
45 if (b != NULL) {
46 free(b->data);
47 free(b);
48 }
49}
50
51/* Free the structure but return the string. */
52char *
53sbuf_free_struct(struct sbuf *b)
54{
55 if (b != NULL) {
56 char *tmp;
57 tmp = b->data;
58 free(b);
59 return tmp;
60 }
61 return NULL;
62}
63
64char *
65sbuf_nconcat(struct sbuf *b, const char *str, int len)
66{
67 size_t minsz = b->len + len + 1;
68
69 if (b->maxsz < minsz) {
70 b->data = xrealloc(b->data, minsz);
71 b->maxsz = minsz;
72 }
73 memcpy(b->data + b->len, str, minsz - b->len - 1);
74 b->len = minsz - 1;
75 *(b->data + b->len) = 0;
76
77 return b->data;
78}
79
80
81char *
82sbuf_concat(struct sbuf *b, const char *str)
83{
84 return sbuf_nconcat(b, str, strlen(str));
85}
86
87char *
88sbuf_copy(struct sbuf *b, const char *str)
89{
90 b->len = 0;
91 return sbuf_concat(b, str);
92}
93
94char *
95sbuf_clear(struct sbuf *b)
96{
97 b->len = 0;
98 b->data[0] = '\0';
99 return b->data;
100}
101
102char *
103sbuf_get(struct sbuf *b)
104{
105 return b->data;
106}
107
108char *
109sbuf_printf(struct sbuf *b, char *fmt,...)
110{
111 va_list ap;
112
113 free(b->data);
114
115 va_start(ap, fmt);
116 b->data = xvsprintf(fmt, ap);
117 va_end(ap);
118
119 b->len = strlen(b->data);
120 b->maxsz = b->len + 1;
121
122 return b->data;
123}
124
125char *
126sbuf_printf_concat(struct sbuf *b, char *fmt,...)
127{
128 char *buffer;
129 va_list ap;
130
131 va_start(ap, fmt);
132 buffer = xvsprintf(fmt, ap);
133 va_end(ap);
134
135 sbuf_concat(b, buffer);
136 free(buffer);
137
138 return b->data;
139}
140
141/* if width >= 0 then limit the width of s to width chars. */
142char *
143sbuf_utf8_nconcat(struct sbuf *b, const char *s, int width)
144{
145 if (width >= 0) {
146 int len, nchars;
147
148 len = nchars = 0;
149 while (s[len] != '\0' && nchars < width) {
150 if (isu8start(s[len]))
151 do
152 len++;
153 while (isu8cont(s[len]));
154 else
155 len++;
156 nchars++;
157 }
158 sbuf_printf_concat(b, "%.*s", len, s);
159 } else
160 sbuf_concat(b, s);
161
162 return b->data;
163}
164
165void
166sbuf_chop(struct sbuf *b)
167{
168 if (b->len) {
169 b->data[--(b->len)] = '\0';
170 }
171}