docs/Writerside/topics/printf.h.md

changeset 1210
2ad0cf0f314b
parent 1172
1a6aa0301226
equal deleted inserted replaced
1209:4a72c47226f4 1210:2ad0cf0f314b
4 directly to an arbitrary stream or [buffer](buffer.h.md), or to memory allocated by an [allocator](allocator.h.md). 4 directly to an arbitrary stream or [buffer](buffer.h.md), or to memory allocated by an [allocator](allocator.h.md).
5 5
6 With the help of these convenience functions, you do not need the libc `snprintf` to print your string to a temporary buffer anymore, 6 With the help of these convenience functions, you do not need the libc `snprintf` to print your string to a temporary buffer anymore,
7 plus you do not need to worry about too small buffer sizes, because the functions will automatically allocate enough memory to contain the entire formatted string. 7 plus you do not need to worry about too small buffer sizes, because the functions will automatically allocate enough memory to contain the entire formatted string.
8 8
9 > Although UCX usually uses `size_t` for sizes, the return type of all `printf`-like functions
10 > (except for the `cx_asprintf()` family of functions) is `int`, consistent with the stdio `printf` return type.
11 {style="note"}
12
9 ## Print to Streams and Buffers 13 ## Print to Streams and Buffers
10 14
11 ```C 15 ```C
12 #include <cx/printf.h> 16 #include <cx/printf.h>
13 17
14 int cx_fprintf(void *stream, cx_write_func wfc, 18 int cx_fprintf(void *stream, cx_write_func wfc,
15 const char *fmt, ...); 19 const char *fmt, ...);
16 20
17 int cx_vfprintf(void *stream, cx_write_func wfc, 21 int cx_vfprintf(void *stream, cx_write_func wfc,
18 const char *fmt, va_list ap); 22 const char *fmt, va_list ap);
19 23
20 int cx_bprintf(CxBuffer *buf, const char *fmt, ...); 24 int cx_bprintf(CxBuffer *buf, const char *fmt, ...);
21 ``` 25 ```
22 26
23 > TODO: document 27 The `cx_fprintf()` function uses the stdio `snprintf()` to prepare a formatted string
24 {style="warning"} 28 which is then written to the `stream` using the write function `wfc`.
29 The return value is the number of bytes written or a value less than zero when an error occurred.
30 If the resulting string is short enough, no additional memory is allocated on the heap.
31 See the Section about [](#small-buffer-optimization) for more details.
25 32
26 The `cx_vfprintf()` function is equivalent to `cx_fprintf()`, 33 The `cx_vfprintf()` function is equivalent to `cx_fprintf()`,
27 except that instead of being called with a variable number of arguments, 34 except that instead of being called with a variable number of arguments,
28 they are called with an argument list as defined by `<stdarg.h>`. 35 it is called with an argument list as defined by `<stdarg.h>`.
36
37 The `cx_bprintf()` function is implemented as macro for `cx_fprintf()` with the
38 `CxBuffer` as `stream` and the `cxBufferWriteFunc` as write function.
29 39
30 ## Print to Freshly Allocated Memory 40 ## Print to Freshly Allocated Memory
31 41
32 ```C 42 ```C
33 #include <cx/printf.h> 43 #include <cx/printf.h>
34 44
35 cxmutstr cx_asprintf(const char *fmt, ...); 45 cxmutstr cx_asprintf(const char *fmt, ...);
36 46
37 cxmutstr cx_asprintf_a(const CxAllocator *allocator, 47 cxmutstr cx_asprintf_a(const CxAllocator *allocator,
38 const char *fmt, ...); 48 const char *fmt, ...);
39 49
40 cxmutstr cx_vasprintf(const char *fmt, va_list ap); 50 cxmutstr cx_vasprintf(const char *fmt, va_list ap);
41 51
42 cxmutstr cx_vasprintf_a(const CxAllocator *allocator, 52 cxmutstr cx_vasprintf_a(const CxAllocator *allocator,
43 const char *fmt, va_list ap); 53 const char *fmt, va_list ap);
44 ``` 54 ```
45 55
46 > TODO: document 56 The `cx_asprintf()` and `cx_asprintf_a()` functions print the formatted output directly to a freshly allocated
47 {style="warning"} 57 string which is then returned from the function.
58 On platforms (or when using allocators) where allocation can fail,
59 the returned string may be empty and the `ptr` field set to `NULL`.
48 60
49 The `cx_vasprintf()` and `cx_vasprintf_a()` functions are equivalent to `cx_asprintf()` and `cx_asprintf_a()`, 61 The `cx_vasprintf()` and `cx_vasprintf_a()` functions are equivalent to `cx_asprintf()` and `cx_asprintf_a()`,
50 except that instead of being called with a variable number of arguments, 62 except that instead of being called with a variable number of arguments,
51 they are called with an argument list as defined by `<stdarg.h>`. 63 they are called with an argument list as defined by `<stdarg.h>`.
52 64
53 ## Print to Existing Memory 65 ## Print to Existing Memory
54 66
55 ```C 67 ```C
56 #include <cx/printf.h> 68 #include <cx/printf.h>
57 69
58 cx_sprintf 70 int cx_sprintf(char **str, size_t *len,
59 cx_sprintf_a 71 const char *fmt, ...);
60 cx_sprintf_s 72
61 cx_sprintf_sa 73 int cx_sprintf_a(CxAllocator *alloc, char **str, size_t *len,
62 cx_vsprintf 74 const char *fmt, ...);
63 cx_vsprintf_a 75
64 cx_vsprintf_s 76 int cx_sprintf_s(char *buf, size_t *len, char **str,
65 cx_vsprintf_sa 77 const char *fmt, ...);
78
79 int cx_sprintf_sa(CxAllocator *alloc,
80 char *buf, size_t *len, char **str,
81 const char *fmt, ...);
82
83 int cx_vsprintf(char **str, size_t *len,
84 const char *fmt, va_list ap);
85
86 int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t *len,
87 const char *fmt, va_list ap);
88
89 int cx_vsprintf_s(char *buf, size_t *len, char **str,
90 const char *fmt, ...);
91
92 int cx_vsprintf_sa(CxAllocator *alloc,
93 char *buf, size_t *len, char **str,
94 const char *fmt, va_list ap);
66 ``` 95 ```
67 96
68 > TODO: document 97 The `cx_sprintf()` and `cx_sprintf_a()` functions take a pointer `str` to a pointer to a pre-allocated buffer,
69 {style="warning"} 98 as well as a pointer `len` to `*str`'s length.
99 If the formatted output would not fit into this buffer, it is reallocated
100 and the new pointer to the buffer and the new length are written back to the variables pointed to by `str` and `len`.
101
102 The `cx_sprintf_s()` and `cx_sprintf_sa()` functions differ from the previous function in that they take
103 the pointer to the pre-allocated buffer in the `buf` argument and not in the `str` argument
104 (which in this case is only used for storing the resulting pointer), and _always_ allocate an entirely new buffer
105 when the length is insufficient.
106 This is particularly useful when you want to print the formatted string to a buffer allocated on the stack, but also
107 want the option to switch to heap-allocated memory when necessary.
108
109 In other words: when the formatted output fits into the buffer pointed to by `buf`, `buf` will be written to `*str`.
110 Otherwise, the pointer to the freshly allocated buffer is written to `*str`.
111
112 > When using `cx_sprintf()` or `cx_sprintf_a()` you should always make sure that the string pointed to by `*str`
113 > was allocated by a matching allocator.
114 > This restriction does not apply for `cx_sprintf_s()` or `cx_sprintf_sa()` which would allocate a fresh buffer when needed.
70 115
71 The `cx_vsprintf()`, `cx_vsprintf_a()`, `cx_vsprintf_s()`, and `cx_vsprintf_sa()` functions are equivalent 116 The `cx_vsprintf()`, `cx_vsprintf_a()`, `cx_vsprintf_s()`, and `cx_vsprintf_sa()` functions are equivalent
72 to `cx_sprintf()`, `cx_sprintf_a()`, `cx_sprintf_s()`, and `cx_sprintf_sa()`, 117 to `cx_sprintf()`, `cx_sprintf_a()`, `cx_sprintf_s()`, and `cx_sprintf_sa()`,
73 except that instead of being called with a variable number of arguments, 118 except that instead of being called with a variable number of arguments,
74 they are called with an argument list as defined by `<stdarg.h>`. 119 they are called with an argument list as defined by `<stdarg.h>`.

mercurial