MINOR: flags/channel: use flag dumping for channel flags and analysers

The two new functions are chn_show_analysers() and chn_show_flags().
They work on an existing buffer so one was declared in flags.c for this
purpose. File flags.c does not have to know about channel flags anymore.
diff --git a/dev/flags/flags.c b/dev/flags/flags.c
index de7127d..fe72eab 100644
--- a/dev/flags/flags.c
+++ b/dev/flags/flags.c
@@ -30,6 +30,9 @@
 		printf(#n"%s", (f) ? " | " : "");	\
 	} while (0)
 
+/* will be sufficient for even largest flag names */
+static char tmpbuf[4096];
+
 unsigned int get_show_as(const char *word)
 {
 	int w = 0;
@@ -45,97 +48,14 @@
 
 void show_chn_ana(unsigned int f)
 {
-	printf("chn->ana    = ");
-
-	if (!f) {
-		printf("0\n");
-		return;
-	}
-
-	SHOW_FLAG(f, AN_REQ_FLT_START_FE);
-	SHOW_FLAG(f, AN_REQ_INSPECT_FE);
-	SHOW_FLAG(f, AN_REQ_WAIT_HTTP);
-	SHOW_FLAG(f, AN_REQ_HTTP_BODY);
-	SHOW_FLAG(f, AN_REQ_HTTP_PROCESS_FE);
-	SHOW_FLAG(f, AN_REQ_SWITCHING_RULES);
-	SHOW_FLAG(f, AN_REQ_FLT_START_BE);
-	SHOW_FLAG(f, AN_REQ_INSPECT_BE);
-	SHOW_FLAG(f, AN_REQ_HTTP_PROCESS_BE);
-	SHOW_FLAG(f, AN_REQ_HTTP_TARPIT);
-	SHOW_FLAG(f, AN_REQ_SRV_RULES);
-	SHOW_FLAG(f, AN_REQ_HTTP_INNER);
-	SHOW_FLAG(f, AN_REQ_PRST_RDP_COOKIE);
-	SHOW_FLAG(f, AN_REQ_STICKING_RULES);
-	SHOW_FLAG(f, AN_REQ_FLT_HTTP_HDRS);
-	SHOW_FLAG(f, AN_REQ_HTTP_XFER_BODY);
-	SHOW_FLAG(f, AN_REQ_WAIT_CLI);
-	SHOW_FLAG(f, AN_REQ_FLT_XFER_DATA);
-	SHOW_FLAG(f, AN_REQ_FLT_END);
-
-	SHOW_FLAG(f, AN_RES_FLT_START_FE);
-	SHOW_FLAG(f, AN_RES_FLT_START_BE);
-	SHOW_FLAG(f, AN_RES_INSPECT);
-	SHOW_FLAG(f, AN_RES_WAIT_HTTP);
-	SHOW_FLAG(f, AN_RES_STORE_RULES);
-	SHOW_FLAG(f, AN_RES_HTTP_PROCESS_FE);
-	SHOW_FLAG(f, AN_RES_HTTP_PROCESS_BE);
-	SHOW_FLAG(f, AN_RES_FLT_HTTP_HDRS);
-	SHOW_FLAG(f, AN_RES_HTTP_XFER_BODY);
-	SHOW_FLAG(f, AN_RES_WAIT_CLI);
-	SHOW_FLAG(f, AN_RES_FLT_XFER_DATA);
-	SHOW_FLAG(f, AN_RES_FLT_END);
-
-	if (f) {
-		printf("EXTRA(0x%08x)", f);
-	}
-	putchar('\n');
+	chn_show_analysers(tmpbuf, sizeof(tmpbuf), " | ", f);
+	printf("chn->ana    = %s\n", tmpbuf);
 }
 
 void show_chn_flags(unsigned int f)
 {
-	printf("chn->flags  = ");
-
-	if (!f) {
-		printf("0\n");
-		return;
-	}
-
-	SHOW_FLAG(f, CF_ISRESP);
-	SHOW_FLAG(f, CF_EOI);
-	SHOW_FLAG(f, CF_FLT_ANALYZE);
-	SHOW_FLAG(f, CF_WAKE_ONCE);
-	SHOW_FLAG(f, CF_NEVER_WAIT);
-	SHOW_FLAG(f, CF_SEND_DONTWAIT);
-	SHOW_FLAG(f, CF_EXPECT_MORE);
-	SHOW_FLAG(f, CF_DONT_READ);
-	SHOW_FLAG(f, CF_AUTO_CONNECT);
-	SHOW_FLAG(f, CF_READ_DONTWAIT);
-	SHOW_FLAG(f, CF_KERN_SPLICING);
-	SHOW_FLAG(f, CF_READ_ATTACHED);
-	SHOW_FLAG(f, CF_ANA_TIMEOUT);
-	SHOW_FLAG(f, CF_WROTE_DATA);
-	SHOW_FLAG(f, CF_STREAMER_FAST);
-	SHOW_FLAG(f, CF_STREAMER);
-	SHOW_FLAG(f, CF_AUTO_CLOSE);
-	SHOW_FLAG(f, CF_SHUTW_NOW);
-	SHOW_FLAG(f, CF_SHUTW);
-	SHOW_FLAG(f, CF_WAKE_WRITE);
-	SHOW_FLAG(f, CF_WRITE_ERROR);
-	SHOW_FLAG(f, CF_WRITE_TIMEOUT);
-	SHOW_FLAG(f, CF_WRITE_PARTIAL);
-	SHOW_FLAG(f, CF_WRITE_NULL);
-	SHOW_FLAG(f, CF_READ_NOEXP);
-	SHOW_FLAG(f, CF_SHUTR_NOW);
-	SHOW_FLAG(f, CF_SHUTR);
-	SHOW_FLAG(f, CF_READ_ERROR);
-	SHOW_FLAG(f, CF_READ_TIMEOUT);
-	SHOW_FLAG(f, CF_READ_PARTIAL);
-	SHOW_FLAG(f, CF_READ_NULL);
-
-	if (f) {
-		printf("EXTRA(0x%08x)", f);
-	}
-	putchar('\n');
+	chn_show_flags(tmpbuf, sizeof(tmpbuf), " | ", f);
+	printf("chn->flags  = %s\n", tmpbuf);
 }
 
 void show_conn_flags(unsigned int f)
diff --git a/include/haproxy/channel-t.h b/include/haproxy/channel-t.h
index 75c4c96..5cfd54f 100644
--- a/include/haproxy/channel-t.h
+++ b/include/haproxy/channel-t.h
@@ -24,6 +24,7 @@
 
 #include <haproxy/api-t.h>
 #include <haproxy/buf-t.h>
+#include <haproxy/show_flags-t.h>
 
 /* The CF_* macros designate Channel Flags, which may be ORed in the bit field
  * member 'flags' in struct channel. Here we have several types of flags :
@@ -49,6 +50,7 @@
  * bits have the same position in a byte (read being the lower byte and write
  * the second one). All flag names are relative to the channel. For instance,
  * 'write' indicates the direction from the channel to the stream connector.
+ * Please also update the chn_show_flags() function below in case of changes.
  */
 
 #define CF_READ_NULL      0x00000001  /* last read detected on producer side */
@@ -126,6 +128,30 @@
 /* Mask for static flags which cause analysers to be woken up when they change */
 #define CF_MASK_STATIC    (CF_SHUTR|CF_SHUTW|CF_SHUTR_NOW|CF_SHUTW_NOW)
 
+/* This function is used to report flags in debugging tools. Please reflect
+ * below any single-bit flag addition above in the same order via the
+ * __APPEND_FLAG macro. The new end of the buffer is returned.
+ */
+static forceinline char *chn_show_flags(char *buf, size_t len, const char *delim, uint flg)
+{
+#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
+	/* prologue */
+	_(0);
+	/* flags */
+	_(CF_READ_NULL, _(CF_READ_PARTIAL, _(CF_READ_TIMEOUT, _(CF_READ_ERROR,
+	_(CF_SHUTR, _(CF_SHUTR_NOW, _(CF_READ_NOEXP, _(CF_WRITE_NULL,
+	_(CF_WRITE_PARTIAL, _(CF_WRITE_TIMEOUT, _(CF_WRITE_ERROR,
+	_(CF_WAKE_WRITE, _(CF_SHUTW, _(CF_SHUTW_NOW, _(CF_AUTO_CLOSE,
+	_(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA, _(CF_ANA_TIMEOUT,
+	_(CF_READ_ATTACHED, _(CF_KERN_SPLICING, _(CF_READ_DONTWAIT,
+	_(CF_AUTO_CONNECT, _(CF_DONT_READ, _(CF_EXPECT_MORE,
+	_(CF_SEND_DONTWAIT, _(CF_NEVER_WAIT, _(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
+	_(CF_EOI, _(CF_ISRESP)))))))))))))))))))))))))))))));
+	/* epilogue */
+	_(~0U);
+	return buf;
+#undef _
+}
 
 /* Analysers (channel->analysers).
  * Those bits indicate that there are some processing to do on the buffer
@@ -133,6 +159,7 @@
  * analysers could be compared to higher level processors.
  * The field is blanked by channel_init() and only by analysers themselves
  * afterwards.
+ * Please also update the chn_show_analysers() function below in case of changes.
  */
 /* AN_REQ_FLT_START_FE:         0x00000001 */
 #define AN_REQ_INSPECT_FE       0x00000002  /* inspect request contents in the frontend */
@@ -183,6 +210,35 @@
 #define AN_RES_FLT_XFER_DATA    0x10000000
 #define AN_RES_FLT_END          0x20000000
 
+/* This function is used to report flags in debugging tools. Please reflect
+ * below any single-bit flag addition above in the same order via the
+ * __APPEND_FLAG macro. The new end of the buffer is returned.
+ */
+static forceinline char *chn_show_analysers(char *buf, size_t len, const char *delim, uint flg)
+{
+#define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__)
+	/* prologue */
+	_(0);
+	/* request flags */
+	_(AN_REQ_FLT_START_FE, _(AN_REQ_INSPECT_FE, _(AN_REQ_WAIT_HTTP,
+	_(AN_REQ_HTTP_BODY, _(AN_REQ_HTTP_PROCESS_FE, _(AN_REQ_SWITCHING_RULES,
+	_(AN_REQ_FLT_START_BE, _(AN_REQ_INSPECT_BE, _(AN_REQ_HTTP_PROCESS_BE,
+	_(AN_REQ_HTTP_TARPIT, _(AN_REQ_SRV_RULES, _(AN_REQ_HTTP_INNER,
+	_(AN_REQ_PRST_RDP_COOKIE, _(AN_REQ_STICKING_RULES,
+	_(AN_REQ_FLT_HTTP_HDRS, _(AN_REQ_HTTP_XFER_BODY, _(AN_REQ_WAIT_CLI,
+	_(AN_REQ_FLT_XFER_DATA, _(AN_REQ_FLT_END,
+	/* response flags */
+	_(AN_RES_FLT_START_FE, _(AN_RES_FLT_START_BE, _(AN_RES_INSPECT,
+	_(AN_RES_WAIT_HTTP, _(AN_RES_STORE_RULES, _(AN_RES_HTTP_PROCESS_FE,
+	_(AN_RES_HTTP_PROCESS_BE, _(AN_RES_FLT_HTTP_HDRS,
+	_(AN_RES_HTTP_XFER_BODY, _(AN_RES_WAIT_CLI, _(AN_RES_FLT_XFER_DATA,
+	_(AN_RES_FLT_END)))))))))))))))))))))))))))))));
+	/* epilogue */
+	_(~0U);
+	return buf;
+#undef _
+}
+
 /* Magic value to forward infinite size (TCP, ...), used with ->to_forward */
 #define CHN_INFINITE_FORWARD    MAX_RANGE(unsigned int)