> Date: 2026-10-22 22:38:12+0200 > From: Alejandro Colomar > [...] > No, it doesn't lose data. My proposal is to have this: > > struct my_seq_buf { > // .buffer points to the start of the buffer > char *buffer; > > /* .p points to the current position. This is the last > * '\0' that has been written to the buffer. On > * truncation, it is a NULL pointer. > */ > char *p; > > /* .end always holds ARRAY_END(buffer). It is a pointer > * one-past-the-last character in the buffer. > */ > char *end; > }; > > This would be initialized as (of course, wrapper in static inline > functions as needed) this: > > char buf[100]; > struct seq_buf b; > > b.buffer = buf; > b.p = buf; > b.end = ARRAY_END(buf); > > Then, you would write to it as: > > b.p = stpecpy(b.p, b.end, "foo"); > b.p = stpecpy(b.p, b.end, "bar"); > ... > b.p = stpecpy(b.p, b.end, "baz"); > if (b.p == NULL) > goto fail; > > Then, at some point, you might want to initialize a new buffer out of > the remainings of it: > > struct seq_buf b2; > > if (b.p == NULL) > goto fail; > b2.start = b.p; We can actually avoid this error by setting up the new buffer to have an empty string if the parent buffer overflowed: b2.start = b.p ?: b.end-1; This is probably related to that empty string that has been showing in seq_buf when the string had overflowed, except that here we don't need to point to a new string, but can reuse the old buffer always. b.end-1 is guaranteed to exist and point to an empty string if b.p==NULL because b.buffer must come from a real array with at least 1 element, and the last element must be a '\0' if the string has overflowed (actually, truncated). Have a lovely day! Alex > b2.p = b.p; > b2.end = b.end; > > See how simple this becomes? (So much that you may doubt the necessity > of the set of APIs at all, but they don't hurt much either.) > > > Cheers, > Alex > > > > > -- Steve > > -- > --