7976e2588e92dca0567231cf3998759bf6f1827f
max
  Thu May 7 03:27:42 2015 -0700
implementing the external tools "send to" menu, refs #15113

diff --git src/lib/sqlNum.c src/lib/sqlNum.c
index 081f857..9bdd963 100644
--- src/lib/sqlNum.c
+++ src/lib/sqlNum.c
@@ -1,301 +1,323 @@
 /* sqlnum.c - Routines to convert from ascii to integer
  * representation of numbers. 
  *
  * This file is copyright 2002 Jim Kent, but license is hereby
  * granted for all use - public, private or commercial. */
 
 #include "common.h"
 #include "sqlNum.h"
+#include "errAbort.h"
 
 /* The sql<Type>InList functions allow for fast thread-safe processing of dynamic arrays in sqlList */
 
 
-unsigned sqlUnsigned(char *s)
+unsigned sqlUnsignedOrError(char *s, char *format, ...)
 /* Convert series of digits to unsigned integer about
  * twice as fast as atoi (by not having to skip white 
- * space or stop except at the null byte.) */
+ * space or stop except at the null byte.) 
+ * like sqlUnsigned, with an optional error message as a printf-style vararg
+ * */
 {
 unsigned res = 0;
 char *p = s;
 char c;
 
 while (((c = *(p++)) >= '0') && (c <= '9'))
     {
     res *= 10;
     res += c - '0';
     }
 --p;
 /* test for invalid character or empty */
 if ((c != '\0') || (p == s))
+    {
+    if (format==NULL)
         errAbort("invalid unsigned integer: \"%s\"", s);
+    else
+        {
+        //errAbort("%s", errorMsg);
+        va_list args;
+        va_start(args, format);
+        vaErrAbort(format, args);
+        va_end(args);
+        }
+    }
 return res;
 }
 
+unsigned sqlUnsigned(char *s)
+/* Convert series of digits to unsigned integer about
+ * twice as fast as atoi (by not having to skip white 
+ * space or stop except at the null byte.) */
+{
+return sqlUnsignedOrError(s, NULL, NULL);
+}
+
 unsigned sqlUnsignedInList(char **pS)
 /* Convert series of digits to unsigned integer about
  * twice as fast as atoi (by not having to skip white 
  * space or stop except at the null byte.) 
  * All of string is number. Number may be delimited by a comma. 
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 unsigned res = 0;
 char *p = s;
 char c;
 
 while (((c = *(p++)) >= '0') && (c <= '9'))
     {
     res *= 10;
     res += c - '0';
     }
 --p;
 if (!(c == '\0' || c == ',') || (p == s))
     {
     char *e = strchr(s, ',');
     if (e)
 	*e = 0;
     errAbort("invalid unsigned integer: \"%s\"", s);
     }
 *pS = p;
 return res;
 }
 
 unsigned long sqlUnsignedLong(char *s)
 /* Convert series of digits to unsigned long about
  * twice as fast as atol (by not having to skip white 
  * space or stop except at the null byte.) */
 {
 unsigned long res = 0;
 char *p = s;
 char c;
 
 while (((c = *(p++)) >= '0') && (c <= '9'))
     {
     res *= 10;
     res += c - '0';
     }
 --p;
 if ((c != '\0') || (p == s))
     errAbort("invalid unsigned long: \"%s\"", s);
 return res;
 }
 
 unsigned long sqlUnsignedLongInList(char **pS)
 /* Convert series of digits to unsigned long about
  * twice as fast as atol (by not having to skip white 
  * space or stop except at the null byte.) 
  * All of string is number. Number may be delimited by a comma. 
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 unsigned long res = 0;
 char *p = s;
 char c;
 
 while (((c = *(p++)) >= '0') && (c <= '9'))
     {
     res *= 10;
     res += c - '0';
     }
 --p;
 if (!(c == '\0' || c == ',') || (p == s))
     {
     char *e = strchr(s, ',');
     if (e)
 	*e = 0;
     errAbort("invalid unsigned long: \"%s\"", s);
     }
 *pS = p;
 return res;
 }
 
 int sqlSigned(char *s)
 /* Convert string to signed integer.  Unlike atol assumes 
  * all of string is number. */
 {
 int res = 0;
 char *p, *p0 = s;
 
 if (*p0 == '-')
     p0++;
 p = p0;
 while ((*p >= '0') && (*p <= '9'))
     {
     res *= 10;
     res += *p - '0';
     p++;
     }
 /* test for invalid character, empty, or just a minus */
 if ((*p != '\0') || (p == p0))
     errAbort("invalid signed integer: \"%s\"", s);
 if (*s == '-')
     return -res;
 else
     return res;
 }
 
 int sqlSignedInList(char **pS)
 /* Convert string to signed integer.  Unlike atol assumes 
  * all of string is number. Number may be delimited by a comma. 
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 int res = 0;
 char *p, *p0 = s;
 
 if (*p0 == '-')
     p0++;
 p = p0;
 while ((*p >= '0') && (*p <= '9'))
     {
     res *= 10;
     res += *p - '0';
     p++;
     }
 /* test for invalid character, empty, or just a minus */
 if (!(*p == '\0' || *p == ',') || (p == p0))
     {
     char *e = strchr(s, ',');
     if (e)
 	*e = 0;
     errAbort("invalid signed integer: \"%s\"", s);
     }
 *pS = p;
 if (*s == '-')
     return -res;
 else
     return res;
 }
 
 long long sqlLongLong(char *s)
 /* Convert string to a long long.  Unlike atol assumes all of string is
  * number. */
 {
 long long res = 0;
 char *p, *p0 = s;
 
 if (*p0 == '-')
     p0++;
 p = p0;
 while ((*p >= '0') && (*p <= '9'))
     {
     res *= 10;
     res += *p - '0';
     p++;
     }
 /* test for invalid character, empty, or just a minus */
 if ((*p != '\0') || (p == p0))
     errAbort("invalid signed long long: \"%s\"", s);
 if (*s == '-')
     return -res;
 else
     return res;
 }
 
 long long sqlLongLongInList(char **pS)
 /* Convert string to a long long.  Unlike atol, assumes 
  * all of string is number. Number may be delimited by a comma. 
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 long long res = 0;
 char *p, *p0 = s;
 
 if (*p0 == '-')
     p0++;
 p = p0;
 while ((*p >= '0') && (*p <= '9'))
     {
     res *= 10;
     res += *p - '0';
     p++;
     }
 /* test for invalid character, empty, or just a minus */
 if (!(*p == '\0' || *p == ',') || (p == p0))
     {
     char *e = strchr(s, ',');
     if (e)
 	*e = 0;
     errAbort("invalid signed long long: \"%s\"", s);
     }
 *pS = p;
 if (*s == '-')
     return -res;
 else
     return res;
 }
 
 float sqlFloat(char *s)
 /* Convert string to a float.  Assumes all of string is number
  * and aborts on an error. */
 {
 char* end;
 /*	used to have an ifdef here to use strtof() but that doesn't
  *	actually exist on all systems and since strtod() does, may as
  *	well use it since it will do the job here.
  */
 float val = (float) strtod(s, &end);
 
 if ((end == s) || (*end != '\0'))
     errAbort("invalid float: %s", s);
 return val;
 }
 
 float sqlFloatInList(char **pS)
 /* Convert string to a float.  Assumes all of string is number
  * and aborts on an error. 
  * Number may be delimited by a comma. 
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 char* end;
 /*	used to have an ifdef here to use strtof() but that doesn't
  *	actually exist on all systems and since strtod() does, may as
  *	well use it since it will do the job here.
  */
 float val = (float) strtod(s, &end);
 
 if ((end == s) || !(*end == '\0' || *end == ','))
     {
     char *e = strchr(s, ',');
     if (e)
 	*e = 0;
     errAbort("invalid float: %s", s);
     }
 *pS = end;
 return val;
 }
 
 double sqlDouble(char *s)
 /* Convert string to a double.  Assumes all of string is number
  * and aborts on an error. */
 {
 char* end;
 double val = strtod(s, &end);
 
 if ((end == s) || (*end != '\0'))
     errAbort("invalid double: %s", s);
 return val;
 }
 
 double sqlDoubleInList(char **pS)
 /* Convert string to a double.  Assumes all of string is number
  * and aborts on an error.
  * Number may be delimited by a comma.
  * Returns the position of the delimiter or the terminating 0. */
 {
 char *s = *pS;
 char* end;
 double val = strtod(s, &end);
 
 if ((end == s) || !(*end == '\0' || *end == ','))
     {
     char *e = strchr(s, ',');
     if (e)
         *e = 0;
     errAbort("invalid double: %s", s);
     }
 *pS = end;
 return val;
 }