Re: [PATCH] strutils: general purpose string handling functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2010-10-22 at 22:15 +0200, Karel Zak wrote:
> On Fri, Oct 22, 2010 at 04:40:22PM -0300, Davidlohr Bueso wrote:
> > On Fri, 2010-10-22 at 21:31 +0200, Karel Zak wrote:
> > > On Fri, Oct 22, 2010 at 03:54:11PM -0300, Davidlohr Bueso wrote:
> > > > [PATCH] strutils: general purpose string handling functions
> > > > 
> > > > This patch replaces a few functions used throught the source:
> > > > * Renames getnum (from schedutils) to strtol_on_err
> > > 
> > >  What about  "strtol_or_err()" ?
> > 
> > Don't quite follow, we had decided that that would be the name for the
> > getnum() replacement.
> 
>  Yep, we have talked about "strtol ***or*** err", but I see "on" in
>  your patch ;-)

Resending correction below. Thanks.


Signed-off-by: Davidlohr Bueso <dave@xxxxxxx>
---
 include/Makefile.am     |    4 +-
 lib/Makefile.am         |    4 +-
 lib/strtosize.c         |  148 ----------------------------------
 lib/strutils.c          |  204 +++++++++++++++++++++++++++++++++++++++++++++++
 misc-utils/Makefile.am  |    4 +-
 mount/Makefile.am       |    6 +-
 schedutils/Makefile.am  |    2 +-
 schedutils/chrt.c       |    6 +-
 schedutils/ionice.c     |   12 ++--
 schedutils/schedutils.c |   34 --------
 schedutils/schedutils.h |    7 --
 schedutils/taskset.c    |    4 +-
 sys-utils/Makefile.am   |    2 +-
 13 files changed, 226 insertions(+), 211 deletions(-)
 delete mode 100644 lib/strtosize.c
 create mode 100644 lib/strutils.c
 delete mode 100644 schedutils/schedutils.c
 delete mode 100644 schedutils/schedutils.h

diff --git a/include/Makefile.am b/include/Makefile.am
index 3b93acd..ac7306c 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -20,11 +20,11 @@ dist_noinst_HEADERS = \
 	nls.h \
 	pathnames.h \
 	setproctitle.h \
-	strtosize.h \
 	swapheader.h \
 	tt.h \
 	usleep.h \
 	wholedisk.h \
 	widechar.h \
 	writeall.h \
-	xstrncpy.h
+	xstrncpy.h \
+	strutils.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 2a185f3..2f6291b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am
 AM_CPPFLAGS += -DTEST_PROGRAM
 
 noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \
-		  test_strtosize test_tt
+		  test_tt test_strutils
 if LINUX
 if HAVE_CPU_SET_T
 noinst_PROGRAMS += test_cpuset
@@ -14,7 +14,7 @@ test_blkdev_SOURCES = blkdev.c
 test_ismounted_SOURCES = ismounted.c
 test_wholedisk_SOURCES = wholedisk.c
 test_mangle_SOURCES = mangle.c
-test_strtosize_SOURCES = strtosize.c
+test_strutils_SOURCES = strutils.c
 if LINUX
 test_cpuset_SOURCES = cpuset.c
 endif
diff --git a/lib/strtosize.c b/lib/strtosize.c
deleted file mode 100644
index 068c542..0000000
--- a/lib/strtosize.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * strtosize() - convert string to size (uintmax_t).
- *
- * Supported suffixes:
- *
- * XiB or X for 2^N
- *     where X = {K,M,G,T,P,E,Y,Z}
- *        or X = {k,m,g,t,p,e}  (undocumented for backward compatibility only)
- * for example:
- *		10KiB	= 10240
- *		10K	= 10240
- *
- * XB for 10^N
- *     where X = {K,M,G,T,P,E,Y,Z}
- * for example:
- *		10KB	= 10000
- *
- * Note that the function does not accept numbers with '-' (negative sign)
- * prefix.
- *
- * Returns 0 on success, -1 in case of error, -2 in case of overflow.
- *
- * Copyright (C) 2010 Karel Zak <kzak@xxxxxxxxxx>
- */
-#include <stdio.h>
-#include <inttypes.h>
-#include <ctype.h>
-#include <errno.h>
-
-static int do_scale_by_power (uintmax_t *x, int base, int power)
-{
-	while (power--) {
-		if (UINTMAX_MAX / base < *x)
-			return -2;
-		*x *= base;
-	}
-	return 0;
-}
-
-int strtosize(const char *str, uintmax_t *res)
-{
-	char *p;
-	uintmax_t x;
-	int base = 1024, rc = 0;
-
-	*res = 0;
-
-	if (!str || !*str)
-		goto err;
-
-	/* Only positive numbers are acceptable
-	 *
-	 * Note that this check is not perfect, it would be better to
-	 * use lconv->negative_sign. But coreutils use the same solution,
-	 * so it's probably good enough...
-	 */
-	p = (char *) str;
-	while (isspace((unsigned char) *p))
-		p++;
-	if (*p == '-')
-		goto err;
-	p = NULL;
-
-	errno = 0;
-	x = strtoumax(str, &p, 0);
-
-	if (p == str ||
-	    (errno != 0 && (x == UINTMAX_MAX || x == 0)))
-		goto err;
-
-	if (!p || !*p)
-		goto done;			/* without suffix */
-
-	/*
-	 * Check size suffixes
-	 */
-	if (*(p + 1) == 'i' && *(p + 2) == 'B' && !*(p + 3))
-		base = 1024;			/* XiB, 2^N */
-	else if (*(p + 1) == 'B' && !*(p + 2))
-		base = 1000;			/* XB, 10^N */
-	else if (*(p + 1))
-		goto err;			/* unexpected suffix */
-
-	switch(*p) {
-	case 'K':
-	case 'k':
-		rc = do_scale_by_power(&x, base, 1);
-		break;
-	case 'M':
-	case 'm':
-		rc = do_scale_by_power(&x, base, 2);
-		break;
-	case 'G':
-	case 'g':
-		rc = do_scale_by_power(&x, base, 3);
-		break;
-	case 'T':
-	case 't':
-		rc = do_scale_by_power(&x, base, 4);
-		break;
-	case 'P':
-	case 'p':
-		rc = do_scale_by_power(&x, base, 5);
-		break;
-	case 'E':
-	case 'e':
-		rc = do_scale_by_power(&x, base, 6);
-		break;
-	case 'Z':
-		rc = do_scale_by_power(&x, base, 7);
-		break;
-	case 'Y':
-		rc = do_scale_by_power(&x, base, 8);
-		break;
-	default:
-		goto err;
-	}
-
-done:
-	*res = x;
-	return rc;
-err:
-	return -1;
-}
-
-#ifdef TEST_PROGRAM
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <err.h>
-
-int main(int argc, char *argv[])
-{
-	uintmax_t size = 0;
-
-	if (argc < 2) {
-		fprintf(stderr, "usage: %s <number>[suffix]\n",	argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	if (strtosize(argv[1], &size))
-		errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]);
-
-	printf("%25s : %20ju\n", argv[1], size);
-	return EXIT_FAILURE;
-}
-#endif /* TEST_PROGRAM */
-
diff --git a/lib/strutils.c b/lib/strutils.c
new file mode 100644
index 0000000..9c8e32b
--- /dev/null
+++ b/lib/strutils.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 Davidlohr Bueso <dave@xxxxxxx>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ * General purpose string related utilities.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+#include <inttypes.h>
+#include <ctype.h>
+
+#include "nls.h"
+
+static int do_scale_by_power(uintmax_t *x, int base, int power)
+{
+	while (power--) {
+		if (UINTMAX_MAX / base < *x)
+			return -2;
+		*x *= base;
+	}
+	return 0;
+}
+
+/*
+ * strtosize() - convert string to size (uintmax_t).
+ *
+ * Supported suffixes:
+ *
+ * XiB or X for 2^N
+ *     where X = {K,M,G,T,P,E,Y,Z}
+ *        or X = {k,m,g,t,p,e}  (undocumented for backward compatibility only)
+ * for example:
+ *		10KiB	= 10240
+ *		10K	= 10240
+ *
+ * XB for 10^N
+ *     where X = {K,M,G,T,P,E,Y,Z}
+ * for example:
+ *		10KB	= 10000
+ *
+ * Note that the function does not accept numbers with '-' (negative sign)
+ * prefix.
+ *
+ * Returns 0 on success, -1 in case of error, -2 in case of overflow.
+ */
+int strtosize(const char *str, uintmax_t *res)
+{
+	char *p;
+	uintmax_t x;
+	int base = 1024, rc = 0;
+
+	*res = 0;
+
+	if (!str || !*str)
+		goto err;
+
+	/* Only positive numbers are acceptable
+	 *
+	 * Note that this check is not perfect, it would be better to
+	 * use lconv->negative_sign. But coreutils use the same solution,
+	 * so it's probably good enough...
+	 */
+	p = (char *) str;
+	while (isspace((unsigned char) *p))
+		p++;
+	if (*p == '-')
+		goto err;
+	p = NULL;
+
+	errno = 0;
+	x = strtoumax(str, &p, 0);
+
+	if (p == str ||
+	    (errno != 0 && (x == UINTMAX_MAX || x == 0)))
+		goto err;
+
+	if (!p || !*p)
+		goto done;			/* without suffix */
+
+	/*
+	 * Check size suffixes
+	 */
+	if (*(p + 1) == 'i' && *(p + 2) == 'B' && !*(p + 3))
+		base = 1024;			/* XiB, 2^N */
+	else if (*(p + 1) == 'B' && !*(p + 2))
+		base = 1000;			/* XB, 10^N */
+	else if (*(p + 1))
+		goto err;			/* unexpected suffix */
+
+	switch (*p) {
+	case 'K':
+	case 'k':
+		rc = do_scale_by_power(&x, base, 1);
+		break;
+	case 'M':
+	case 'm':
+		rc = do_scale_by_power(&x, base, 2);
+		break;
+	case 'G':
+	case 'g':
+		rc = do_scale_by_power(&x, base, 3);
+		break;
+	case 'T':
+	case 't':
+		rc = do_scale_by_power(&x, base, 4);
+		break;
+	case 'P':
+	case 'p':
+		rc = do_scale_by_power(&x, base, 5);
+		break;
+	case 'E':
+	case 'e':
+		rc = do_scale_by_power(&x, base, 6);
+		break;
+	case 'Z':
+		rc = do_scale_by_power(&x, base, 7);
+		break;
+	case 'Y':
+		rc = do_scale_by_power(&x, base, 8);
+		break;
+	default:
+		goto err;
+	}
+
+done:
+	*res = x;
+	return rc;
+err:
+	return -1;
+}
+
+#ifndef HAVE_STRNCHR
+char *strnchr(const char *s, size_t maxlen, int c)
+{
+	for (; maxlen-- && *s != '\0'; ++s)
+		if (*s == (char)c)
+			return (char *)s;
+	return NULL;
+}
+#endif
+
+#ifndef HAVE_STRNDUP
+char *strndup(const char *s, size_t n)
+{
+	size_t len = strnlen(s, n);
+	char *new = (char *) malloc((len + 1) * sizeof(char));
+	if (!new)
+		return NULL;
+	new[len] = '\0';
+	return (char *) memcpy(new, s, len);
+}
+#endif
+
+/*
+ * 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')
+		goto err;
+	errno = 0;
+	num = strtol(str, &end, 10);
+
+	if (errno || (end && *end))
+		goto err;
+
+	return num;
+err:
+	if (errno)
+		err(EXIT_FAILURE, "%s: '%s'", errmesg, str);
+	else
+		errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
+	return 0;
+}
+
+#ifdef TEST_PROGRAM
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+	uintmax_t size = 0;
+	
+	if (argc < 2) {
+		fprintf(stderr, "usage %s <number>\n", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+	printf("strtol_or_err: %l\n", strtol_or_err(argv[1], _("failed to parse number")));
+
+	if (strtosize(argv[1], &size))
+		errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]);
+
+	printf("%25s : %20ju\n", argv[1], size);
+        return EXIT_SUCCESS;
+}
+#endif /* TEST_PROGRAM */
diff --git a/misc-utils/Makefile.am b/misc-utils/Makefile.am
index 6a16f99..6d58df8 100644
--- a/misc-utils/Makefile.am
+++ b/misc-utils/Makefile.am
@@ -37,12 +37,12 @@ if BUILD_LIBBLKID
 sbin_PROGRAMS += blkid findfs wipefs
 dist_man_MANS += blkid.8 findfs.8 wipefs.8
 blkid_SOURCES = blkid.c $(top_srcdir)/lib/ismounted.c \
-		$(top_srcdir)/lib/strtosize.c
+		$(top_srcdir)/lib/strutils.c
 blkid_LDADD = $(ul_libblkid_la)
 blkid_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir)
 findfs_LDADD = $(ul_libblkid_la)
 findfs_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir)
-wipefs_SOURCES = wipefs.c $(top_srcdir)/lib/strtosize.c
+wipefs_SOURCES = wipefs.c $(top_srcdir)/lib/strutils.c
 wipefs_LDADD = $(ul_libblkid_la)
 wipefs_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir)
 if HAVE_STATIC_BLKID
diff --git a/mount/Makefile.am b/mount/Makefile.am
index 235cceb..36b06e3 100644
--- a/mount/Makefile.am
+++ b/mount/Makefile.am
@@ -28,12 +28,12 @@ cflags_common = $(AM_CFLAGS)
 ldflags_static = -all-static
 
 mount_SOURCES = mount.c $(srcs_mount) $(top_srcdir)/lib/setproctitle.c \
-		$(top_srcdir)/lib/strtosize.c
+		$(top_srcdir)/lib/strutils.c
 mount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
 mount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
 mount_LDADD = $(ldadd_common)
 
-umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strtosize.c
+umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strutils.c
 umount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
 umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
 umount_LDADD = $(ldadd_common)
@@ -45,7 +45,7 @@ swapon_CFLAGS = $(cflags_common)
 swapon_LDADD = $(ldadd_common)
 
 losetup_SOURCES = lomount.c $(srcs_common) loop.h lomount.h \
-		$(top_srcdir)/lib/strtosize.c
+		$(top_srcdir)/lib/strutils.c
 losetup_CPPFLAGS = -DMAIN $(AM_CPPFLAGS)
 
 mount_static_LDADD =
diff --git a/schedutils/Makefile.am b/schedutils/Makefile.am
index c83e5ea..dc33175 100644
--- a/schedutils/Makefile.am
+++ b/schedutils/Makefile.am
@@ -2,7 +2,7 @@ include $(top_srcdir)/config/include-Makefile.am
 
 if BUILD_SCHEDUTILS
 
-srcs_common = schedutils.c schedutils.h
+srcs_common = $(top_srcdir)/lib/strutils.c
 
 usrbin_exec_PROGRAMS = chrt
 dist_man_MANS = chrt.1
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
index 89b12c7..3cbf6d0 100644
--- a/schedutils/chrt.c
+++ b/schedutils/chrt.c
@@ -32,7 +32,7 @@
 #include "c.h"
 #include "nls.h"
 
-#include "schedutils.h"
+#include "strutils.h"
 
 /* the SCHED_BATCH is supported since Linux 2.6.16
  *  -- temporary workaround for people with old glibc headers
@@ -240,7 +240,7 @@ int main(int argc, char *argv[])
 			break;
 		case 'p':
 			errno = 0;
-			pid = getnum(argv[argc - 1], _("failed to parse pid"));
+			pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
 			break;
 		case 'r':
 			policy = SCHED_RR;
@@ -268,7 +268,7 @@ int main(int argc, char *argv[])
 	}
 
 	errno = 0;
-	priority = getnum(argv[optind], _("failed to parse priority"));
+	priority = strtol_or_err(argv[optind], _("failed to parse priority"));
 
 #ifdef SCHED_RESET_ON_FORK
 	/* sanity check */
diff --git a/schedutils/ionice.c b/schedutils/ionice.c
index 34132f0..bb66e8e 100644
--- a/schedutils/ionice.c
+++ b/schedutils/ionice.c
@@ -18,7 +18,7 @@
 
 #include "nls.h"
 
-#include "schedutils.h"
+#include "strutils.h"
 
 static int tolerant;
 
@@ -105,15 +105,15 @@ int main(int argc, char *argv[])
 	while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
 		switch (c) {
 		case 'n':
-			ioprio = getnum(optarg, _("failed to parse class data"));
+			ioprio = strtol_or_err(optarg, _("failed to parse class data"));
 			set |= 1;
 			break;
 		case 'c':
-			ioclass = getnum(optarg, _("failed to parse class"));
+			ioclass = strtol_or_err(optarg, _("failed to parse class"));
 			set |= 2;
 			break;
 		case 'p':
-			pid = getnum(optarg, _("failed to parse pid"));
+			pid = strtol_or_err(optarg, _("failed to parse pid"));
 			break;
 		case 't':
 			tolerant = 1;
@@ -147,7 +147,7 @@ int main(int argc, char *argv[])
 		ioprio_print(pid);
 
 		for(; argv[optind]; ++optind) {
-			pid = getnum(argv[optind], _("failed to parse pid"));
+			pid = strtol_or_err(argv[optind], _("failed to parse pid"));
 			ioprio_print(pid);
 		}
 	} else {
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
 
 			for(; argv[optind]; ++optind)
 			{
-				pid = getnum(argv[optind], _("failed to parse pid"));
+				pid = strtol_or_err(argv[optind], _("failed to parse pid"));
 				ioprio_setpid(pid, ioprio, ioclass);
 			}
 		}
diff --git a/schedutils/schedutils.c b/schedutils/schedutils.c
deleted file mode 100644
index 9d6051b..0000000
--- a/schedutils/schedutils.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 Karel Zak <kzak@xxxxxxxxxx>
- *
- * Released under the terms of the GNU General Public License version 2
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <err.h>
-
-#include "nls.h"
-
-long getnum(const char *str, const char *errmesg)
-{
-	long num;
-	char *end = NULL;
-
-	if (str == NULL || *str == '\0')
-		goto err;
-	errno = 0;
-	num = strtol(str, &end, 10);
-
-	if (errno || (end && *end))
-		goto err;
-
-	return num;
-err:
-	if (errno)
-		err(EXIT_FAILURE, "%s: '%s'", errmesg, str);
-	else
-		errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
-	return 0;
-}
diff --git a/schedutils/schedutils.h b/schedutils/schedutils.h
deleted file mode 100644
index 80e4f7b..0000000
--- a/schedutils/schedutils.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef UTIL_LINUX_SCHED_UTILS
-#define UTIL_LINUX_SCHED_UTILS
-
-extern long getnum(const char *str, const char *errmesg);
-
-#endif
-
diff --git a/schedutils/taskset.c b/schedutils/taskset.c
index 201fc15..0ba099d 100644
--- a/schedutils/taskset.c
+++ b/schedutils/taskset.c
@@ -32,7 +32,7 @@
 #include "cpuset.h"
 #include "nls.h"
 
-#include "schedutils.h"
+#include "strutils.h"
 
 static void __attribute__((__noreturn__)) usage(FILE *out)
 {
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
 	while ((opt = getopt_long(argc, argv, "+pchV", longopts, NULL)) != -1) {
 		switch (opt) {
 		case 'p':
-			pid = getnum(argv[argc - 1], _("failed to parse pid"));
+			pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
 			break;
 		case 'c':
 			c_opt = 1;
diff --git a/sys-utils/Makefile.am b/sys-utils/Makefile.am
index 166d718..d3bedd4 100644
--- a/sys-utils/Makefile.am
+++ b/sys-utils/Makefile.am
@@ -33,7 +33,7 @@ info_TEXINFOS = ipc.texi
 
 if BUILD_FALLOCATE
 usrbin_exec_PROGRAMS += fallocate
-fallocate_SOURCES = fallocate.c $(top_srcdir)/lib/strtosize.c
+fallocate_SOURCES = fallocate.c $(top_srcdir)/lib/strutils.c
 dist_man_MANS += fallocate.1
 endif
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux