0999158088e0fb3715eb27703c8c4f7123d77144 galt Mon Sep 21 16:51:20 2015 -0700 added GNU-C attributes to function declarations in src/inc, src/hg/inc, and some CGIs so that the compiler can catch errors where the parameter list given by the user does not match their format string. These var-args functions are like printf. diff --git src/lib/sqlNum.c src/lib/sqlNum.c index 9bdd963..f3b2a7c 100644 --- src/lib/sqlNum.c +++ src/lib/sqlNum.c @@ -1,323 +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 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.) * 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); +return sqlUnsignedOrError(s, 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; }