kunit: string-stream: Add option to make all lines end with newline
authorRichard Fitzgerald <rf@opensource.cirrus.com>
Mon, 28 Aug 2023 10:41:04 +0000 (11:41 +0100)
committerShuah Khan <skhan@linuxfoundation.org>
Mon, 18 Sep 2023 16:45:16 +0000 (10:45 -0600)
Add an optional feature to string_stream that will append a newline to
any added string that does not already end with a newline. The purpose
of this is so that string_stream can be used to collect log lines.

This is enabled/disabled by calling string_stream_set_append_newlines().

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
lib/kunit/string-stream.c
lib/kunit/string-stream.h

index ed24d86af9f5e3b4eece9ee44f3e1d5e78355e4f..1dcf6513b692fc5424afe0b9d929d7729e6e15b3 100644 (file)
@@ -44,32 +44,46 @@ int string_stream_vadd(struct string_stream *stream,
                       va_list args)
 {
        struct string_stream_fragment *frag_container;
-       int len;
+       int buf_len, result_len;
        va_list args_for_counting;
 
        /* Make a copy because `vsnprintf` could change it */
        va_copy(args_for_counting, args);
 
        /* Evaluate length of formatted string */
-       len = vsnprintf(NULL, 0, fmt, args_for_counting);
+       buf_len = vsnprintf(NULL, 0, fmt, args_for_counting);
 
        va_end(args_for_counting);
 
-       if (len == 0)
+       if (buf_len == 0)
                return 0;
 
+       /* Reserve one extra for possible appended newline. */
+       if (stream->append_newlines)
+               buf_len++;
+
        /* Need space for null byte. */
-       len++;
+       buf_len++;
 
        frag_container = alloc_string_stream_fragment(stream->test,
-                                                     len,
+                                                     buf_len,
                                                      stream->gfp);
        if (IS_ERR(frag_container))
                return PTR_ERR(frag_container);
 
-       len = vsnprintf(frag_container->fragment, len, fmt, args);
+       if (stream->append_newlines) {
+               /* Don't include reserved newline byte in writeable length. */
+               result_len = vsnprintf(frag_container->fragment, buf_len - 1, fmt, args);
+
+               /* Append newline if necessary. */
+               if (frag_container->fragment[result_len - 1] != '\n')
+                       result_len = strlcat(frag_container->fragment, "\n", buf_len);
+       } else {
+               result_len = vsnprintf(frag_container->fragment, buf_len, fmt, args);
+       }
+
        spin_lock(&stream->lock);
-       stream->length += len;
+       stream->length += result_len;
        list_add_tail(&frag_container->node, &stream->fragments);
        spin_unlock(&stream->lock);
 
index b669f9a75a9489237ecd463b9ec356c0eda82d26..048930bf97f05bb48d933940c8c87f1be2a208e7 100644 (file)
@@ -25,6 +25,7 @@ struct string_stream {
        spinlock_t lock;
        struct kunit *test;
        gfp_t gfp;
+       bool append_newlines;
 };
 
 struct kunit;
@@ -47,4 +48,10 @@ bool string_stream_is_empty(struct string_stream *stream);
 
 void string_stream_destroy(struct string_stream *stream);
 
+static inline void string_stream_set_append_newlines(struct string_stream *stream,
+                                                    bool append_newlines)
+{
+       stream->append_newlines = append_newlines;
+}
+
 #endif /* _KUNIT_STRING_STREAM_H */