]> sigrok.org Git - libsigrok.git/commitdiff
log: rephrase default sr_logv() routine, strip CR and LF
authorGerhard Sittig <redacted>
Sun, 19 Mar 2023 14:52:53 +0000 (15:52 +0100)
committerGerhard Sittig <redacted>
Sun, 19 Mar 2023 21:40:07 +0000 (22:40 +0100)
Unobfuscate how the unconditional prefix and the conditional timestamp
will prefix the caller's message. Separate the result check for emission
of the prefix/timestamp from the check for successful construction of
the caller's message text. Release the dynamic buffer in the error path.
Use pointers and character variables in the copy loop for readability.

Strip LF as well as CR from the resulting log output text. The previous
implementation exclusively stripped LF. Escaping non-printables is not
attempted in this version.

src/log.c

index 701df645e76cf296dfe7c760368704668575a2d5..669d442bb9c411cf2722c22bc836ac5fdf2f605f 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -184,16 +184,24 @@ SR_API int sr_log_callback_get(sr_log_callback *cb, void **cb_data)
 
 static int sr_logv(void *cb_data, int loglevel, const char *format, va_list args)
 {
+       int ret;
        uint64_t elapsed_us, minutes;
        unsigned int rest_us, seconds, microseconds;
-       char *raw_output, *output;
-       int raw_len, raw_idx, idx, ret;
+       char *raw_output, *output, c;
+       ssize_t print_len;
+       size_t raw_len;
+       const char *raw_ptr;
+       char *out_ptr;
 
        /* This specific log callback doesn't need the void pointer data. */
        (void)cb_data;
 
        (void)loglevel;
 
+       /* Prefix with 'sr:'. Optionally prefix with timestamp. */
+       ret = fputs("sr: ", stderr);
+       if (ret < 0)
+               return SR_ERR;
        if (cur_loglevel >= LOGLEVEL_TIMESTAMP) {
                elapsed_us = g_get_monotonic_time() - sr_log_start_time;
 
@@ -202,30 +210,41 @@ static int sr_logv(void *cb_data, int loglevel, const char *format, va_list args
                seconds = rest_us / G_TIME_SPAN_SECOND;
                microseconds = rest_us % G_TIME_SPAN_SECOND;
 
-               ret = g_fprintf(stderr, "sr: [%.2" PRIu64 ":%.2u.%.6u] ",
+               ret = g_fprintf(stderr, "[%.2" PRIu64 ":%.2u.%.6u] ",
                                minutes, seconds, microseconds);
-       } else {
-               ret = fputs("sr: ", stderr);
+               if (ret < 0)
+                       return SR_ERR;
        }
 
-       if (ret < 0 || (raw_len = g_vasprintf(&raw_output, format, args)) < 0)
+       /* Print the caller's message into a local buffer. */
+       raw_output = NULL;
+       print_len = g_vasprintf(&raw_output, format, args);
+       if (print_len < 0) {
+               g_free(raw_output);
                return SR_ERR;
+       }
+       raw_len = (size_t)print_len;
 
-       output = g_malloc0(raw_len + 1);
-
-       /* Copy the string without any unwanted newlines. */
-       raw_idx = idx = 0;
-       while (raw_idx < raw_len) {
-               if (raw_output[raw_idx] != '\n') {
-                       output[idx] = raw_output[raw_idx];
-                       idx++;
-               }
-               raw_idx++;
+       /* Copy the string. Strip unwanted line breaks. */
+       output = g_malloc(raw_len + 1);
+       if (!output) {
+               g_free(raw_output);
+               return SR_ERR;
+       }
+       out_ptr = output;
+       raw_ptr = raw_output;
+       while (*raw_ptr) {
+               c = *raw_ptr++;
+               if (c == '\r' || c == '\n')
+                       continue;
+               *out_ptr++ = c;
        }
+       *out_ptr = '\0';
+       g_free(raw_output);
 
+       /* Print the trimmed output text. */
        g_fprintf(stderr, "%s\n", output);
        fflush(stderr);
-       g_free(raw_output);
        g_free(output);
 
        return SR_OK;