Skip to content

Commit 87c1e2a

Browse files
UCS/LOG: Improvements to ucs_log_print_multi_line
1 parent 773218e commit 87c1e2a

File tree

1 file changed

+46
-58
lines changed

1 file changed

+46
-58
lines changed

src/ucs/debug/log.c

Lines changed: 46 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -282,90 +282,78 @@ ucs_log_print_single_line(const char *short_file, int line,
282282
}
283283
}
284284

285-
static size_t
286-
ucs_log_calc_expected_length(ucs_string_buffer_t *prefix, const char *message)
287-
{
288-
size_t prefix_length = ucs_string_buffer_length(prefix);
289-
size_t line_count = 1;
290-
const char *ptr = message;
291-
292-
while (*ptr != '\0') {
293-
if (*ptr == '\n') {
294-
line_count++;
295-
}
296-
ptr++;
297-
}
298-
299-
return line_count * prefix_length /* total prefixes length */
300-
+ (ptr - message) /* total message length (including newlines) */
301-
+ 1; /* final newline */
302-
}
303-
304285
static void
305286
ucs_log_print_multi_line(const char *short_file, int line,
306287
ucs_log_level_t level,
307288
const ucs_log_component_config_t *comp_conf,
308289
const struct timeval *tv, const char *message,
309290
const char *first_line_end)
310291
{
311-
UCS_STRING_BUFFER_ONSTACK(prefix, 128);
312-
const char *line_start = message;
313-
const char *line_end = first_line_end;
314-
const char *prefix_cstr;
315-
char *strb_buffer;
316-
ucs_string_buffer_t strb;
317-
size_t strb_buffer_capacity;
292+
size_t output_len = 0;
293+
const char *line_start = message;
294+
const char *line_end = first_line_end;
295+
char prefix[256];
296+
char output[2048];
297+
int ret;
318298

319299
/* Format the log prefix once */
320300
if (RUNNING_ON_VALGRIND || !ucs_log_initialized) {
321-
ucs_string_buffer_appendf(&prefix, UCS_LOG_SHORT_FMT,
322-
UCS_LOG_SHORT_ARG(short_file, line, level,
323-
comp_conf, tv));
301+
ret = snprintf(prefix, sizeof(prefix), UCS_LOG_SHORT_FMT,
302+
UCS_LOG_SHORT_ARG(short_file, line, level, comp_conf,
303+
tv));
324304
} else {
325-
ucs_string_buffer_appendf(&prefix, UCS_LOG_FMT,
326-
UCS_LOG_ARG(short_file, line, level,
327-
comp_conf, tv));
305+
ret = snprintf(prefix, sizeof(prefix), UCS_LOG_FMT,
306+
UCS_LOG_ARG(short_file, line, level, comp_conf, tv));
328307
}
329-
ucs_assert(ucs_array_available_length(&prefix) > 1);
330-
prefix_cstr = ucs_string_buffer_cstr(&prefix);
331-
332-
/* Allocate a buffer with the expected length of the log message,
333-
* it may be allocated on the heap depending on the maximal allocation
334-
size on the stack */
335-
strb_buffer_capacity =
336-
ucs_log_calc_expected_length(&prefix, message) /* string length */
337-
+ 1 /* null terminator */
338-
+ 1; /* extra space to validate that the buffer is not truncated */
339-
340-
strb_buffer = ucs_alloc_on_stack(strb_buffer_capacity,
341-
"multi_line_strb_buffer");
342-
ucs_string_buffer_init_fixed(&strb, strb_buffer, strb_buffer_capacity);
308+
ucs_assert((ret >= 0) && ((size_t)ret < sizeof(prefix)));
343309

344310
/* Append line by line */
345311
ucs_assert(line_end != NULL);
346312
do {
347-
ucs_string_buffer_appendf(&strb, "%s%.*s\n", prefix_cstr,
348-
(int)(line_end - line_start), line_start);
313+
size_t remaining_space = sizeof(output) - output_len;
314+
315+
ret = snprintf(output + output_len, remaining_space, "%s%.*s\n", prefix,
316+
(int)(line_end - line_start), line_start);
317+
ucs_assert(ret >= 0);
318+
319+
if ((size_t)ret >= remaining_space) {
320+
output_len = sizeof(output) - 1;
321+
output[sizeof(output) - 1] = '\0';
322+
output[sizeof(output) - 2] = '\n';
323+
output[sizeof(output) - 3] = '>'; /* Truncated indicator */
324+
output[sizeof(output) - 4] = ' ';
325+
break;
326+
}
327+
328+
output_len += ret;
329+
330+
if (*line_end == '\0') {
331+
break; /* This was the last line */
332+
}
333+
349334
line_start = line_end + 1;
350-
} while ((line_end = strchr(line_start, '\n')) != NULL);
335+
line_end = strchr(line_start, '\n');
336+
if (line_end == NULL) {
337+
/* The last line is next, set to the end of the message */
338+
line_end = line_start + strlen(line_start);
339+
}
340+
} while (1);
351341

352-
/* Append last line */
353-
ucs_string_buffer_appendf(&strb, "%s%s\n", prefix_cstr, line_start);
354-
ucs_assert(ucs_array_available_length(&strb) == 2);
342+
ucs_assert(output_len > 0);
355343

356344
/* Print the entire buffer in a single operation to avoid interleaving */
357345
if (RUNNING_ON_VALGRIND) {
358-
VALGRIND_PRINTF("%s", strb_buffer);
346+
VALGRIND_PRINTF("%s", output);
359347
} else if (ucs_log_initialized) {
360348
if (ucs_log_file_close) { /* non-stdout/stderr */
361-
ucs_log_handle_file_max_size(ucs_string_buffer_length(&strb));
349+
ucs_log_handle_file_max_size(output_len);
362350
}
363-
fputs(strb_buffer, ucs_log_file);
351+
fputs(output, ucs_log_file);
352+
fflush(ucs_log_file);
364353
} else {
365-
fputs(strb_buffer, stdout);
354+
fputs(output, stdout);
355+
fflush(stdout);
366356
}
367-
368-
ucs_free_on_stack(strb_buffer, strb_buffer_capacity);
369357
}
370358

371359
static void ucs_log_print(const char *file, int line, ucs_log_level_t level,

0 commit comments

Comments
 (0)