R
R
random-guy2018-07-21 04:29:55
C++ / C#
random-guy, 2018-07-21 04:29:55

Is it possible/how to get the tail of sprintf output?

TL;DR: Is it possible to get the last n characters of output using any of the sprintf variants without using additional memory?
Details: There is a system with very limited memory. Part of this memory is allocated for the ring buffer, into which characters are output by redefined functions from the printf family. Those. places at the current position of the entry in this ring buffer and advances the current position forward. When the pointer reaches the end of the buffer and the output string is longer than the available space, the string should "break", i.e. the beginning of the string must be at the end of the buffer, and the end of the string must be at the beginning (assuming that the space at the beginning has already been freed), i.e. it should look like this, for example:printf("Hello world\n");Hello world\nchar buf[16] = "orld\n\0\0\0\0Hello w";To cut off the tail of an output line I can use snprintf, but how can I cut off the head of an output line? And, yes, of course, the answer in the style of "retreat n bytes from the beginning of the line and print" is not suitable, because the line will not contain Hello world, but "%s: a[%d] = %d".
I suspect that this cannot be done, but you never know, what if there is a way?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
F
forspamonly2, 2018-07-22
@random-guy

interesting question, a rarity here.
comes to mind two options for organizing the ring buffer transparently for the rest of the stdlib.
first: if this system with limited memory has an MMU, then you can map the same piece of memory to adjacent pages so that after the end of the buffer it starts again. and after each sprintf check for overflow and shift the current position pointer to the first page (take away the buffer size). or just do and if the size is a multiple of a power of two. it would be hardware and actually free in terms of performance, it would work in general with all the functions of stdlib, but it would be troublesome and far from always possible.
second option: you can make your own stream ( man fopencookie). for your purpose, it is enough to write only a record handler, which will actually loop the buffer: copy as much as possible to the end, and the rest to the beginning. and output everything to this stream with fsprifs and other streaming functions. it may even be possible to redirect stdout to this self-made stream, then ordinary printfs will work.

P
Philipp, 2018-07-21
@zoonman

If you have a terminating character, for example 0x00, then you can scan the buffer and, when a transition from 0x00 to something else is detected, start reading in a circle until you hit 0x00 again.
Typically, a ring buffer has a pointer to the current position in the buffer. Since the ring buffer has a fixed size, it can be read backwards starting from the current position until the end character is encountered.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question