]> git.sur5r.net Git - cc65/blob - src/common/strbuf.h
Fixed LinuxDoc Tools issues in some verbatim blocks in the Atari document.
[cc65] / src / common / strbuf.h
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 strbuf.h                                  */
4 /*                                                                           */
5 /*                       Variable sized string buffers                       */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2001-2009, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #ifndef STRBUF_H
37 #define STRBUF_H
38
39
40
41 #include <stdarg.h>
42 #include <string.h>
43
44 /* common */
45 #include "attrib.h"
46 #include "check.h"
47 #include "inline.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 typedef struct StrBuf StrBuf;
58 struct StrBuf {
59     char*       Buf;                    /* Pointer to buffer */
60     unsigned    Len;                    /* Length of the string */
61     unsigned    Index;                  /* Used for reading (Get and friends) */
62     unsigned    Allocated;              /* Size of allocated memory */
63 };
64
65 /* An empty string buf */
66 extern const StrBuf EmptyStrBuf;
67
68 /* Initializer for static string bufs */
69 #define STATIC_STRBUF_INITIALIZER       { 0, 0, 0, 0 }
70
71 /* Initializer for auto string bufs */
72 #define AUTO_STRBUF_INITIALIZER         { 0, 0, 0, 0 }
73
74 /* Initialize with a string literal (beware: evaluates str twice!) */
75 #define LIT_STRBUF_INITIALIZER(str)     { (char*)str, sizeof(str)-1, 0, 0 }
76
77
78
79 /*****************************************************************************/
80 /*                                   Code                                    */
81 /*****************************************************************************/
82
83
84
85 #if defined(HAVE_INLINE)
86 INLINE StrBuf* SB_Init (StrBuf* B)
87 /* Initialize a string buffer */
88 {
89     *B = EmptyStrBuf;
90     return B;
91 }
92 #else
93 StrBuf* SB_Init (StrBuf* B);
94 #endif
95
96 StrBuf* SB_InitFromString (StrBuf* B, const char* S);
97 /* Initialize a string buffer from a literal string. Beware: The buffer won't
98 ** store a copy but a pointer to the actual string. A buffer initialized with
99 ** this routine may be "forgotten" without calling SB_Done, since no memory
100 ** has been allocated.
101 */
102
103 void SB_Done (StrBuf* B);
104 /* Free the data of a string buffer (but not the struct itself) */
105
106 StrBuf* NewStrBuf (void);
107 /* Allocate, initialize and return a new StrBuf */
108
109 void FreeStrBuf (StrBuf* B);
110 /* Free a string buffer */
111
112 void SB_Realloc (StrBuf* B, unsigned NewSize);
113 /* Reallocate the string buffer space, make sure at least NewSize bytes are
114 ** available.
115 */
116
117 #if defined(HAVE_INLINE)
118 INLINE unsigned SB_GetLen (const StrBuf* B)
119 /* Return the length of the buffer contents */
120 {
121     return B->Len;
122 }
123 #else
124 #  define SB_GetLen(B)  (B)->Len
125 #endif
126
127 #if defined(HAVE_INLINE)
128 INLINE unsigned SB_GetIndex (const StrBuf* B)
129 /* Return the user index of the string buffer */
130 {
131     return B->Index;
132 }
133 #else
134 #  define SB_GetIndex(B)  (B)->Index
135 #endif
136
137 #if defined(HAVE_INLINE)
138 INLINE void SB_SetIndex (StrBuf* B, unsigned Index)
139 /* Set the user index of the string buffer */
140 {
141     B->Index = Index;
142 }
143 #else
144 #  define SB_SetIndex(B, Idx) ((B)->Index = (Idx))
145 #endif
146
147 #if defined(HAVE_INLINE)
148 INLINE const char* SB_GetConstBuf (const StrBuf* B)
149 /* Return a buffer pointer */
150 {
151     return B->Buf;
152 }
153 #else
154 #  define SB_GetConstBuf(B)     (B)->Buf
155 #endif
156
157 #if defined(HAVE_INLINE)
158 INLINE char* SB_GetBuf (StrBuf* B)
159 /* Return a buffer pointer */
160 {
161     return B->Buf;
162 }
163 #else
164 #  define SB_GetBuf(B)     (B)->Buf
165 #endif
166
167 #if defined(HAVE_INLINE)
168 INLINE char SB_At (const StrBuf* B, unsigned Index)
169 /* Get a character from the buffer */
170 {
171     PRECONDITION (Index < B->Len);
172     return B->Buf[Index];
173 }
174 #else
175 char SB_At (const StrBuf* B, unsigned Index);
176 /* Get a character from the buffer */
177 #endif
178
179 #if defined(HAVE_INLINE)
180 INLINE char SB_AtUnchecked (const StrBuf* B, unsigned Index)
181 /* Get a character from the buffer */
182 {
183     return B->Buf[Index];
184 }
185 #else
186 #  define SB_AtUnchecked(B, Index)      ((B)->Buf[Index])
187 #endif
188
189 #if defined(HAVE_INLINE)
190 INLINE int SB_IsEmpty (const StrBuf* B)
191 /* Return true if the string buffer is empty */
192 {
193     return (B->Len == 0);
194 }
195 #else
196 #  define SB_IsEmpty(B) ((B)->Len == 0)
197 #endif
198
199 #if defined(HAVE_INLINE)
200 INLINE int SB_NotEmpty (const StrBuf* B)
201 /* Return true if the string buffer is not empty */
202 {
203     return (B->Len > 0);
204 }
205 #else
206 #  define SB_NotEmpty(B) ((B)->Len > 0)
207 #endif
208
209 #if defined(HAVE_INLINE)
210 INLINE void SB_Clear (StrBuf* B)
211 /* Clear the string buffer (make it empty) */
212 {
213     B->Len = B->Index = 0;
214 }
215 #else
216 #  define SB_Clear(B)   ((B)->Len = (B)->Index = 0)
217 #endif
218
219 #if defined(HAVE_INLINE)
220 INLINE void SB_Reset (StrBuf* B)
221 /* Reset the string buffer index to zero */
222 {
223     B->Index = 0;
224 }
225 #else
226 #  define SB_Reset(B)   ((B)->Index = 0)
227 #endif
228
229 #if defined(HAVE_INLINE)
230 INLINE char SB_Get (StrBuf* B)
231 /* Return the next character from the string incrementing Index. Returns NUL
232 ** if the end of the string is reached.
233 */
234 {
235     return (B->Index < B->Len)? B->Buf[B->Index++] : '\0';
236 }
237 #else
238 #  define SB_Get(B)     (((B)->Index < (B)->Len)? (B)->Buf[(B)->Index++] : '\0')
239 #endif
240
241 #if defined(HAVE_INLINE)
242 INLINE char SB_Peek (const StrBuf* B)
243 /* Look at the next character from the string without incrementing Index.
244 ** Returns NUL if the end of the string is reached.
245 */
246 {
247     return (B->Index < B->Len)? B->Buf[B->Index] : '\0';
248 }
249 #else
250 #  define SB_Peek(B)     (((B)->Index < (B)->Len)? (B)->Buf[(B)->Index] : '\0')
251 #endif
252
253 #if defined(HAVE_INLINE)
254 INLINE char SB_LookAt (const StrBuf* B, unsigned Index)
255 /* Look at a specific character from the string. Returns NUL if the given
256 ** index is greater than the size of the string.
257 */
258 {
259     return (Index < B->Len)? B->Buf[Index] : '\0';
260 }
261 #else
262 #  define SB_LookAt(B,Index)     (((Index) < (B)->Len)? (B)->Buf[(Index)] : '\0')
263 #endif
264
265 #if defined(HAVE_INLINE)
266 INLINE char SB_LookAtLast (const StrBuf* B)
267 /* Look at the last character from the string. Returns NUL if the string buffer
268 ** is empty.
269 */
270 {
271     return (B->Len > 0)? B->Buf[B->Len-1] : '\0';
272 }
273 #else
274 #  define SB_LookAtLast(B)      (((B)->Len > 0)? (B)->Buf[(B)->Len-1] : '\0')
275 #endif
276
277 #if defined(HAVE_INLINE)
278 INLINE void SB_Skip (StrBuf* B)
279 /* Skip the next character in the string buffer if this is possible. */
280 {
281     if (B->Index < B->Len) {
282         ++B->Index;
283     }
284 }
285 #else
286 #  define SB_Skip(B)     do { if ((B)->Index < (B)->Len) ++(B)->Index; } while (0)
287 #endif
288
289 #if defined(HAVE_INLINE)
290 INLINE void SB_SkipMultiple (StrBuf* B, unsigned Count)
291 /* Skip a number of characters in the string buffer if this is possible. */
292 {
293     if ((B->Index += Count) > B->Len) {
294         B->Index = B->Len;
295     }
296 }
297 #else
298 #  define SB_SkipMultiple(B, Count)     \
299         do { if (((B)->Index += (Count)) > (B)->Len) (B)->Index = (B)->Len; } while (0)
300 #endif
301
302 void SB_Drop (StrBuf* B, unsigned Count);
303 /* Drop characters from the end of the string. */
304
305 void SB_Terminate (StrBuf* B);
306 /* Zero terminate the given string buffer. NOTE: The terminating zero is not
307 ** accounted for in B->Len, if you want that, you have to use AppendChar!
308 */
309
310 void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size);
311 /* Copy Buf to Target, discarding the old contents of Target */
312
313 #if defined(HAVE_INLINE)
314 INLINE void SB_CopyStr (StrBuf* Target, const char* S)
315 /* Copy S to Target, discarding the old contents of Target */
316 {
317     SB_CopyBuf (Target, S, strlen (S));
318 }
319 #else
320 void SB_CopyStr (StrBuf* Target, const char* S);
321 /* Copy S to Target, discarding the old contents of Target */
322 #endif
323
324 #if defined(HAVE_INLINE)
325 INLINE void SB_Copy (StrBuf* Target, const StrBuf* Source)
326 /* Copy Source to Target, discarding the old contents of Target */
327 {
328     SB_CopyBuf (Target, Source->Buf, Source->Len);
329     Target->Index = Source->Index;
330 }
331 #else
332 void SB_Copy (StrBuf* Target, const StrBuf* Source);
333 /* Copy Source to Target, discarding the old contents of Target */
334 #endif
335
336 void SB_AppendChar (StrBuf* B, int C);
337 /* Append a character to a string buffer */
338
339 void SB_AppendBuf (StrBuf* B, const char* S, unsigned Size);
340 /* Append a character buffer to the end of the string buffer */
341
342 #if defined(HAVE_INLINE)
343 INLINE void SB_AppendStr (StrBuf* B, const char* S)
344 /* Append a string to the end of the string buffer */
345 {
346     SB_AppendBuf (B, S, strlen (S));
347 }
348 #else
349 void SB_AppendStr (StrBuf* B, const char* S);
350 /* Append a string to the end of the string buffer */
351 #endif
352
353 #if defined(HAVE_INLINE)
354 INLINE void SB_Append (StrBuf* Target, const StrBuf* Source)
355 /* Append the contents of Source to Target */
356 {
357     SB_AppendBuf (Target, Source->Buf, Source->Len);
358 }
359 #else
360 void SB_Append (StrBuf* Target, const StrBuf* Source);
361 /* Append the contents of Source to Target */
362 #endif
363
364 #if defined(HAVE_INLINE)
365 INLINE void SB_Cut (StrBuf* B, unsigned Len)
366 /* Cut the contents of B at the given length. If the current length of the
367 ** buffer is smaller than Len, nothing will happen.
368 */
369 {
370     if (Len < B->Len) {
371         B->Len = Len;
372     }
373 }
374 #else
375 void SB_Cut (StrBuf* B, unsigned Len);
376 /* Cut the contents of B at the given length. If the current length of the
377 ** buffer is smaller than Len, nothing will happen.
378 */
379 #endif
380
381 void SB_Slice (StrBuf* Target, const StrBuf* Source, unsigned Start, unsigned Len);
382 /* Copy a slice from Source into Target. The current contents of Target are
383 ** destroyed. If Start is greater than the length of Source, or if Len
384 ** characters aren't available, the result will be a buffer with less than Len
385 ** bytes.
386 */
387
388 void SB_Move (StrBuf* Target, StrBuf* Source);
389 /* Move the complete contents of Source to target. This will delete the old
390 ** contents of Target, and Source will be empty after the call.
391 */
392
393 void SB_ToLower (StrBuf* S);
394 /* Convert all characters in S to lower case */
395
396 void SB_ToUpper (StrBuf* S);
397 /* Convert all characters in S to upper case */
398
399 int SB_Compare (const StrBuf* S1, const StrBuf* S2);
400 /* Do a lexical compare of S1 and S2. See strcmp for result codes. */
401
402 int SB_CompareStr (const StrBuf* S1, const char* S2);
403 /* Do a lexical compare of S1 and S2. See strcmp for result codes. */
404
405 void SB_VPrintf (StrBuf* S, const char* Format, va_list ap) attribute ((format (printf, 2, 0)));
406 /* printf function with S as target. The function is safe, which means that
407 ** the current contents of S are discarded, and are allocated again with
408 ** a matching size for the output. The function will call FAIL when problems
409 ** are detected (anything that let xsnprintf return -1).
410 */
411
412 void SB_Printf (StrBuf* S, const char* Format, ...) attribute ((format (printf, 2, 3)));
413 /* vprintf function with S as target. The function is safe, which means that
414 ** the current contents of S are discarded, and are allocated again with
415 ** a matching size for the output. The function will call FAIL when problems
416 ** are detected (anything that let xsnprintf return -1).
417 */
418
419
420
421 /* End of strbuf.h */
422
423 #endif