summaryrefslogtreecommitdiffstats
path: root/dev/flags/flags.c
blob: 65af2379b09b8ec071284912ee7b142310bcedb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <stdio.h>
#include <stdlib.h>

/* make the include files below expose their flags */
#define HA_EXPOSE_FLAGS

#include <haproxy/channel-t.h>
#include <haproxy/connection-t.h>
#include <haproxy/fd-t.h>
#include <haproxy/http_ana-t.h>
#include <haproxy/htx-t.h>
#include <haproxy/mux_fcgi-t.h>
#include <haproxy/mux_h2-t.h>
#include <haproxy/mux_h1-t.h>
#include <haproxy/stconn-t.h>
#include <haproxy/stream-t.h>
#include <haproxy/task-t.h>

// 1 bit per flag, no hole permitted here
#define SHOW_AS_ANA   0x00000001
#define SHOW_AS_CHN   0x00000002
#define SHOW_AS_CONN  0x00000004
#define SHOW_AS_SC    0x00000008
#define SHOW_AS_SET   0x00000010
#define SHOW_AS_STRM  0x00000020
#define SHOW_AS_TASK  0x00000040
#define SHOW_AS_TXN   0x00000080
#define SHOW_AS_SD    0x00000100
#define SHOW_AS_HSL   0x00000200
#define SHOW_AS_HTX   0x00000400
#define SHOW_AS_HMSG  0x00000800
#define SHOW_AS_FD    0x00001000
#define SHOW_AS_H2C   0x00002000
#define SHOW_AS_H2S   0x00004000
#define SHOW_AS_H1C   0x00008000
#define SHOW_AS_H1S   0x00010000
#define SHOW_AS_FCONN 0x00020000
#define SHOW_AS_FSTRM 0x00040000

// command line names, must be in exact same order as the SHOW_AS_* flags above
// so that show_as_words[i] matches flag 1U<<i.
const char *show_as_words[] = { "ana", "chn", "conn", "sc", "stet", "strm", "task", "txn", "sd", "hsl", "htx", "hmsg", "fd", "h2c", "h2s",  "h1c", "h1s", "fconn", "fstrm"};

/* will be sufficient for even largest flag names */
static char buf[4096];
static size_t bsz = sizeof(buf);

unsigned int get_show_as(const char *word)
{
	int w = 0;

	while (1) {
		if (w == sizeof(show_as_words) / sizeof(*show_as_words))
			return 0;
		if (strcmp(word, show_as_words[w]) == 0)
			return 1U << w;
		w++;
	}
}

void usage_exit(const char *name)
{
	int word, nbword;

	fprintf(stderr, "Usage: %s [", name);

	nbword = sizeof(show_as_words) / sizeof(*show_as_words);
	for (word = 0; word < nbword; word++)
		fprintf(stderr, "%s%s", word ? "|" : "", show_as_words[word]);
	fprintf(stderr, "]* { [+-][0x]value* | - }\n");
	exit(1);
}

int main(int argc, char **argv)
{
	unsigned int flags;
	unsigned int show_as = 0;
	unsigned int f;
	const char *name = argv[0];
	char line[20];
	char *value;
	int multi = 0;
	int use_stdin = 0;
	char *err;

	while (argc > 0) {
		argv++; argc--;
		if (argc < 1)
			usage_exit(name);

		f = get_show_as(argv[0]);
		if (!f)
			break;
		show_as |= f;
	}

	if (!show_as)
		show_as = ~0U;

	if (argc > 1)
		multi = 1;

	if (strcmp(argv[0], "-") == 0)
		use_stdin = 1;

	while (argc > 0) {
		if (use_stdin) {
			value = fgets(line, sizeof(line), stdin);
			if (!value)
				break;

			/* skip common leading delimiters that slip from copy-paste */
			while (*value == ' ' || *value == '\t' || *value == ':' || *value == '=')
				value++;

			/* stop at the end of the number and trim any C suffix like "UL" */
			err = value;
			while (*err == '-' || *err == '+' ||
			       (isalnum((unsigned char)*err) && toupper((unsigned char)*err) != 'U' && toupper((unsigned char)*err) != 'L'))
				err++;
			*err = 0;
		} else {
			value = argv[0];
			argv++; argc--;
		}

		flags = strtoul(value, &err, 0);
		if (!*value || *err) {
			fprintf(stderr, "Unparsable value: <%s>\n", value);
			usage_exit(name);
		}

		if (multi || use_stdin)
			printf("### 0x%08x:\n", flags);

		if (show_as & SHOW_AS_ANA)   printf("chn->ana    = %s\n", (chn_show_analysers(buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_CHN)   printf("chn->flags  = %s\n", (chn_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_CONN)  printf("conn->flags = %s\n", (conn_show_flags   (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_SC)    printf("sc->flags = %s\n",   (sc_show_flags     (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_SD)    printf("sd->flags = %s\n",   (se_show_flags     (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_SET)   printf("strm->et = %s\n",    (strm_et_show_flags(buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_STRM)  printf("strm->flags = %s\n", (strm_show_flags   (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_TASK)  printf("task->state = %s\n", (task_show_state   (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_TXN)   printf("txn->flags = %s\n",  (txn_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_HSL)   printf("sl->flags = %s\n",   (hsl_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_HTX)   printf("htx->flags = %s\n",  (htx_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_HMSG)  printf("hmsg->flags = %s\n", (hmsg_show_flags   (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_FD)    printf("fd->flags = %s\n",   (fd_show_flags     (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_H2C)   printf("h2c->flags = %s\n",  (h2c_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_H2S)   printf("h2s->flags = %s\n",  (h2s_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_H1C)   printf("h1c->flags = %s\n",  (h1c_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_H1S)   printf("h1s->flags = %s\n",  (h1s_show_flags    (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_FCONN) printf("fconn->flags = %s\n",(fconn_show_flags  (buf, bsz, " | ", flags), buf));
		if (show_as & SHOW_AS_FSTRM) printf("fstrm->flags = %s\n",(fstrm_show_flags  (buf, bsz, " | ", flags), buf));
	}
	return 0;
}