r460 - in devmapper/trunk: . dmeventd dmsetup include lib lib/datastruct lib/ioctl lib/mm lib/regex po

Bastian Blank waldi at alioth.debian.org
Thu May 31 21:59:43 UTC 2007


Author: waldi
Date: Thu May 31 21:59:43 2007
New Revision: 460

Log:
Merge /devmapper/upstream/current (1.02.19).


Added:
   devmapper/trunk/lib/regex/
   devmapper/trunk/lib/regex/matcher.c
   devmapper/trunk/lib/regex/parse_rx.c
   devmapper/trunk/lib/regex/parse_rx.h
   devmapper/trunk/lib/regex/ttree.c
   devmapper/trunk/lib/regex/ttree.h
Modified:
   devmapper/trunk/   (props changed)
   devmapper/trunk/VERSION
   devmapper/trunk/WHATS_NEW
   devmapper/trunk/dmeventd/dmeventd.c
   devmapper/trunk/dmeventd/libdevmapper-event.c
   devmapper/trunk/dmsetup/dmsetup.c
   devmapper/trunk/include/intl.h
   devmapper/trunk/include/kdev_t.h
   devmapper/trunk/include/lib.h
   devmapper/trunk/include/list.h
   devmapper/trunk/include/log.h
   devmapper/trunk/lib/.exported_symbols
   devmapper/trunk/lib/Makefile.in
   devmapper/trunk/lib/datastruct/bitset.h
   devmapper/trunk/lib/datastruct/hash.c
   devmapper/trunk/lib/datastruct/hash.h
   devmapper/trunk/lib/ioctl/libdm-iface.c
   devmapper/trunk/lib/libdevmapper.h
   devmapper/trunk/lib/libdm-report.c
   devmapper/trunk/lib/libdm-string.c
   devmapper/trunk/lib/mm/dbg_malloc.h
   devmapper/trunk/lib/mm/pool.h
   devmapper/trunk/po/device-mapper.po

Modified: devmapper/trunk/VERSION
==============================================================================
--- devmapper/trunk/VERSION	(original)
+++ devmapper/trunk/VERSION	Thu May 31 21:59:43 2007
@@ -1 +1 @@
-1.02.18 (2007-02-13)
+1.02.19 (2007-04-27)

Modified: devmapper/trunk/WHATS_NEW
==============================================================================
--- devmapper/trunk/WHATS_NEW	(original)
+++ devmapper/trunk/WHATS_NEW	Thu May 31 21:59:43 2007
@@ -1,3 +1,15 @@
+Version 1.02.19 - 27th April 2007
+=================================
+  Standardise protective include file #defines.
+  Add regex functions to library.
+  Avoid trailing separator in reports when there are hidden sort fields.
+  Fix segfault in 'dmsetup status' without --showkeys against crypt target.
+  Deal with some more compiler warnings.
+  Introduce _add_field() and _is_same_field() to libdm-report.c.
+  Fix some libdevmapper-event and dmeventd memory leaks.
+  Remove unnecessary memset() return value checks.
+  Fix a few leaks in reporting error paths. [1.02.15+]
+
 Version 1.02.18 - 13th February 2007
 ====================================
   Improve dmeventd messaging protocol: drain pipe and tag messages.

Modified: devmapper/trunk/dmeventd/dmeventd.c
==============================================================================
--- devmapper/trunk/dmeventd/dmeventd.c	(original)
+++ devmapper/trunk/dmeventd/dmeventd.c	Thu May 31 21:59:43 2007
@@ -226,8 +226,8 @@
 	if (!ret)
 		return NULL;
 
-	if (!memset(ret, 0, sizeof(*ret)) ||
-	    !(ret->device.uuid = dm_strdup(data->device_uuid))) {
+	memset(ret, 0, sizeof(*ret));
+	if (!(ret->device.uuid = dm_strdup(data->device_uuid))) {
 		dm_free(ret);
 		return NULL;
 	}
@@ -245,6 +245,8 @@
 
 static void _free_thread_status(struct thread_status *thread)
 {
+	if (thread->current_task)
+		dm_task_destroy(thread->current_task);
 	dm_free(thread->device.uuid);
 	dm_free(thread->device.name);
 	dm_free(thread);
@@ -258,8 +260,8 @@
 	if (!ret)
 		return NULL;
 
-	if (!memset(ret, 0, sizeof(*ret)) ||
-	    !(ret->dso_name = dm_strdup(data->dso_name))) {
+	memset(ret, 0, sizeof(*ret));
+	if (!(ret->dso_name = dm_strdup(data->dso_name))) {
 		dm_free(ret);
 		return NULL;
 	}
@@ -621,6 +623,8 @@
 	} else if (thread->events & DM_EVENT_TIMEOUT && errno == EINTR) {
 		thread->current_events |= DM_EVENT_TIMEOUT;
 		ret = DM_WAIT_INTR;
+	} else if (thread->status == DM_THREAD_SHUTDOWN && errno == EINTR) {
+		ret = DM_WAIT_FATAL;
 	} else {
 		syslog(LOG_NOTICE, "dm_task_run failed, errno = %d, %s",
 		       errno, strerror(errno));
@@ -811,11 +815,6 @@
 
 static int _terminate_thread(struct thread_status *thread)
 {
-	int ret;
-
-	if ((ret = pthread_cancel(thread->thread)))
-		return ret;
-
 	return pthread_kill(thread->thread, SIGALRM);
 }
 
@@ -1389,7 +1388,7 @@
 	message_data.msg = msg;
 	if (msg->cmd == DM_EVENT_CMD_HELLO)  {
 		ret = 0;
-		answer = dm_strdup(msg->data);
+		answer = msg->data;
 		if (answer) {
 			msg->size = dm_asprintf(&(msg->data), "%s HELLO", answer);
 			dm_free(answer);

Modified: devmapper/trunk/dmeventd/libdevmapper-event.c
==============================================================================
--- devmapper/trunk/dmeventd/libdevmapper-event.c	(original)
+++ devmapper/trunk/dmeventd/libdevmapper-event.c	Thu May 31 21:59:43 2007
@@ -359,10 +359,17 @@
 	 */
 	if (!_daemon_write(fifos, msg)) {
 		stack;
+		dm_free(msg->data);
+		msg->data = 0;
 		return -EIO;
 	}
 
 	do {
+
+		if (msg->data)
+			dm_free(msg->data);
+		msg->data = 0;
+
 		if (!_daemon_read(fifos, msg)) {
 			stack;
 			return -EIO;
@@ -548,6 +555,11 @@
 	}
 
 	ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0);
+
+	if (msg->data)
+		dm_free(msg->data);
+	msg->data = 0;
+
 	if (!ret)
 		ret = _daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
 
@@ -714,6 +726,12 @@
 
 	dm_event_handler_set_dso(dmevh, reply_dso);
 	dm_event_handler_set_event_mask(dmevh, reply_mask);
+
+	if (reply_dso)
+		dm_free(reply_dso);
+	if (reply_uuid)
+		dm_free(reply_uuid);
+
 	dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
 	if (!dmevh->dev_name) {
 		ret = -ENOMEM;
@@ -736,6 +754,10 @@
  fail:
 	if (msg.data)
 		dm_free(msg.data);
+	if (reply_dso)
+		dm_free(reply_dso);
+	if (reply_uuid)
+		dm_free(reply_uuid);
 	_dm_event_handler_clear_dev_info(dmevh);
 	dm_task_destroy(dmt);
 	return ret;

Modified: devmapper/trunk/dmsetup/dmsetup.c
==============================================================================
--- devmapper/trunk/dmsetup/dmsetup.c	(original)
+++ devmapper/trunk/dmsetup/dmsetup.c	Thu May 31 21:59:43 2007
@@ -19,7 +19,7 @@
 #define _GNU_SOURCE
 #define _FILE_OFFSET_BITS 64
 
-#include <configure.h>
+#include "configure.h"
 
 #include "libdevmapper.h"
 #include "log.h"
@@ -749,7 +749,7 @@
 	if (!_set_task_device(dmt, name, 0))
 		goto error;
 
-	if (!dm_task_add_target(dmt, 0, size, "error", ""))
+	if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
 		goto error;
 
 	if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))
@@ -962,17 +962,18 @@
 			if (data && !_switches[VERBOSE_ARG])
 				printf("%s: ", name);
 			if (target_type) {
-
-			/* Suppress encryption key */
-			if (!_switches[SHOWKEYS_ARG] &&
-			    !strcmp(target_type, "crypt")) {
-				c = params;
-				while (*c && *c != ' ')
-					c++;
-				c++;
-				while (*c && *c != ' ')
-					*c++ = '0';
-			}
+				/* Suppress encryption key */
+				if (!_switches[SHOWKEYS_ARG] &&
+				    cmd == DM_DEVICE_TABLE &&
+				    !strcmp(target_type, "crypt")) {
+					c = params;
+					while (*c && *c != ' ')
+						c++;
+					if (*c)
+						c++;
+					while (*c && *c != ' ')
+						*c++ = '0';
+				}
 				printf("%" PRIu64 " %" PRIu64 " %s %s",
 				       start, length, target_type, params);
 			}
@@ -1261,10 +1262,10 @@
 	}
 }
 
-static void _out_string(const unsigned char *str)
+static void _out_string(const char *str)
 {
 	while (*str)
-		_out_char(*str++);
+		_out_char((unsigned char) *str++);
 }
 
 /* non-negative integers only */
@@ -1502,7 +1503,7 @@
 			 struct dm_report_field *field, const void *data,
 			 void *private __attribute((unused)))
 {
-	const char *name = dm_task_get_name((struct dm_task *) data);
+	const char *name = dm_task_get_name((const struct dm_task *) data);
 
 	return dm_report_field_string(rh, field, &name);
 }
@@ -1512,7 +1513,7 @@
 			 struct dm_report_field *field,
 			 const void *data, void *private __attribute((unused)))
 {
-	const char *uuid = dm_task_get_uuid((struct dm_task *) data);
+	const char *uuid = dm_task_get_uuid((const struct dm_task *) data);
 
 	if (!uuid || !*uuid)
 		uuid = "";
@@ -1527,7 +1528,7 @@
 {
 	char buf[5];
 	const char *s = buf;
-	struct dm_info *info = (struct dm_info *) data;
+	const struct dm_info *info = data;
 
 	buf[0] = info->live_table ? 'L' : '-';
 	buf[1] = info->inactive_table ? 'I' : '-';
@@ -1767,7 +1768,7 @@
 {
 	const char *s, *end;
 	struct winsize winsz;
-	int len;
+	size_t len;
 
 	/* Symbol set default */
 	if (!strcmp(nl_langinfo(CODESET), "UTF-8"))
@@ -1823,7 +1824,7 @@
 
 	/* Truncation doesn't work well with vt100 drawing char */
 	if (_tsym != &_tsym_vt100)
-		if (ioctl(1, TIOCGWINSZ, &winsz) >= 0 && winsz.ws_col > 3)
+		if (ioctl(1, (unsigned long) TIOCGWINSZ, &winsz) >= 0 && winsz.ws_col > 3)
 			_termwidth = winsz.ws_col - 3;
 
 	return 1;
@@ -1860,13 +1861,13 @@
 		if (strncmp(device, DEV_PATH, strlen(DEV_PATH)))
 			goto error;
 
-		strncpy(buf, strrchr(device, '/') + 1, PATH_MAX);
+		strncpy(buf, strrchr(device, '/') + 1, (size_t) PATH_MAX);
 		dm_free(device);
 
 	} else {
 		/* check for device number */
 		if (!strncmp(dev, "loop", strlen("loop")))
-			strncpy(buf, dev, PATH_MAX);
+			strncpy(buf, dev, (size_t) PATH_MAX);
 		else
 			goto error;
 	}
@@ -1909,8 +1910,9 @@
 	sectors = size >> SECTOR_SHIFT;
 
 	if (_switches[VERBOSE_ARG])
-		fprintf(stderr, "losetup: set loop size to %llukB (%llu sectors)\n",
-			sectors >> 1, sectors);
+		fprintf(stderr, "losetup: set loop size to %llukB "
+			"(%llu sectors)\n", (long long unsigned) sectors >> 1,
+			(long long unsigned) sectors);
 
 #ifdef HAVE_SYS_STATVFS_H
 	if (fstatvfs(fd, &fsbuf))
@@ -2019,6 +2021,7 @@
 	if (*argc != 2) {
 		fprintf(stderr, "%s: Too few arguments\n", base);
 		_losetup_usage(stderr);
+		dm_free(device_name);
 		return 0;
 	}
 
@@ -2027,13 +2030,15 @@
 		fprintf(stderr, "%s: Could not parse loop file name %s\n",
 			base, (*argv)[1]);
 		_losetup_usage(stderr);
+		dm_free(device_name);
 		return 0;
 	}
 
 	/* FIXME Missing free */
 	_table = dm_malloc(LOOP_TABLE_SIZE);
-	if (!_loop_table(_table, LOOP_TABLE_SIZE, loop_file, device_name, offset)) {
+	if (!_loop_table(_table, (size_t) LOOP_TABLE_SIZE, loop_file, device_name, offset)) {
 		fprintf(stderr, "Could not build device-mapper table for %s\n", (*argv)[0]);
+		dm_free(device_name);
 		return 0;
 	}
 	_switches[TABLE_ARG]++;

Modified: devmapper/trunk/include/intl.h
==============================================================================
--- devmapper/trunk/include/intl.h	(original)
+++ devmapper/trunk/include/intl.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_INTL_H
-#define _LVM_INTL_H
+#ifndef _DM_INTL_H
+#define _DM_INTL_H
 
 #ifdef INTL_PACKAGE
 #  include <libintl.h>

Modified: devmapper/trunk/include/kdev_t.h
==============================================================================
--- devmapper/trunk/include/kdev_t.h	(original)
+++ devmapper/trunk/include/kdev_t.h	Thu May 31 21:59:43 2007
@@ -12,8 +12,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_KDEV_H
-#define _LVM_KDEV_H
+#ifndef _DM_KDEV_H
+#define _DM_KDEV_H
 
 #define MAJOR(dev)      ((dev & 0xfff00) >> 8)
 #define MINOR(dev)      ((dev & 0xff) | ((dev >> 12) & 0xfff00))

Modified: devmapper/trunk/include/lib.h
==============================================================================
--- devmapper/trunk/include/lib.h	(original)
+++ devmapper/trunk/include/lib.h	Thu May 31 21:59:43 2007
@@ -16,8 +16,8 @@
 /*
  * This file must be included first by every library source file.
  */
-#ifndef _LVM_LIB_H
-#define _LVM_LIB_H
+#ifndef _DM_LIB_H
+#define _DM_LIB_H
 
 #define _REENTRANT
 #define _GNU_SOURCE

Modified: devmapper/trunk/include/list.h
==============================================================================
--- devmapper/trunk/include/list.h	(original)
+++ devmapper/trunk/include/list.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_LIST_H
-#define _LVM_LIST_H
+#ifndef _DM_LIST_H
+#define _DM_LIST_H
 
 #include <assert.h>
 #include <stdio.h>

Modified: devmapper/trunk/include/log.h
==============================================================================
--- devmapper/trunk/include/log.h	(original)
+++ devmapper/trunk/include/log.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef LIB_DMLOG_H
-#define LIB_DMLOG_H
+#ifndef _DM_LOG_H
+#define _DM_LOG_H
 
 #include "libdevmapper.h"
 
@@ -40,5 +40,6 @@
 #define return_0	do { stack; return 0; } while (0)
 #define return_NULL	do { stack; return NULL; } while (0)
 #define goto_out	do { stack; goto out; } while (0)
+#define goto_bad	do { stack; goto bad; } while (0)
 
 #endif

Modified: devmapper/trunk/lib/.exported_symbols
==============================================================================
--- devmapper/trunk/lib/.exported_symbols	(original)
+++ devmapper/trunk/lib/.exported_symbols	Thu May 31 21:59:43 2007
@@ -127,3 +127,5 @@
 dm_report_field_uint32
 dm_report_field_uint64
 dm_report_field_set_value
+dm_regex_create
+dm_regex_match

Modified: devmapper/trunk/lib/Makefile.in
==============================================================================
--- devmapper/trunk/lib/Makefile.in	(original)
+++ devmapper/trunk/lib/Makefile.in	Thu May 31 21:59:43 2007
@@ -27,6 +27,9 @@
 	libdm-report.c \
 	mm/dbg_malloc.c \
 	mm/pool.c \
+	regex/matcher.c \
+	regex/parse_rx.c \
+	regex/ttree.c \
 	$(interface)/libdm-iface.c
 
 INCLUDES = -I$(interface)

Modified: devmapper/trunk/lib/datastruct/bitset.h
==============================================================================
--- devmapper/trunk/lib/datastruct/bitset.h	(original)
+++ devmapper/trunk/lib/datastruct/bitset.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_BITSET_H
-#define _LVM_BITSET_H
+#ifndef _DM_BITSET_H
+#define _DM_BITSET_H
 
 #include "pool.h"
 

Modified: devmapper/trunk/lib/datastruct/hash.c
==============================================================================
--- devmapper/trunk/lib/datastruct/hash.c	(original)
+++ devmapper/trunk/lib/datastruct/hash.c	Thu May 31 21:59:43 2007
@@ -68,14 +68,14 @@
 	return n;
 }
 
-static unsigned long _hash(const unsigned char *str, unsigned len)
+static unsigned long _hash(const char *str, unsigned len)
 {
 	unsigned long h = 0, g;
 	unsigned i;
 
 	for (i = 0; i < len; i++) {
 		h <<= 4;
-		h += _nums[*str++];
+		h += _nums[(unsigned char) *str++];
 		g = h & ((unsigned long) 0xf << 16u);
 		if (g) {
 			h ^= g >> 16u;

Modified: devmapper/trunk/lib/datastruct/hash.h
==============================================================================
--- devmapper/trunk/lib/datastruct/hash.h	(original)
+++ devmapper/trunk/lib/datastruct/hash.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_HASH_H
-#define _LVM_HASH_H
+#ifndef _DM_HASH_H
+#define _DM_HASH_H
 
 struct hash_table;
 struct hash_node;

Modified: devmapper/trunk/lib/ioctl/libdm-iface.c
==============================================================================
--- devmapper/trunk/lib/ioctl/libdm-iface.c	(original)
+++ devmapper/trunk/lib/ioctl/libdm-iface.c	Thu May 31 21:59:43 2007
@@ -433,12 +433,12 @@
 	return 1;
 }
 
-static const char *_dm_task_get_name_v1(struct dm_task *dmt)
+static const char *_dm_task_get_name_v1(const struct dm_task *dmt)
 {
 	return (dmt->dmi.v1->name);
 }
 
-static const char *_dm_task_get_uuid_v1(struct dm_task *dmt)
+static const char *_dm_task_get_uuid_v1(const struct dm_task *dmt)
 {
 	return (dmt->dmi.v1->uuid);
 }
@@ -924,7 +924,7 @@
 	return 1;
 }
 
-const char *dm_task_get_name(struct dm_task *dmt)
+const char *dm_task_get_name(const struct dm_task *dmt)
 {
 #ifdef DM_COMPAT
 	if (_dm_version == 1)
@@ -934,7 +934,7 @@
 	return (dmt->dmi.v4->name);
 }
 
-const char *dm_task_get_uuid(struct dm_task *dmt)
+const char *dm_task_get_uuid(const struct dm_task *dmt)
 {
 #ifdef DM_COMPAT
 	if (_dm_version == 1)
@@ -1555,7 +1555,7 @@
 		dmi->flags |= DM_SKIP_BDGET_FLAG;
 
 	log_debug("dm %s %s %s%s%s %s%.0d%s%.0d%s"
-		  "%s%c%c%s %.0llu %s [%u]",
+		  "%s%c%c%s %.0" PRIu64 " %s [%u]",
 		  _cmd_data_v4[dmt->type].name,
 		  dmi->name, dmi->uuid, dmt->newname ? " " : "",
 		  dmt->newname ? dmt->newname : "",

Modified: devmapper/trunk/lib/libdevmapper.h
==============================================================================
--- devmapper/trunk/lib/libdevmapper.h	(original)
+++ devmapper/trunk/lib/libdevmapper.h	Thu May 31 21:59:43 2007
@@ -133,8 +133,8 @@
 int dm_get_library_version(char *version, size_t size);
 int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size);
 int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi);
-const char *dm_task_get_name(struct dm_task *dmt);
-const char *dm_task_get_uuid(struct dm_task *dmt);
+const char *dm_task_get_name(const struct dm_task *dmt);
+const char *dm_task_get_uuid(const struct dm_task *dmt);
 
 struct dm_deps *dm_task_get_deps(struct dm_task *dmt);
 struct dm_names *dm_task_get_names(struct dm_task *dmt);
@@ -631,6 +631,25 @@
 int dm_asprintf(char **buf, const char *format, ...);
 
 /*********************
+ * regular expressions
+ *********************/
+struct dm_regex;
+
+/*
+ * Initialise an array of num patterns for matching.
+ * Uses memory from mem.
+ */
+struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
+				 unsigned num_patterns);
+
+/*
+ * Match string s against the patterns.
+ * Returns the index of the highest pattern in the array that matches,
+ * or -1 if none match.
+ */
+int dm_regex_match(struct dm_regex *regex, const char *s);
+
+/*********************
  * reporting functions
  *********************/
 

Modified: devmapper/trunk/lib/libdm-report.c
==============================================================================
--- devmapper/trunk/lib/libdm-report.c	(original)
+++ devmapper/trunk/lib/libdm-report.c	Thu May 31 21:59:43 2007
@@ -296,36 +296,75 @@
 	return 1;
 }
 
-static int _field_match(struct dm_report *rh, const char *field, size_t flen)
+static struct field_properties * _add_field(struct dm_report *rh,
+					    uint32_t field_num, uint32_t flags)
 {
-	uint32_t f, l;
 	struct field_properties *fp;
 
-	if (!flen)
-		return 0;
+	rh->report_types |= rh->fields[field_num].type;
 
-	for (f = 0; rh->fields[f].report_fn; f++) {
-		if ((!strncasecmp(rh->fields[f].id, field, flen) &&
-		     strlen(rh->fields[f].id) == flen) ||
-		    (l = strlen(rh->field_prefix),
-		     !strncasecmp(rh->field_prefix, rh->fields[f].id, l) &&
-		     !strncasecmp(rh->fields[f].id + l, field, flen) &&
-		     strlen(rh->fields[f].id) == l + flen)) {
-			rh->report_types |= rh->fields[f].type;
-			if (!(fp = dm_pool_zalloc(rh->mem, sizeof(*fp)))) {
-				log_error("dm_report: "
-					  "struct field_properties allocation "
-					  "failed");
-				return 0;
-			}
-			if (!_copy_field(rh, fp, f))
-				return 0;
+	if (!(fp = dm_pool_zalloc(rh->mem, sizeof(struct field_properties)))) {
+		log_error("dm_report: struct field_properties allocation "
+			  "failed");
+		return NULL;
+	}
 
-			list_add(&rh->field_props, &fp->list);
-			return 1;
-		}
+	if (!_copy_field(rh, fp, field_num)) {
+		stack;
+		dm_pool_free(rh->mem, fp);
+		return NULL;
 	}
 
+	fp->flags |= flags;
+
+	/*
+	 * Place hidden fields at the front so list_end() will
+	 * tell us when we've reached the last visible field.
+	 */
+	if (fp->flags & FLD_HIDDEN)
+		list_add_h(&rh->field_props, &fp->list);
+	else
+		list_add(&rh->field_props, &fp->list);
+
+	return fp;
+}
+
+/*
+ * Compare name1 against name2 or prefix plus name2
+ * name2 is not necessarily null-terminated.
+ * len2 is the length of name2.
+ */
+static int _is_same_field(const char *name1, const char *name2,
+			  size_t len2, const char *prefix)
+{
+	size_t prefix_len;
+
+	/* Exact match? */
+	if (!strncasecmp(name1, name2, len2) && strlen(name1) == len2)
+		return 1;
+
+	/* Match including prefix? */
+	prefix_len = strlen(prefix);
+	if (!strncasecmp(prefix, name1, prefix_len) &&
+	    !strncasecmp(name1 + prefix_len, name2, len2) &&
+	    strlen(name1) == prefix_len + len2)
+		return 1;
+
+	return 0;
+}
+
+static int _field_match(struct dm_report *rh, const char *field, size_t flen)
+{
+	uint32_t f;
+
+	if (!flen)
+		return 0;
+
+	for (f = 0; rh->fields[f].report_fn; f++)
+		if (_is_same_field(rh->fields[f].id, field, flen,
+				   rh->field_prefix))
+			return _add_field(rh, f, 0) ? 1 : 0;
+
 	return 0;
 }
 
@@ -341,21 +380,8 @@
 		}
 	}
 
-	if (!found) {
-		rh->report_types |= rh->fields[field_num].type;
-		if (!(found = dm_pool_zalloc(rh->mem, sizeof(*found)))) {
-			log_error("dm_report: "
-				  "struct field_properties allocation failed");
-			return 0;
-		}
-		if (!_copy_field(rh, found, field_num))
-			return 0;
-
-		/* Add as a non-display field */
-		found->flags |= FLD_HIDDEN;
-
-		list_add(&rh->field_props, &found->list);
-	}
+	if (!found && !(found = _add_field(rh, field_num, FLD_HIDDEN)))
+		return_0;
 
 	if (found->flags & FLD_SORT_KEY) {
 		log_error("dm_report: Ignoring duplicate sort field: %s",
@@ -372,7 +398,7 @@
 
 static int _key_match(struct dm_report *rh, const char *key, size_t len)
 {
-	uint32_t f, l;
+	uint32_t f;
 	uint32_t flags;
 
 	if (!len)
@@ -394,16 +420,10 @@
 		return 0;
 	}
 
-	for (f = 0; rh->fields[f].report_fn; f++) {
-		if ((!strncasecmp(rh->fields[f].id, key, len) &&
-		     strlen(rh->fields[f].id) == len) ||
-		    (l = strlen(rh->field_prefix),
-		     !strncasecmp(rh->field_prefix, rh->fields[f].id, l) &&
-		     !strncasecmp(rh->fields[f].id + l, key, len) &&
-		     strlen(rh->fields[f].id) == l + len)) {
+	for (f = 0; rh->fields[f].report_fn; f++)
+		if (_is_same_field(rh->fields[f].id, key, len,
+				   rh->field_prefix))
 			return _add_sort_key(rh, f, flags);
-		}
-	}
 
 	return 0;
 }
@@ -504,15 +524,20 @@
 
 	if (!(rh->mem = dm_pool_create("report", 10 * 1024))) {
 		log_error("dm_report_init: allocation of memory pool failed");
+		dm_free(rh);
 		return NULL;
 	}
 
 	/* Generate list of fields for output based on format string & flags */
-	if (!_parse_options(rh, output_fields))
+	if (!_parse_options(rh, output_fields)) {
+		dm_report_free(rh);
 		return NULL;
+	}
 
-	if (!_parse_keys(rh, sort_keys))
+	if (!_parse_keys(rh, sort_keys)) {
+		dm_report_free(rh);
 		return NULL;
+	}
 
 	/* Return updated types value for further compatility check by caller */
 	if (report_types)

Modified: devmapper/trunk/lib/libdm-string.c
==============================================================================
--- devmapper/trunk/lib/libdm-string.c	(original)
+++ devmapper/trunk/lib/libdm-string.c	Thu May 31 21:59:43 2007
@@ -117,7 +117,7 @@
 	n = vsnprintf(buf, bufsize, format, ap);
 	va_end(ap);
 
-	if (n < 0 || (n > bufsize - 1))
+	if (n < 0 || ((unsigned) n + 1 > bufsize))
 		return -1;
 
 	return n;

Modified: devmapper/trunk/lib/mm/dbg_malloc.h
==============================================================================
--- devmapper/trunk/lib/mm/dbg_malloc.h	(original)
+++ devmapper/trunk/lib/mm/dbg_malloc.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_DBG_MALLOC_H
-#define _LVM_DBG_MALLOC_H
+#ifndef _DM_DBG_MALLOC_H
+#define _DM_DBG_MALLOC_H
 
 #include <stdlib.h>
 #include <string.h>

Modified: devmapper/trunk/lib/mm/pool.h
==============================================================================
--- devmapper/trunk/lib/mm/pool.h	(original)
+++ devmapper/trunk/lib/mm/pool.h	Thu May 31 21:59:43 2007
@@ -13,8 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LVM_POOL_H
-#define _LVM_POOL_H
+#ifndef _DM_POOL_H
+#define _DM_POOL_H
 
 #include <string.h>
 #include <stdlib.h>

Added: devmapper/trunk/lib/regex/matcher.c
==============================================================================
--- (empty file)
+++ devmapper/trunk/lib/regex/matcher.c	Thu May 31 21:59:43 2007
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "parse_rx.h"
+#include "ttree.h"
+#include "assert.h"
+
+struct dfa_state {
+	int final;
+	struct dfa_state *lookup[256];
+};
+
+struct state_queue {
+	struct dfa_state *s;
+	dm_bitset_t bits;
+	struct state_queue *next;
+};
+
+struct dm_regex {		/* Instance variables for the lexer */
+	struct dfa_state *start;
+	unsigned num_nodes;
+	int nodes_entered;
+	struct rx_node **nodes;
+	struct dm_pool *scratch, *mem;
+};
+
+#define TARGET_TRANS '\0'
+
+static int _count_nodes(struct rx_node *rx)
+{
+	int r = 1;
+
+	if (rx->left)
+		r += _count_nodes(rx->left);
+
+	if (rx->right)
+		r += _count_nodes(rx->right);
+
+	return r;
+}
+
+static void _fill_table(struct dm_regex *m, struct rx_node *rx)
+{
+	assert((rx->type != OR) || (rx->left && rx->right));
+
+	if (rx->left)
+		_fill_table(m, rx->left);
+
+	if (rx->right)
+		_fill_table(m, rx->right);
+
+	m->nodes[m->nodes_entered++] = rx;
+}
+
+static void _create_bitsets(struct dm_regex *m)
+{
+	int i;
+
+	for (i = 0; i < m->num_nodes; i++) {
+		struct rx_node *n = m->nodes[i];
+		n->firstpos = dm_bitset_create(m->scratch, m->num_nodes);
+		n->lastpos = dm_bitset_create(m->scratch, m->num_nodes);
+		n->followpos = dm_bitset_create(m->scratch, m->num_nodes);
+	}
+}
+
+static void _calc_functions(struct dm_regex *m)
+{
+	int i, j, final = 1;
+	struct rx_node *rx, *c1, *c2;
+
+	for (i = 0; i < m->num_nodes; i++) {
+		rx = m->nodes[i];
+		c1 = rx->left;
+		c2 = rx->right;
+
+		if (dm_bit(rx->charset, TARGET_TRANS))
+			rx->final = final++;
+
+		switch (rx->type) {
+		case CAT:
+			if (c1->nullable)
+				dm_bit_union(rx->firstpos,
+					  c1->firstpos, c2->firstpos);
+			else
+				dm_bit_copy(rx->firstpos, c1->firstpos);
+
+			if (c2->nullable)
+				dm_bit_union(rx->lastpos,
+					  c1->lastpos, c2->lastpos);
+			else
+				dm_bit_copy(rx->lastpos, c2->lastpos);
+
+			rx->nullable = c1->nullable && c2->nullable;
+			break;
+
+		case PLUS:
+			dm_bit_copy(rx->firstpos, c1->firstpos);
+			dm_bit_copy(rx->lastpos, c1->lastpos);
+			rx->nullable = c1->nullable;
+			break;
+
+		case OR:
+			dm_bit_union(rx->firstpos, c1->firstpos, c2->firstpos);
+			dm_bit_union(rx->lastpos, c1->lastpos, c2->lastpos);
+			rx->nullable = c1->nullable || c2->nullable;
+			break;
+
+		case QUEST:
+		case STAR:
+			dm_bit_copy(rx->firstpos, c1->firstpos);
+			dm_bit_copy(rx->lastpos, c1->lastpos);
+			rx->nullable = 1;
+			break;
+
+		case CHARSET:
+			dm_bit_set(rx->firstpos, i);
+			dm_bit_set(rx->lastpos, i);
+			rx->nullable = 0;
+			break;
+
+		default:
+			log_error("Internal error: Unknown calc node type");
+		}
+
+		/*
+		 * followpos has it's own switch
+		 * because PLUS and STAR do the
+		 * same thing.
+		 */
+		switch (rx->type) {
+		case CAT:
+			for (j = 0; j < m->num_nodes; j++) {
+				if (dm_bit(c1->lastpos, j)) {
+					struct rx_node *n = m->nodes[j];
+					dm_bit_union(n->followpos,
+						  n->followpos, c2->firstpos);
+				}
+			}
+			break;
+
+		case PLUS:
+		case STAR:
+			for (j = 0; j < m->num_nodes; j++) {
+				if (dm_bit(rx->lastpos, j)) {
+					struct rx_node *n = m->nodes[j];
+					dm_bit_union(n->followpos,
+						  n->followpos, rx->firstpos);
+				}
+			}
+			break;
+		}
+	}
+}
+
+static struct dfa_state *_create_dfa_state(struct dm_pool *mem)
+{
+	return dm_pool_zalloc(mem, sizeof(struct dfa_state));
+}
+
+static struct state_queue *_create_state_queue(struct dm_pool *mem,
+					       struct dfa_state *dfa,
+					       dm_bitset_t bits)
+{
+	struct state_queue *r = dm_pool_alloc(mem, sizeof(*r));
+
+	if (!r) {
+		stack;
+		return NULL;
+	}
+
+	r->s = dfa;
+	r->bits = dm_bitset_create(mem, bits[0]);	/* first element is the size */
+	dm_bit_copy(r->bits, bits);
+	r->next = 0;
+	return r;
+}
+
+static int _calc_states(struct dm_regex *m, struct rx_node *rx)
+{
+	unsigned iwidth = (m->num_nodes / DM_BITS_PER_INT) + 1;
+	struct ttree *tt = ttree_create(m->scratch, iwidth);
+	struct state_queue *h, *t, *tmp;
+	struct dfa_state *dfa, *ldfa;
+	int i, a, set_bits = 0, count = 0;
+	dm_bitset_t bs, dfa_bits;
+
+	if (!tt)
+		return_0;
+
+	if (!(bs = dm_bitset_create(m->scratch, m->num_nodes)))
+		return_0;
+
+	/* create first state */
+	dfa = _create_dfa_state(m->mem);
+	m->start = dfa;
+	ttree_insert(tt, rx->firstpos + 1, dfa);
+
+	/* prime the queue */
+	h = t = _create_state_queue(m->scratch, dfa, rx->firstpos);
+	while (h) {
+		/* pop state off front of the queue */
+		dfa = h->s;
+		dfa_bits = h->bits;
+		h = h->next;
+
+		/* iterate through all the inputs for this state */
+		dm_bit_clear_all(bs);
+		for (a = 0; a < 256; a++) {
+			/* iterate through all the states in firstpos */
+			for (i = dm_bit_get_first(dfa_bits);
+			     i >= 0; i = dm_bit_get_next(dfa_bits, i)) {
+				if (dm_bit(m->nodes[i]->charset, a)) {
+					if (a == TARGET_TRANS)
+						dfa->final = m->nodes[i]->final;
+
+					dm_bit_union(bs, bs,
+						  m->nodes[i]->followpos);
+					set_bits = 1;
+				}
+			}
+
+			if (set_bits) {
+				ldfa = ttree_lookup(tt, bs + 1);
+				if (!ldfa) {
+					/* push */
+					ldfa = _create_dfa_state(m->mem);
+					ttree_insert(tt, bs + 1, ldfa);
+					tmp =
+					    _create_state_queue(m->scratch,
+								ldfa, bs);
+					if (!h)
+						h = t = tmp;
+					else {
+						t->next = tmp;
+						t = tmp;
+					}
+
+					count++;
+				}
+
+				dfa->lookup[a] = ldfa;
+				set_bits = 0;
+				dm_bit_clear_all(bs);
+			}
+		}
+	}
+
+	log_debug("Matcher built with %d dfa states", count);
+	return 1;
+}
+
+struct dm_regex *dm_regex_create(struct dm_pool *mem, const char **patterns,
+				 unsigned num_patterns)
+{
+	char *all, *ptr;
+	int i;
+	size_t len = 0;
+	struct rx_node *rx;
+	struct dm_pool *scratch = dm_pool_create("regex matcher", 10 * 1024);
+	struct dm_regex *m;
+
+	if (!scratch)
+		return_NULL;
+
+	if (!(m = dm_pool_alloc(mem, sizeof(*m)))) {
+		dm_pool_destroy(scratch);
+		return_NULL;
+	}
+
+	memset(m, 0, sizeof(*m));
+
+	/* join the regexps together, delimiting with zero */
+	for (i = 0; i < num_patterns; i++)
+		len += strlen(patterns[i]) + 8;
+
+	ptr = all = dm_pool_alloc(scratch, len + 1);
+
+	if (!all)
+		goto_bad;
+
+	for (i = 0; i < num_patterns; i++) {
+		ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], TARGET_TRANS);
+		if (i < (num_patterns - 1))
+			*ptr++ = '|';
+	}
+
+	/* parse this expression */
+	if (!(rx = rx_parse_tok(scratch, all, ptr))) {
+		log_error("Couldn't parse regex");
+		goto bad;
+	}
+
+	m->mem = mem;
+	m->scratch = scratch;
+	m->num_nodes = _count_nodes(rx);
+	m->nodes = dm_pool_alloc(scratch, sizeof(*m->nodes) * m->num_nodes);
+
+	if (!m->nodes)
+		goto_bad;
+
+	_fill_table(m, rx);
+	_create_bitsets(m);
+	_calc_functions(m);
+	_calc_states(m, rx);
+	dm_pool_destroy(scratch);
+	m->scratch = NULL;
+
+	return m;
+
+      bad:
+	dm_pool_destroy(scratch);
+	dm_pool_free(mem, m);
+	return NULL;
+}
+
+static struct dfa_state *_step_matcher(int c, struct dfa_state *cs, int *r)
+{
+	if (!(cs = cs->lookup[(unsigned char) c]))
+		return NULL;
+
+	if (cs->final && (cs->final > *r))
+		*r = cs->final;
+
+	return cs;
+}
+
+int dm_regex_match(struct dm_regex *regex, const char *s)
+{
+	struct dfa_state *cs = regex->start;
+	int r = 0;
+
+	if (!(cs = _step_matcher(HAT_CHAR, cs, &r)))
+		goto out;
+
+	for (; *s; s++)
+		if (!(cs = _step_matcher(*s, cs, &r)))
+			goto out;
+
+	_step_matcher(DOLLAR_CHAR, cs, &r);
+
+      out:
+	/* subtract 1 to get back to zero index */
+	return r - 1;
+}

Added: devmapper/trunk/lib/regex/parse_rx.c
==============================================================================
--- (empty file)
+++ devmapper/trunk/lib/regex/parse_rx.c	Thu May 31 21:59:43 2007
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "parse_rx.h"
+
+struct parse_sp {		/* scratch pad for the parsing process */
+	struct dm_pool *mem;
+	int type;		/* token type, 0 indicates a charset */
+	dm_bitset_t charset;	/* The current charset */
+	const char *cursor;	/* where we are in the regex */
+	const char *rx_end;	/* 1pte for the expression being parsed */
+};
+
+static struct rx_node *_or_term(struct parse_sp *ps);
+
+static void _single_char(struct parse_sp *ps, unsigned int c, const char *ptr)
+{
+	ps->type = 0;
+	ps->cursor = ptr + 1;
+	dm_bit_clear_all(ps->charset);
+	dm_bit_set(ps->charset, c);
+}
+
+/*
+ * Get the next token from the regular expression.
+ * Returns: 1 success, 0 end of input, -1 error.
+ */
+static int _rx_get_token(struct parse_sp *ps)
+{
+	int neg = 0, range = 0;
+	char c, lc = 0;
+	const char *ptr = ps->cursor;
+	if (ptr == ps->rx_end) {	/* end of input ? */
+		ps->type = -1;
+		return 0;
+	}
+
+	switch (*ptr) {
+		/* charsets and ncharsets */
+	case '[':
+		ptr++;
+		if (*ptr == '^') {
+			dm_bit_set_all(ps->charset);
+
+			/* never transition on zero */
+			dm_bit_clear(ps->charset, 0);
+			neg = 1;
+			ptr++;
+
+		} else
+			dm_bit_clear_all(ps->charset);
+
+		while ((ptr < ps->rx_end) && (*ptr != ']')) {
+			if (*ptr == '\\') {
+				/* an escaped character */
+				ptr++;
+				switch (*ptr) {
+				case 'n':
+					c = '\n';
+					break;
+				case 'r':
+					c = '\r';
+					break;
+				case 't':
+					c = '\t';
+					break;
+				default:
+					c = *ptr;
+				}
+			} else if (*ptr == '-' && lc) {
+				/* we've got a range on our hands */
+				range = 1;
+				ptr++;
+				if (ptr == ps->rx_end) {
+					log_error("Incomplete range"
+						  "specification");
+					return -1;
+				}
+				c = *ptr;
+			} else
+				c = *ptr;
+
+			if (range) {
+				/* add lc - c into the bitset */
+				if (lc > c) {
+					char tmp = c;
+					c = lc;
+					lc = tmp;
+				}
+
+				for (; lc <= c; lc++) {
+					if (neg)
+						dm_bit_clear(ps->charset, lc);
+					else
+						dm_bit_set(ps->charset, lc);
+				}
+				range = 0;
+			} else {
+				/* add c into the bitset */
+				if (neg)
+					dm_bit_clear(ps->charset, c);
+				else
+					dm_bit_set(ps->charset, c);
+			}
+			ptr++;
+			lc = c;
+		}
+
+		if (ptr >= ps->rx_end) {
+			ps->type = -1;
+			return -1;
+		}
+
+		ps->type = 0;
+		ps->cursor = ptr + 1;
+		break;
+
+		/* These characters are special, we just return their ASCII
+		   codes as the type.  Sorted into ascending order to help the
+		   compiler */
+	case '(':
+	case ')':
+	case '*':
+	case '+':
+	case '?':
+	case '|':
+		ps->type = (int) *ptr;
+		ps->cursor = ptr + 1;
+		break;
+
+	case '^':
+		_single_char(ps, HAT_CHAR, ptr);
+		break;
+
+	case '$':
+		_single_char(ps, DOLLAR_CHAR, ptr);
+		break;
+
+	case '.':
+		/* The 'all but newline' character set */
+		ps->type = 0;
+		ps->cursor = ptr + 1;
+		dm_bit_set_all(ps->charset);
+		dm_bit_clear(ps->charset, (int) '\n');
+		dm_bit_clear(ps->charset, (int) '\r');
+		dm_bit_clear(ps->charset, 0);
+		break;
+
+	case '\\':
+		/* escaped character */
+		ptr++;
+		if (ptr >= ps->rx_end) {
+			log_error("Badly quoted character at end "
+				  "of expression");
+			ps->type = -1;
+			return -1;
+		}
+
+		ps->type = 0;
+		ps->cursor = ptr + 1;
+		dm_bit_clear_all(ps->charset);
+		switch (*ptr) {
+		case 'n':
+			dm_bit_set(ps->charset, (int) '\n');
+			break;
+		case 'r':
+			dm_bit_set(ps->charset, (int) '\r');
+			break;
+		case 't':
+			dm_bit_set(ps->charset, (int) '\t');
+			break;
+		default:
+			dm_bit_set(ps->charset, (int) *ptr);
+		}
+		break;
+
+	default:
+		/* add a single character to the bitset */
+		ps->type = 0;
+		ps->cursor = ptr + 1;
+		dm_bit_clear_all(ps->charset);
+		dm_bit_set(ps->charset, (int) *ptr);
+		break;
+	}
+
+	return 1;
+}
+
+static struct rx_node *_node(struct dm_pool *mem, int type,
+			     struct rx_node *l, struct rx_node *r)
+{
+	struct rx_node *n = dm_pool_zalloc(mem, sizeof(*n));
+
+	if (n) {
+		if (!(n->charset = dm_bitset_create(mem, 256))) {
+			dm_pool_free(mem, n);
+			return NULL;
+		}
+
+		n->type = type;
+		n->left = l;
+		n->right = r;
+	}
+
+	return n;
+}
+
+static struct rx_node *_term(struct parse_sp *ps)
+{
+	struct rx_node *n;
+
+	switch (ps->type) {
+	case 0:
+		if (!(n = _node(ps->mem, CHARSET, NULL, NULL))) {
+			stack;
+			return NULL;
+		}
+
+		dm_bit_copy(n->charset, ps->charset);
+		_rx_get_token(ps);	/* match charset */
+		break;
+
+	case '(':
+		_rx_get_token(ps);	/* match '(' */
+		n = _or_term(ps);
+		if (ps->type != ')') {
+			log_error("missing ')' in regular expression");
+			return 0;
+		}
+		_rx_get_token(ps);	/* match ')' */
+		break;
+
+	default:
+		n = 0;
+	}
+
+	return n;
+}
+
+static struct rx_node *_closure_term(struct parse_sp *ps)
+{
+	struct rx_node *l, *n;
+
+	if (!(l = _term(ps)))
+		return NULL;
+
+	for (;;) {
+		switch (ps->type) {
+		case '*':
+			n = _node(ps->mem, STAR, l, NULL);
+			break;
+
+		case '+':
+			n = _node(ps->mem, PLUS, l, NULL);
+			break;
+
+		case '?':
+			n = _node(ps->mem, QUEST, l, NULL);
+			break;
+
+		default:
+			return l;
+		}
+
+		if (!n) {
+			stack;
+			return NULL;
+		}
+
+		_rx_get_token(ps);
+		l = n;
+	}
+
+	return n;
+}
+
+static struct rx_node *_cat_term(struct parse_sp *ps)
+{
+	struct rx_node *l, *r, *n;
+
+	if (!(l = _closure_term(ps)))
+		return NULL;
+
+	if (ps->type == '|')
+		return l;
+
+	if (!(r = _cat_term(ps)))
+		return l;
+
+	if (!(n = _node(ps->mem, CAT, l, r)))
+		stack;
+
+	return n;
+}
+
+static struct rx_node *_or_term(struct parse_sp *ps)
+{
+	struct rx_node *l, *r, *n;
+
+	if (!(l = _cat_term(ps)))
+		return NULL;
+
+	if (ps->type != '|')
+		return l;
+
+	_rx_get_token(ps);		/* match '|' */
+
+	if (!(r = _or_term(ps))) {
+		log_error("Badly formed 'or' expression");
+		return NULL;
+	}
+
+	if (!(n = _node(ps->mem, OR, l, r)))
+		stack;
+
+	return n;
+}
+
+struct rx_node *rx_parse_tok(struct dm_pool *mem,
+			     const char *begin, const char *end)
+{
+	struct rx_node *r;
+	struct parse_sp *ps = dm_pool_zalloc(mem, sizeof(*ps));
+
+	if (!ps) {
+		stack;
+		return NULL;
+	}
+
+	ps->mem = mem;
+	ps->charset = dm_bitset_create(mem, 256);
+	ps->cursor = begin;
+	ps->rx_end = end;
+	_rx_get_token(ps);		/* load the first token */
+
+	if (!(r = _or_term(ps))) {
+		log_error("Parse error in regex");
+		dm_pool_free(mem, ps);
+	}
+
+	return r;
+}
+
+struct rx_node *rx_parse_str(struct dm_pool *mem, const char *str)
+{
+	return rx_parse_tok(mem, str, str + strlen(str));
+}

Added: devmapper/trunk/lib/regex/parse_rx.h
==============================================================================
--- (empty file)
+++ devmapper/trunk/lib/regex/parse_rx.h	Thu May 31 21:59:43 2007
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _DM_PARSE_REGEX_H
+#define _DM_PARSE_REGEX_H
+
+enum {
+	CAT,
+	STAR,
+	PLUS,
+	OR,
+	QUEST,
+	CHARSET
+};
+
+/*
+ * We're never going to be running the regex on non-printable
+ * chars, so we can use a couple of these chars to represent the
+ * start and end of a string.
+ */
+#define HAT_CHAR 0x2
+#define DOLLAR_CHAR 0x3
+
+struct rx_node {
+	int type;
+	dm_bitset_t charset;
+	struct rx_node *left, *right;
+
+	/* used to build the dfa for the toker */
+	int nullable, final;
+	dm_bitset_t firstpos;
+	dm_bitset_t lastpos;
+	dm_bitset_t followpos;
+};
+
+struct rx_node *rx_parse_str(struct dm_pool *mem, const char *str);
+struct rx_node *rx_parse_tok(struct dm_pool *mem,
+			     const char *begin, const char *end);
+
+#endif

Added: devmapper/trunk/lib/regex/ttree.c
==============================================================================
--- (empty file)
+++ devmapper/trunk/lib/regex/ttree.c	Thu May 31 21:59:43 2007
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "ttree.h"
+
+struct node {
+	unsigned k;
+	struct node *l, *m, *r;
+	void *data;
+};
+
+struct ttree {
+	int klen;
+	struct dm_pool *mem;
+	struct node *root;
+};
+
+static struct node **_lookup_single(struct node **c, unsigned int k)
+{
+	while (*c) {
+		if (k < (*c)->k)
+			c = &((*c)->l);
+
+		else if (k > (*c)->k)
+			c = &((*c)->r);
+
+		else {
+			c = &((*c)->m);
+			break;
+		}
+	}
+
+	return c;
+}
+
+void *ttree_lookup(struct ttree *tt, unsigned *key)
+{
+	struct node **c = &tt->root;
+	int count = tt->klen;
+
+	while (*c && count) {
+		c = _lookup_single(c, *key++);
+		count--;
+	}
+
+	return *c ? (*c)->data : NULL;
+}
+
+static struct node *_tree_node(struct dm_pool *mem, unsigned int k)
+{
+	struct node *n = dm_pool_zalloc(mem, sizeof(*n));
+
+	if (n)
+		n->k = k;
+
+	return n;
+}
+
+int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
+{
+	struct node **c = &tt->root;
+	int count = tt->klen;
+	unsigned int k;
+
+	do {
+		k = *key++;
+		c = _lookup_single(c, k);
+		count--;
+
+	} while (*c && count);
+
+	if (!*c) {
+		count++;
+
+		while (count--) {
+			if (!(*c = _tree_node(tt->mem, k))) {
+				stack;
+				return 0;
+			}
+
+			k = *key++;
+
+			if (count)
+				c = &((*c)->m);
+		}
+	}
+	(*c)->data = data;
+
+	return 1;
+}
+
+struct ttree *ttree_create(struct dm_pool *mem, unsigned int klen)
+{
+	struct ttree *tt;
+
+	if (!(tt = dm_pool_zalloc(mem, sizeof(*tt)))) {
+		stack;
+		return NULL;
+	}
+
+	tt->klen = klen;
+	tt->mem = mem;
+	return tt;
+}

Added: devmapper/trunk/lib/regex/ttree.h
==============================================================================
--- (empty file)
+++ devmapper/trunk/lib/regex/ttree.h	Thu May 31 21:59:43 2007
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _DM_TTREE_H
+#define _DM_TTREE_H
+
+struct ttree;
+
+struct ttree *ttree_create(struct dm_pool *mem, unsigned int klen);
+
+void *ttree_lookup(struct ttree *tt, unsigned *key);
+int ttree_insert(struct ttree *tt, unsigned *key, void *data);
+
+#endif

Modified: devmapper/trunk/po/device-mapper.po
==============================================================================
--- devmapper/trunk/po/device-mapper.po	(original)
+++ devmapper/trunk/po/device-mapper.po	Thu May 31 21:59:43 2007
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-01-29 19:56+0000\n"
+"POT-Creation-Date: 2007-04-27 20:54+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -37,6 +37,12 @@
 #: libdm-deptree.c:1667 libdm-deptree.c:1676 libdm-deptree.c:1685
 #: libdm-deptree.c:1697 libdm-deptree.c:1733 libdm-deptree.c:1752
 #: libdm-deptree.c:1795 libdm-deptree.c:1809 libdm-deptree.c:1820
+#: libdm-report.c:313 libdm-report.c:384 regex/matcher.c:181
+#: regex/matcher.c:202 regex/matcher.c:205 regex/matcher.c:277
+#: regex/matcher.c:281 regex/matcher.c:293 regex/matcher.c:313
+#: regex/parse_rx.c:228 regex/parse_rx.c:279 regex/parse_rx.c:304
+#: regex/parse_rx.c:327 regex/parse_rx.c:339 regex/ttree.c:90
+#: regex/ttree.c:110
 msgid "<backtrace>"
 msgstr ""
 
@@ -223,7 +229,7 @@
 
 #: ioctl/libdm-iface.c:1557
 #, c-format
-msgid "dm %s %s %s%s%s %s%.0d%s%.0d%s%s%c%c%s %.0llu %s [%u]"
+msgid "dm %s %s %s%s%s %s%.0d%s%.0d%s%s%c%c%s %.0lu %s [%u]"
 msgstr ""
 
 #: ioctl/libdm-iface.c:1581 ioctl/libdm-iface.c:1586
@@ -688,7 +694,7 @@
 msgid "dm_report_field_uint64: uint64 too big: %d"
 msgstr ""
 
-#: libdm-report.c:264 libdm-report.c:428
+#: libdm-report.c:264 libdm-report.c:448
 msgid " "
 msgstr ""
 
@@ -712,92 +718,92 @@
 msgid "dm_report: field not match: %s"
 msgstr ""
 
-#: libdm-report.c:316 libdm-report.c:347
+#: libdm-report.c:307
 msgid "dm_report: struct field_properties allocation failed"
 msgstr ""
 
-#: libdm-report.c:361
+#: libdm-report.c:387
 #, c-format
 msgid "dm_report: Ignoring duplicate sort field: %s"
 msgstr ""
 
-#: libdm-report.c:393
+#: libdm-report.c:419
 msgid "dm_report: Missing sort field name"
 msgstr ""
 
-#: libdm-report.c:430
+#: libdm-report.c:450
 #, c-format
 msgid "Unrecognised field: %.*s"
 msgstr ""
 
-#: libdm-report.c:452
+#: libdm-report.c:472
 #, c-format
 msgid "dm_report: Unrecognised field: %.*s"
 msgstr ""
 
-#: libdm-report.c:474
+#: libdm-report.c:494
 msgid "dm_report_init: dm_malloc failed"
 msgstr ""
 
-#: libdm-report.c:506
+#: libdm-report.c:526
 msgid "dm_report_init: allocation of memory pool failed"
 msgstr ""
 
-#: libdm-report.c:552
+#: libdm-report.c:577
 msgid "dm_report_object: struct row allocation failed"
 msgstr ""
 
-#: libdm-report.c:562
+#: libdm-report.c:587
 msgid "dm_report_object: row sort value structure allocation failed"
 msgstr ""
 
-#: libdm-report.c:573
+#: libdm-report.c:598
 msgid "dm_report_object: struct dm_report_field allocation failed"
 msgstr ""
 
-#: libdm-report.c:586
+#: libdm-report.c:611
 #, c-format
 msgid "dm_report_object: report function failed for field %s"
 msgstr ""
 
-#: libdm-report.c:626
+#: libdm-report.c:651
 msgid "dm_report: dm_pool_begin_object failed for headings"
 msgstr ""
 
-#: libdm-report.c:640
+#: libdm-report.c:665
 msgid "dm_report: snprintf heading failed"
 msgstr ""
 
-#: libdm-report.c:644 libdm-report.c:649 libdm-report.c:656 libdm-report.c:661
+#: libdm-report.c:669 libdm-report.c:674 libdm-report.c:681 libdm-report.c:686
 msgid "dm_report: Failed to generate report headings for printing"
 msgstr ""
 
-#: libdm-report.c:664 libdm-report.c:826
+#: libdm-report.c:689 libdm-report.c:851
 #, c-format
 msgid "%s"
 msgstr ""
 
-#: libdm-report.c:727
+#: libdm-report.c:752
 msgid "dm_report: sort array allocation failed"
 msgstr ""
 
-#: libdm-report.c:770
+#: libdm-report.c:795
 msgid "dm_report: Unable to allocate output line"
 msgstr ""
 
-#: libdm-report.c:784 libdm-report.c:798 libdm-report.c:808 libdm-report.c:817
+#: libdm-report.c:809 libdm-report.c:823 libdm-report.c:833 libdm-report.c:842
 msgid "dm_report: Unable to extend output line"
 msgstr ""
 
-#: libdm-report.c:794
+#: libdm-report.c:819
 msgid "dm_report: left-aligned snprintf() failed"
 msgstr ""
 
-#: libdm-report.c:804
+#: libdm-report.c:829
 msgid "dm_report: right-aligned snprintf() failed"
 msgstr ""
 
-#: libdm-report.c:823
+#: libdm-report.c:848
 msgid "dm_report: Unable to terminate output line"
 msgstr ""
 
@@ -842,3 +848,36 @@
 #, c-format
 msgid "Out of memory.  Requested %zu bytes."
 msgstr ""
+
+#: regex/matcher.c:136
+msgid "Internal error: Unknown calc node type"
+msgstr ""
+
+#: regex/matcher.c:262
+#, c-format
+msgid "Matcher built with %d dfa states"
+msgstr ""
+
+#: regex/matcher.c:303
+msgid "Couldn't parse regex"
+msgstr ""
+
+#: regex/parse_rx.c:88
+msgid "Incomplete rangespecification"
+msgstr ""
+
+#: regex/parse_rx.c:166
+msgid "Badly quoted character at end of expression"
+msgstr ""
+
+#: regex/parse_rx.c:240
+msgid "missing ')' in regular expression"
+msgstr ""
+
+#: regex/parse_rx.c:322
+msgid "Badly formed 'or' expression"
+msgstr ""
+
+#: regex/parse_rx.c:350
+msgid "Parse error in regex"
+msgstr ""



More information about the pkg-lvm-commits mailing list