summaryrefslogtreecommitdiffstats
path: root/local/strutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'local/strutils.c')
-rw-r--r--local/strutils.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/local/strutils.c b/local/strutils.c
new file mode 100644
index 0000000..e5245db
--- /dev/null
+++ b/local/strutils.c
@@ -0,0 +1,123 @@
+/*
+ * strutils.c - various string routines shared by commands
+ * This file was copied from util-linux at fall 2011.
+ *
+ * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "c.h"
+#include "strutils.h"
+
+/*
+ * same as strtol(3) but exit on failure instead of returning crap
+ */
+long strtol_or_err(const char *str, const char *errmesg)
+{
+ long num;
+ char *end = NULL;
+
+ if (str != NULL && *str != '\0') {
+ errno = 0;
+ num = strtol(str, &end, 10);
+ if (errno == 0 && str != end && end != NULL && *end == '\0')
+ return num;
+ }
+ error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
+ return 0;
+}
+
+/*
+ * same as strtod(3) but exit on failure instead of returning crap
+ */
+double strtod_or_err(const char *str, const char *errmesg)
+{
+ double num;
+ char *end = NULL;
+
+ if (str != NULL && *str != '\0') {
+ errno = 0;
+ num = strtod(str, &end);
+ if (errno == 0 && str != end && end != NULL && *end == '\0')
+ return num;
+ }
+ error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
+ return 0;
+}
+
+/*
+ * Covert a string into a double in a non-locale aware way.
+ * This means the decimal point can be either . or ,
+ * Also means you cannot use the other for thousands separator
+ *
+ * Exits on failure like its other _or_err cousins
+ */
+double strtod_nol_or_err(char *str, const char *errmesg)
+{
+ double num;
+ const char *cp, *radix;
+ double mult;
+ int negative = 0;
+
+ if (str != NULL && *str != '\0') {
+ num = 0.0;
+ cp = str;
+ /* strip leading spaces */
+ while (isspace(*cp))
+ cp++;
+
+ /* get sign */
+ if (*cp == '-') {
+ negative = 1;
+ cp++;
+ } else if (*cp == '+')
+ cp++;
+
+ /* find radix */
+ radix = cp;
+ mult=0.1;
+ while(isdigit(*radix)) {
+ radix++;
+ mult *= 10;
+ }
+ while(isdigit(*cp)) {
+ num += (*cp - '0') * mult;
+ mult /= 10;
+ cp++;
+ }
+ /* got the integers */
+ if (*cp == '\0')
+ return (negative?-num:num);
+ if (*cp != '.' && *cp != ',')
+ error(EXIT_FAILURE, EINVAL, "%s: '%s'", errmesg, str);
+
+ cp++;
+ mult = 0.1;
+ while(isdigit(*cp)) {
+ num += (*cp - '0') * mult;
+ mult /= 10;
+ cp++;
+ }
+ if (*cp == '\0')
+ return (negative?-num:num);
+ }
+ error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
+ return 0;
+}