MINOR: config: support process ranges for "bind-process"

Several users have already been caught by "bind-process" which does not
support ranges, so let's support them now.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index b503720..4d25015 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -580,7 +580,7 @@
   the "-p" command line argument. The file must be accessible to the user
   starting the process. See also "daemon".
 
-stats bind-process [ all | odd | even | <number 1-32> ] ...
+stats bind-process [ all | odd | even | <number 1-32>[-<number 1-32>] ] ...
   Limits the stats socket to a certain set of processes numbers. By default the
   stats socket is bound to all processes, causing a warning to be emitted when
   nbproc is greater than 1 because there is no way to select the target process
@@ -1582,7 +1582,7 @@
              documentation, and section 5 about bind options.
 
 
-bind-process [ all | odd | even | <number 1-32> ] ...
+bind-process [ all | odd | even | <number 1-32>[-<number 1-32>] ] ...
   Limit visibility of an instance to a certain set of processes numbers.
   May be used in sections :   defaults | frontend | listen | backend
                                  yes   |    yes   |   yes  |   yes
@@ -1598,10 +1598,11 @@
                   with less than 2 processes otherwise some instances might be
                   missing from all processes.
 
-    number        The instance will be enabled on this process number, between
-                  1 and 32. You must be careful not to reference a process
-                  number greater than the configured global.nbproc, otherwise
-                  some instances might be missing from all processes.
+    number        The instance will be enabled on this process number or range,
+                  whose values must all be between 1 and 32. You must be
+                  careful not to reference a process number greater than the
+                  configured global.nbproc, otherwise some instances might be
+                  missing from all processes.
 
   This keyword limits binding of certain instances to certain processes. This
   is useful in order not to have too many processes listening to the same
@@ -1630,6 +1631,10 @@
             bind 10.0.0.3:80
             bind-process 1 2 3 4
 
+        listen management
+            bind 10.0.0.4:80
+            bind-process 1-4
+
   See also : "nbproc" in global section.
 
 
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ec1912b..9ce0f2b 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2023,7 +2023,8 @@
 		unsigned int set = 0;
 
 		while (*args[cur_arg]) {
-			int u;
+			unsigned int low, high;
+
 			if (strcmp(args[cur_arg], "all") == 0) {
 				set = 0;
 				break;
@@ -2034,20 +2035,39 @@
 			else if (strcmp(args[cur_arg], "even") == 0) {
 				set |= 0xAAAAAAAA;
 			}
-			else {
-				u = str2uic(args[cur_arg]);
-				if (u < 1 || u > 32) {
-					Alert("parsing [%s:%d]: %s expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
+			else if (isdigit(*args[cur_arg])) {
+				char *dash = strchr(args[cur_arg], '-');
+
+				low = high = str2uic(args[cur_arg]);
+				if (dash)
+					high = str2uic(dash + 1);
+
+				if (high < low) {
+					unsigned int swap = low;
+					low = high;
+					high = swap;
+				}
+
+				if (low < 1 || high > 32) {
+					Alert("parsing [%s:%d]: %s supports process numbers from 1 to 32.\n",
 					      file, linenum, args[0]);
 					err_code |= ERR_ALERT | ERR_FATAL;
 					goto out;
 				}
-				if (u > global.nbproc) {
-					Warning("parsing [%s:%d]: %s references process number higher than global.nbproc.\n",
-						file, linenum, args[0]);
+
+				if (high > global.nbproc) {
+					Warning("parsing [%s:%d]: %s references process number %d which is higher than global.nbproc (%d).\n",
+						file, linenum, args[0], high, global.nbproc);
 					err_code |= ERR_WARN;
 				}
-				set |= 1 << (u - 1);
+				while (low <= high)
+					set |= 1 << (low++ - 1);
+			}
+			else {
+				Alert("parsing [%s:%d]: %s expects 'all', 'odd', 'even', or a list of process ranges with numbers from 1 to 32.\n",
+				      file, linenum, args[0]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
 			}
 			cur_arg++;
 		}
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 5f59dde..8264506 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -305,7 +305,8 @@
 		unsigned int set = 0;
 
 		while (*args[cur_arg]) {
-			int u;
+			unsigned int low, high;
+
 			if (strcmp(args[cur_arg], "all") == 0) {
 				set = 0;
 				break;
@@ -316,15 +317,33 @@
 			else if (strcmp(args[cur_arg], "even") == 0) {
 				set |= 0xAAAAAAAA;
 			}
-			else {
-				u = str2uic(args[cur_arg]);
-				if (u < 1 || u > 32) {
-					memprintf(err,
-						  "'%s %s' expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
-						  args[0], args[1]);
+			else if (isdigit(*args[cur_arg])) {
+				char *dash = strchr(args[cur_arg], '-');
+
+				low = high = str2uic(args[cur_arg]);
+				if (dash)
+					high = str2uic(dash + 1);
+
+				if (high < low) {
+					unsigned int swap = low;
+					low = high;
+					high = swap;
+				}
+
+				if (low < 1 || high > 32) {
+					memprintf(err, "'%s %s' supports process numbers from 1 to 32.\n",
+					          args[0], args[1]);
 					return -1;
 				}
-				set |= 1 << (u - 1);
+
+				while (low <= high)
+					set |= 1 << (low++ - 1);
+			}
+			else {
+				memprintf(err,
+				          "'%s %s' expects 'all', 'odd', 'even', or a list of process ranges with numbers from 1 to 32.\n",
+				          args[0], args[1]);
+				return -1;
 			}
 			cur_arg++;
 		}