]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CONTRIB: debug: also support reading values from stdin
authorWilly Tarreau <w@1wt.eu>
Thu, 6 Feb 2020 17:17:50 +0000 (18:17 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 6 Feb 2020 17:30:07 +0000 (18:30 +0100)
This is convenient when processing large dumps, it allows to copy-paste
values to inspect from one window to another, or to directly transfer
a "show fd"/"show stream" output through sed. In order to do this, simply
pass "-" alone instead of the value and they will all be read one line at
a time from stdin. For example, in order to quickly print the different
set of connection flags from "show fd", this is sufficient:

     sed -ne 's/^.* cflg=\([^ ]*\).*/\1/p' | contrib/debug/flags conn -

contrib/debug/flags.c

index 65286f188874d20dd458512bd6db2383d1f88595..2f92abeb543c079eb43d096c364774a73d87a1ad 100644 (file)
@@ -395,7 +395,7 @@ void show_strm_flags(unsigned int f)
 
 void usage_exit(const char *name)
 {
-       fprintf(stderr, "Usage: %s [ana|chn|conn|cs|si|sierr|strm|task|txn]* [0x]value*\n", name);
+       fprintf(stderr, "Usage: %s [ana|chn|conn|cs|si|sierr|strm|task|txn]* { [+-][0x]value* | - }\n", name);
        exit(1);
 }
 
@@ -405,7 +405,10 @@ int main(int argc, char **argv)
        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) {
@@ -425,14 +428,38 @@ int main(int argc, char **argv)
        if (argc > 1)
                multi = 1;
 
+       if (strcmp(argv[0], "-") == 0)
+               use_stdin = 1;
+
        while (argc > 0) {
-               flags = strtoul(argv[0], &err, 0);
-               if (!*argv[0] || *err) {
-                       fprintf(stderr, "Unparsable value: <%s>\n", argv[0]);
+               if (use_stdin) {
+                       value = fgets(line, sizeof(line), stdin);
+                       if (!value)
+                               break;
+
+                       /* skip common leading delimitors 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(*err) && toupper(*err) != 'U' && toupper(*err) != 'L'))
+                               err++;
+                       if (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)
+               if (multi || use_stdin)
                        printf("### 0x%08x:\n", flags);
 
                if (show_as & SHOW_AS_ANA)   show_chn_ana(flags);
@@ -444,8 +471,6 @@ int main(int argc, char **argv)
                if (show_as & SHOW_AS_STRM)  show_strm_flags(flags);
                if (show_as & SHOW_AS_TASK)  show_task_state(flags);
                if (show_as & SHOW_AS_TXN)   show_txn_flags(flags);
-
-               argv++; argc--;
        }
        return 0;
 }