chiark / gitweb /
Makefile for manual page installation. Subtle and complicated.
[mLib] / man / dstr.3
CommitLineData
b6b9d458 1.\" -*-nroff-*-
2.de VS
3.sp 1
4.RS 5
5.nf
6.ft B
7..
8.de VE
9.ft R
10.fi
11.RE
12.sp 1
13..
08da152e 14.de hP
b6b9d458 15.IP
16.ft B
17\h'-\w'\\$1\ 'u'\\$1\ \c
18.ft P
19..
20.ie t .ds o \(bu
21.el .ds o o
08da152e 22.TH dstr 3 "8 May 1999" "mLib"
b6b9d458 23dstr \- a simple dynamic string type
08da152e 24.\" @dstr_create
25.\" @dstr_destroy
26.\" @dstr_reset
27.\" @dstr_ensure
28.\" @dstr_tidy
29.\"
30.\" @dstr_putc
31.\" @dstr_putz
32.\" @dstr_puts
33.\" @dstr_putf
34.\" @dstr_putd
35.\" @dstr_putm
36.\" @dstr_putline
37.\" @dstr_write
38.\"
39.\" @DCREATE
40.\" @DDESTROY
41.\" @DRESET
42.\" @DENSURE
43.\" @DPUTC
44.\" @DPUTZ
45.\" @DPUTS
46.\" @DPUTD
47.\" @DPUTM
48.\" @DWRITE
49.\"
b6b9d458 50.SH SYNOPSIS
51.nf
52.B "#include <mLib/dstr.h>"
53
54.BI "void dstr_create(dstr *" d );
55.BI "void dstr_destroy(dstr *" d );
56.BI "void dstr_reset(dstr *" d );
57
58.BI "void dstr_ensure(dstr *" d ", size_t " sz );
59.BI "void dstr_tidy(dstr *" d );
60
61.BI "void dstr_putc(dstr *" d ", char " ch );
62.BI "void dstr_putz(dstr *" d );
63.BI "void dstr_puts(dstr *" d ", const char *" s );
64.BI "int dstr_vputf(dstr *" d ", va_list " ap );
65.BI "int dstr_putf(dstr *" d ", ...);
66.BI "void dstr_putd(dstr *" d ", const dstr *" p );
67.BI "void dstr_putm(dstr *" d ", const void *" p ", size_t " sz );
68.BI "int dstr_putline(dstr *" d ", FILE *" fp );
69.BI "size_t dstr_write(const dstr *" d ", FILE *" fp );
70
71.BI "void DCREATE(dstr *" d );
72.BI "void DDESTROY(dstr *" d );
73.BI "void DRESET(dstr *" d );
74.BI "void DENSURE(dstr *" d ", size_t " sz );
08da152e 75.BI "void DPUTC(dstr *" c ", char " ch );
b6b9d458 76.BI "void DPUTZ(dstr *" d );
77.BI "void DPUTS(dstr *" d ", const char *" s );
78.BI "void DPUTD(dstr *" d ", const dstr *" p );
79.BI "void DPUTM(dstr *" d ", const void *" p ", size_t " sz );
80.BI "size_t DWRITE(const dstr *" d ", FILE *" fp );
81.fi
82.SH SUMMARY
83The header
84.B dstr.h
85declares a type for representing dynamically extending strings, and a
86small collection of useful operations on them. None of the operations
87returns a failure result on an out-of-memory condition; instead, the
88exception
89.B EXC_NOMEM
90is raised.
91.PP
92Many of the functions which act on dynamic strings have macro
93equivalents. These equivalent macros may evaluate their arguments
94multiple times.
95.SH "UNDERLYING TYPE"
96A
97.B dstr
98object is a small structure with the following members:
99.VS
100typedef struct dstr {
101 char *buf; /* Pointer to string buffer */
102 size_t sz; /* Size of the buffer */
103 size_t len; /* Length of the string */
104} dstr;
105.VE
106The
107.B buf
108member points to the actual character data in the string. The data may
109or may not be null terminated, depending on what operations have
110recently been performed on it. None of the
111.B dstr
112functions depend on the string being null-terminated; indeed, all of
113them work fine on strings containing arbitrary binary data. You can
114force null-termination by calling the
115.B dstr_putz
116function, or the
117.B DPUTZ
118macro.
119.PP
120The
121.B sz
122member describes the current size of the buffer. This reflects the
123maximum possible length of string that can be represented in
124.B buf
125without allocating a new buffer.
126.PP
127The
128.B len
129member describes the current length of the string. It is the number of
130bytes in the string which are actually interesting. The length does
131.I not
132include a null-terminating byte, if there is one.
133.PP
134The following invariants are maintained by
135.B dstr
136and must hold when any function is called:
08da152e 137.hP \*o
b6b9d458 138If
139.B sz
140is nonzero, then
141.B buf
142points to a block of memory of length
143.BR sz .
144If
145.B sz
146is zero, then
147.B buf
148is a null pointer.
08da152e 149.hP \*o
b6b9d458 150At all times,
151.BI sz " >= " len\fR.
152.PP
153Note that there is no equaivalent of the standard C distinction between
154the empty string (a pointer to an array of characters whose first
155element is zero) and the nonexistant string (a null pointer). Any
156.B dstr
157whose
158.B len
159is zero is an empty string.
160.SH "CREATION AND DESTRUCTION"
161The caller is responsible for allocating the
162.B dstr
163structure. It can be initialized in any of the following ways:
08da152e 164.hP \*o
b6b9d458 165Using the macro
166.B DSTR_INIT
167as an initializer in the declaration of the object.
08da152e 168.hP \*o
b6b9d458 169Passing its address to the
170.B dstr_create
171function.
08da152e 172.hP \*o
b6b9d458 173Passing its address to the (equivalent)
174.B DCREATE
175macro.
176.PP
177The initial value of a
178.B dstr
179is the empty string.
180.PP
181The additional storage space for a string's contents may be reclaimed by
182passing it to the
183.B dstr_destroy
184function, or the
185.B DDESTROY
186macro. After destruction, a string's value is reset to the empty
187string:
188.I "it's still a valid"
189.BR dstr .
190However, once a string has been destroyed, it's safe to deallocate the
191underlying
192.B dstr
193object.
194.PP
195The
196.B dstr_reset
197function empties a string
198.I without
199deallocating any memory. Therefore appending more characters is quick,
200beause the old buffer is still there and doesn't need to be allocated.
201Calling
202.VS
203dstr_reset(d);
204.VE
205is equivalent to directly assinging
206.VS
207d->len = 0;
208.VE
209There's also a macro
210.B DRESET
211which does the same job as the
212.B dstr_reset
213function.
214.SH "EXTENDING A STRING"
215All memory allocation for strings is done by the function
216.BR dstr_ensure .
217Given a pointer
218.I d
219to a
220.B dstr
221and a size
222.IR sz ,
223the function ensures that there are at least
224.I sz
225unused bytes in the string's buffer. The current algorithm for
226extending the buffer is fairly unsophisticated, but seems to work
227relatively well \- see the source if you really want to know what it's
228doing.
229.PP
230Extending a string never returns a failure result. Instead, if there
231isn't enough memory for a longer string, the exception
232.B EXC_NOMEM
233is raised. See
08da152e 234.BR exc (3)
b6b9d458 235for more information about
236.BR mLib 's
237exception handling system.
238.PP
239Note that if an ensure operation needs to reallocate a string buffer,
240any pointers you've taken into the string become invalid.
241.PP
242There's a macro
243.B DENSURE
244which does a quick inline check to see whether there's enough space in
245a string's buffer. This saves a procedure call when no reallocation
246needs to be done. The
247.B DENSURE
248macro is called in the same way as the
249.B dstr_ensure
250function.
251.PP
252The function
253.B dstr_tidy
254`trims' a string's buffer so that it's just large enough for the string
255contents and a null terminating byte. This might raise an exception due
256to lack of memory. (There are two possible ways this might happen.
257Firstly, the underlying allocator might just be braindamaged enough to
258fail on reducing a block's size. Secondly, tidying an empty string with no
259buffer allocated for it causes allocation of a buffer large enough for
260the terminating null byte.)
261.SH "CONTRIBUTING DATA TO A STRING"
262There are a collection of functions which add data to a string. All of
263these functions add their new data to the
264.I end
265of the string. This is good, because programs usually build strings
266left-to-right. If you want to do something more clever, that's up to
267you.
268.PP
269Several of these functions have equivalent macros which do the main work
270inline. (There still might need to be a function call if the buffer
271needs to be extended.)
272.PP
273Any of these functions might extend the string, causing pointers into
274the string buffer to be invalidated. If you don't want that to happen,
275pre-ensure enough space before you start.
276.PP
277The simplest function is
278.B dstr_putc
279which appends a single character
280.I ch
281to the end of the string. It has a macro equivalent called
282.BR DPUTC .
283.PP
284The function
285.B dstr_putz
286places a zero byte at the end of the string. It does
287.I not
288affect the string's length, so any other data added to the string will
289overwrite the null terminator. This is useful if you want to pass your
290string to one of the standard C library string-handling functions. The
291macro
292.B DPUTZ
293does the same thing.
294.PP
295The function
296.B dstr_puts
297writes a C-style null-terminated string to the end of a dynamic string.
298A terminating zero byte is also written, as if
299.B dstr_putz
300were called. The macro
301.B DPUTS
302does the same job.
303.PP
304The function
305.B dstr_putf
306works similarly to the standard
307.BR sprintf (3)
308function. It accepts a
309.BR print (3)-style
310format string and an arbitrary number of arguments to format and writes
311the resulting text to the end of a dynamic string, returning the number
312of characters so written. A terminating zero byte is also appended.
313The formatting is intended to be convenient and safe rather than
314efficient, so don't expect blistering performance. Similarly, there may
315be differences between the formatting done by
316.B dstr_putf
317and
318.BR sprintf (3)
319because the former has to do most of its work itself. In particular,
320.B dstr_putf
321doesn't (and probably never will) understand the
322.RB ` n$ '
323positional paramter notation accepted by many Unix C libraries. There
324is no macro equivalent of
325.BR dstr_putf .
326.PP
327The function
328.B dstr_vputf
329provides access to the `guts' of
330.BR dstr_putf :
331given a format string and a
332.B va_list
333pointer, it will format the arguments according to the format string,
334just as
335.B dstr_putf
336does.
337.PP
338The function
339.B dstr_putd
340appends the contents of one dynamic string to another. A null
341terminator is also appended. The macro
342.B DPUTD
343does the same thing.
344.PP
345The function
346.B dstr_putm
347puts an arbitrary block of memory, addressed by
348.IR p ,
349with length
350.I sz
351bytes, at the end of a dynamic string. No terminating null is appended:
352it's assumed that if you're playing with arbitrary chunks of memory then
353you're probably not going to be using the resulting data as a normal
354text string. The macro
355.B DPUTM
356works the same way.
357.PP
358The function
359.B dstr_putline
360reads a line from an input stream
361.I fp
362and appends it to a string. If an error occurs, or end-of-file is
363encountered, before any characters have been read, then
364.B dstr_putline
365returns the value
366.BR EOF.
367Otherwise, it reads until it encounters a newline character, an error,
368or end-of-file, and returns the number of characters read. If reading
369was terminated by a newline character, the newline character is
370.I not
371inserted in the buffer. A terminating null is appended, as by
372.BR dstr_putz .
373.SH "OTHER FUNCTIONS"
374The
375.B dstr_write
376function writes a string to an output stream
377.IR fp .
378It returns the number of characters written, or
379.B 0
380if an error occurred before the first write. No newline character is
381written to the stream, unless the string actually contains one already.
382The macro
383.B DWRITE
384is equivalent.
385.SH "SECURITY CONSIDERATIONS"
386The implemenetation of the
387.B dstr
388functions is designed to do string handling in security-critical
389programs. However, there may be bugs in the code somewhere. In
390particular, the
391.B dstr_putf
392functions is quite complicated, and could do with some checking by
393independent people who know what they're doing.
08da152e 394.SH "SEE ALSO"
395.BR exc (3),
396.BR mLib (3).
b6b9d458 397.SH AUTHOR
398Mark Wooding, <mdw@nsict.org>