Fix for bug #15469: RFE: relative arguments in "number" command

"Nico R." <[email protected]> Thu, 15 Nov 2007 00:41:16 +0100
Newsgroups gmane.comp.gnu.screen
Message-ID <[email protected]>
Hello,

here is a fix for RFE #15469 <URL:https://savannah.gnu.org/bugs/?15469>.

The patch allows to use "+" or "-" in front of a number with the
"number" command, in order to have screen calculate the window number
relative to the current one. The syntax without "+" or "-" is of course
still valid.

Have fun,
-- 
Nico
screen-cvs20071114T001101+0100-bug_15469.patch (text/plain, 2.3 KB)
Patch to fix RFE #15469.
 -nico

--- screen.orig/src/process.c	2007-11-14 23:11:01.000000000 +0000
+++ screen/src/process.c	2007-11-14 23:12:01.000000000 +0000
@@ -2801,9 +2801,9 @@
         Msg(0, "This is window %d (%s).\n", fore->w_number, fore->w_title);
       else
         {
-	  int old = fore->w_number;
+	  int old = n = fore->w_number;
 
-	  if (ParseNum(act, &n) || n >= maxwin)
+	  if (ParseNumPlusMinus(act, &n) || n >= maxwin || n < 0)
 	    break;
 	  p = wtab[n];
 	  wtab[n] = fore;
@@ -4504,6 +4504,33 @@
   return 0;
 }
 
+/*
+ * Parses an integer which is zero or positive.
+ * A null pointer, the empty string, non-numbers, or negative values are not
+ * allowed; an error is indicated by a negative return value.
+ */
+int
+ParseNum_sub(p)
+char *p;
+{
+  int i;
+
+  if (!p || !*p)
+    return -1;
+
+  i = 0;
+  do
+    {
+      if (*p >= '0' && *p <= '9')
+	i = 10 * i + (*p - '0');
+      else
+	return -1;
+      p++;
+    }
+  while (*p);
+  return i;
+}
+
 int
 ParseNum(act, var)
 struct action *act;
@@ -4519,24 +4546,62 @@
           rc_name, comms[act->nr].name);
       return -1;
     }
-  i = 0; 
-  while (*p)
+  i = ParseNum_sub(p); 
+  if (i < 0)
     {
-      if (*p >= '0' && *p <= '9')
-	i = 10 * i + (*p - '0');
-      else
-	{
-	  Msg(0, "%s: %s: invalid argument. Give numeric argument.",
-	      rc_name, comms[act->nr].name);
-	  return -1;
-	}    
-      p++;
-    }
+      Msg(0, "%s: %s: invalid argument. Give numeric argument.",
+	  rc_name, comms[act->nr].name);
+      return -1;
+    }    
   debug1("ParseNum got %d\n", i);
   *var = i;
   return 0;
 }
 
+int
+ParseNumPlusMinus(act, var)
+struct action *act;
+int *var;
+{
+  char *p, **args = act->args;
+
+  p = *args;
+  if (p == 0 || *p == 0 || args[1])
+    {
+      Msg(0, "%s: %s: invalid argument. Give one argument.",
+          rc_name, comms[act->nr].name);
+      return -1;
+    }
+  if (*p == '+')
+    {
+      int plus;
+
+      p++;
+      plus = ParseNum_sub(p);
+      if (plus < 0)
+        return -1;
+
+      *var += plus;
+    }
+  else if (*p == '-')
+    {
+      int minus;
+
+      p++;
+      minus = ParseNum_sub(p);
+      if (minus < 0)
+        return -1;
+
+      *var -= minus;
+    }
+  else
+    if (ParseNum(act, var))
+      return -1;
+
+  debug1("ParseNumPlusMinus got %d\n", *var);
+  return 0;
+}
+
 static int
 ParseNum1000(act, var)
 struct action *act;
signature.asc (application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7-ecc0.1.6 (GNU/Linux)

iD8DBQFHO4ejxI5uhYOGv4URA/7LAJ9PcMh1whhQtb6r1zixRHNLVoHDoACgkCy0
OCvi5gBkQvaSZAb4slwHT9k=
=jADO
-----END PGP SIGNATURE-----