]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add append_prefixed_str()
authorWilly Tarreau <w@1wt.eu>
Wed, 21 Aug 2019 11:17:37 +0000 (13:17 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Aug 2019 12:32:09 +0000 (14:32 +0200)
This is somewhat related to indent_msg() except that this one places a
known prefix at the beginning of each line, allows to replace the EOL
character, and not to insert a prefix on the first line if not desired.
It works with a normal output buffer/chunk so it doesn't need to allocate
anything nor to modify the input string. It is suitable for use in multi-
line backtraces.

include/common/standard.h
src/standard.c

index 0f4b1870e4bc67b07a3f35de6ae1d4a8ca004a5b..cdefc9f5b3ebbbd8538e99762b7d84c852f62bc3 100644 (file)
@@ -1238,6 +1238,7 @@ char *memprintf(char **out, const char *format, ...)
  *   free(err);
  */
 char *indent_msg(char **out, int level);
+int append_prefixed_str(struct buffer *out, const char *in, const char *pfx, char eol, int first);
 
 /* removes environment variable <name> from the environment as found in
  * environ. This is only provided as an alternative for systems without
index 2f205f74832243b13aabe25bb41d56a4ee60646c..717c14a94624d0583c2e33e3eef6384fa887488e 100644 (file)
@@ -3709,6 +3709,41 @@ char *indent_msg(char **out, int level)
        return ret;
 }
 
+/* makes a copy of message <in> into <out>, with each line prefixed with <pfx>
+ * and end of lines replaced with <eol> if not 0. The first line to indent has
+ * to be indicated in <first> (starts at zero), so that it is possible to skip
+ * indenting the first line if it has to be appended after an existing message.
+ * Empty strings are never indented, and NULL strings are considered empty both
+ * for <in> and <pfx>. It returns non-zero if an EOL was appended as the last
+ * character, non-zero otherwise.
+ */
+int append_prefixed_str(struct buffer *out, const char *in, const char *pfx, char eol, int first)
+{
+       int bol, lf;
+       int pfxlen = pfx ? strlen(pfx) : 0;
+
+       if (!in)
+               return 0;
+
+       bol = 1;
+       lf = 0;
+       while (*in) {
+               if (bol && pfxlen) {
+                       if (first > 0)
+                               first--;
+                       else
+                               b_putblk(out, pfx, pfxlen);
+                       bol = 0;
+               }
+
+               lf = (*in == '\n');
+               bol |= lf;
+               b_putchr(out, (lf && eol) ? eol : *in);
+               in++;
+       }
+       return lf;
+}
+
 /* removes environment variable <name> from the environment as found in
  * environ. This is only provided as an alternative for systems without
  * unsetenv() (old Solaris and AIX versions). THIS IS NOT THREAD SAFE.