All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <45A81618.2080608@ce.jp.nec.com>

diff --git a/a/1.txt b/N1/1.txt
index b10deb7..d667a3c 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -17,3 +17,10 @@ Comments are welcome.
 Thanks,
 -- 
 Jun'ichi Nomura, NEC Corporation of America
+-------------- next part --------------
+A non-text attachment was scrubbed...
+Name: 01-libdm-report.patch
+Type: text/x-patch
+Size: 33117 bytes
+Desc: not available
+URL: <http://listman.redhat.com/archives/lvm-devel/attachments/20070112/6486edb7/attachment.bin>
diff --git a/a/2.hdr b/a/2.hdr
deleted file mode 100644
index 5ad18fb..0000000
--- a/a/2.hdr
+++ /dev/null
@@ -1,5 +0,0 @@
-Content-Type: text/x-patch;
- name="01-libdm-report.patch"
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline;
- filename="01-libdm-report.patch"
diff --git a/a/2.txt b/a/2.txt
deleted file mode 100644
index 141a11f..0000000
--- a/a/2.txt
+++ /dev/null
@@ -1,1271 +0,0 @@
-New dm_report API.
-The code is based on LVM2 reporter function and act much like
-lvs/pvs/vgs commands.
-
-Main APIs are:
-  - dm_report_init
-      Register definition of reported object types and fields
-      and set options.
-      Returns a handle for following calls.
-  - dm_report_object
-      Generate report for one object.
-      The result will be sorted and bufferred until dm_report_output is called
-      if requested.
-  - dm_report_output
-      Output bufferred report.
-  - dm_report_free
-      Abandon the report handle.
-
-There are some other functions for types and fields definition.
-
-Details can be found in the patch.
-
-And each field name passed by format parameter of dm_report_init can be
-followed by the following comparison operator and the value or string:
-    =   : equal to the value or string
-    !=  : not equal to the value or string
-    >=  : greater than or equal to the value
-    <=  : lesser than or equal to the value
-    <   : lesser than the value
-    >   : greater than the value
-    =~  : contains the string
-    !~  : not contain the string
-    =~^ : contains the string as prefix
-    !~^ : not contain the string as prefix
-    
-If the field name is prefixed by "-" in "-o" option string,
-the field is used only to check the condition and not displayed.
-
-
-
-Index: device-mapper/lib/libdevmapper.h
-===================================================================
---- device-mapper.orig/lib/libdevmapper.h	2007-01-12 15:21:52.000000000 -0500
-+++ device-mapper/lib/libdevmapper.h	2007-01-12 15:36:55.000000000 -0500
-@@ -1,6 +1,7 @@
- /*
-  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
-- * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
-+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
-+ * Copyright (C) 2007 NEC Corporation
-  *
-  * This file is part of the device-mapper userspace tools.
-  *
-@@ -623,4 +624,68 @@ int dm_snprintf(char *buf, size_t bufsiz
-  */
- char *dm_basename(const char *path);
- 
-+/*********************
-+ * report function
-+ *********************/
-+
-+struct dm_report_field;
-+struct dm_report;
-+
-+/* Definition of reported object */
-+struct dm_report_object_type {
-+	uint32_t id;		/* must be a power of 2 */
-+	const char *desc;	/* description of the object type */
-+	const char *prefix;	/* default prefix of id string (if any) */
-+	void * (*get) (void *object); /* callback from report_object() */
-+};
-+
-+/* Definition of field */
-+#define DM_REPORT_FIELD_ALIGN_LEFT	0x00000001
-+#define DM_REPORT_FIELD_ALIGN_RIGHT	0x00000002
-+#define DM_REPORT_FIELD_STRING	0x00000004
-+#define DM_REPORT_FIELD_NUMBER	0x00000008
-+struct dm_report_field_type {
-+	uint32_t type;		/* object type id */
-+	const char id[32];	/* string used to specify the field */
-+	unsigned int offset;	/* byte offset in the object */
-+	const char heading[32];	/* string printed in header */
-+	int width;		/* default width */
-+	uint32_t flags;		/* string or number, alignment */
-+	int (*report_fn) (struct dm_report * rh, struct dm_pool * mem,
-+			  struct dm_report_field * field, const void *data);
-+};
-+
-+/*
-+ * Report API
-+ */
-+struct dm_report *dm_report_init(const char *format, const char *keys,
-+				 uint32_t *report_types, const char *separator,
-+				 int aligned, int buffered, int headings,
-+				 const struct dm_report_field_type *fds,
-+				 int num_fds,
-+				 const struct dm_report_object_type *types,
-+				 int num_types,
-+				 void *private);
-+void dm_report_free(struct dm_report *rh);
-+int dm_report_object(struct dm_report *rh, void *object);
-+int dm_report_output(struct dm_report *rh);
-+void * dm_report_get_private(struct dm_report *rh);
-+
-+/* report functions for common types */
-+int dm_report_field_string(struct dm_report *rh, struct dm_pool *mem,
-+			   struct dm_report_field *field, const void *data);
-+int dm_report_field_int32(struct dm_report *rh, struct dm_pool *mem,
-+			  struct dm_report_field *field, const void *data);
-+int dm_report_field_uint32(struct dm_report *rh, struct dm_pool *mem,
-+			   struct dm_report_field *field, const void *data);
-+int dm_report_field_int(struct dm_report *rh, struct dm_pool *mem,
-+			struct dm_report_field *field, const void *data);
-+int dm_report_field_uint64(struct dm_report *rh, struct dm_pool *mem,
-+			struct dm_report_field *field, const void *data);
-+
-+/* helper functions for custom report functions */
-+int dm_report_field_raw(struct dm_report *rh, struct dm_pool *mem,
-+			struct dm_report_field *field, const void *data);
-+void dm_report_field_set_string(struct dm_report_field *field, const char *string);
-+void dm_report_field_set_sort_value(struct dm_report_field *field, const void *value);
- #endif				/* LIB_DEVICE_MAPPER_H */
-Index: device-mapper/lib/libdm-report.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ device-mapper/lib/libdm-report.c	2007-01-12 15:56:04.000000000 -0500
-@@ -0,0 +1,1111 @@
-+/*
-+ * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
-+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
-+ * Copyright (C) 2007 NEC Corporation
-+ *
-+ * This file is part of device-mapper userspace tools.
-+ * The code is based on LVM2 report function.
-+ *
-+ * 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 "libdevmapper.h"
-+#include "list.h"
-+#include "log.h"
-+
-+/*
-+ * Report handle flags
-+ */
-+#define RH_SORT_REQUIRED	0x00000001
-+#define RH_HEADINGS_PRINTED	0x00000002
-+#define RH_BUFFERED		0x00000004
-+#define RH_ALIGNED		0x00000008
-+#define RH_HEADINGS		0x00000010
-+
-+struct dm_report {
-+	struct dm_pool *mem;
-+
-+	uint32_t report_types;
-+	const char *field_prefix;
-+	uint32_t flags;
-+	const char *separator;
-+
-+	uint32_t keys_count;
-+
-+	/* Ordered list of fields needed for this report */
-+	struct list field_props;
-+
-+	/* Rows of report data */
-+	struct list rows;
-+
-+	/* Array of field definitions */
-+	const struct dm_report_field_type *fields;
-+	int num_fields;
-+	const struct dm_report_object_type *types;
-+	int num_types;
-+
-+	/* To store caller private data */
-+	void *private;
-+};
-+
-+void * dm_report_get_private(struct dm_report *rh)
-+{
-+	return rh->private;
-+}
-+
-+/*
-+ * Per-field flags
-+ */
-+#define FLD_ALIGN_LEFT	0x00000001
-+#define FLD_ALIGN_RIGHT	0x00000002
-+#define FLD_STRING	0x00000004
-+#define FLD_NUMBER	0x00000008
-+#define FLD_HIDDEN	0x00000010
-+#define FLD_SORT_KEY	0x00000020
-+#define FLD_ASCENDING	0x00000040
-+#define FLD_DESCENDING	0x00000080
-+
-+#define FLD_CMP_EQUAL	0x00010000
-+#define FLD_CMP_NOT	0x00020000
-+#define FLD_CMP_GT	0x00040000
-+#define FLD_CMP_LT	0x00080000
-+#define FLD_CMP_SUBSTR	0x00100000
-+#define FLD_CMP_PREFIX	0x00200000
-+#define FLD_CMP_MASK	0x00ff0000
-+
-+struct field_properties {
-+	struct list list;
-+	uint32_t field_num;
-+	uint32_t sort_posn;
-+	int width;
-+	const struct dm_report_object_type *type;
-+	uint32_t flags;
-+	char *cmp;
-+};
-+
-+/*
-+ * Report data field
-+ */
-+struct dm_report_field {
-+	struct list list;
-+	struct field_properties *props;
-+
-+	const char *report_string;	/* Formatted ready for display */
-+	const void *sort_value;		/* Raw value for sorting */
-+};
-+
-+struct row {
-+	struct list list;
-+	struct dm_report *rh;
-+	struct list fields;			  /* Fields in display order */
-+	struct dm_report_field *(*sort_fields)[]; /* Fields in sort order */
-+};
-+
-+static const struct dm_report_object_type *_find_type(struct dm_report *rh,
-+						      uint32_t report_type)
-+{
-+	const struct dm_report_object_type *t;
-+
-+	for (t = rh->types; t < rh->types + rh->num_types; t++)
-+		if (t->id == report_type)
-+			return t;
-+
-+	return NULL;
-+}
-+
-+/*
-+ * Data-munging functions to prepare each data type for display and sorting
-+ */
-+
-+int dm_report_field_string(struct dm_report *rh, struct dm_pool *mem,
-+			   struct dm_report_field *field, const void *data)
-+{
-+	char *repstr;
-+
-+	if (!(repstr = dm_pool_strdup(rh->mem, *(const char **) data))) {
-+		log_error("dm_report_field_string: dm_pool_strdup failed");
-+		return 0;
-+	}
-+
-+	field->report_string = repstr;
-+	field->sort_value = (const void *) field->report_string;
-+
-+	return 1;
-+}
-+
-+int dm_report_field_uint32(struct dm_report *rh, struct dm_pool *mem,
-+			   struct dm_report_field *field, const void *data)
-+{
-+	const uint32_t value = *(const uint32_t *) data;
-+	uint64_t *sortval;
-+	char *repstr;
-+
-+	if (!(repstr = dm_pool_zalloc(rh->mem, 12))) {
-+		log_error("dm_report_field_uint32: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
-+		log_error("dm_report_field_uint32: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (dm_snprintf(repstr, 11, "%u", value) < 0) {
-+		log_error("dm_report_field_uint32: uint32 too big: %u", value);
-+		return 0;
-+	}
-+
-+	*sortval = (const uint64_t) value;
-+	field->sort_value = sortval;
-+	field->report_string = repstr;
-+
-+	return 1;
-+}
-+
-+int dm_report_field_int32(struct dm_report *rh, struct dm_pool *mem,
-+			  struct dm_report_field *field, const void *data)
-+{
-+	const int32_t value = *(const int32_t *) data;
-+	uint64_t *sortval;
-+	char *repstr;
-+
-+	if (!(repstr = dm_pool_zalloc(rh->mem, 13))) {
-+		log_error("dm_report_field_int32: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {
-+		log_error("dm_report_field_int32: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (dm_snprintf(repstr, 12, "%d", value) < 0) {
-+		log_error("dm_report_field_int32: int32 too big: %d", value);
-+		return 0;
-+	}
-+
-+	*sortval = (const uint64_t) value;
-+	field->sort_value = sortval;
-+	field->report_string = repstr;
-+
-+	return 1;
-+}
-+
-+int dm_report_field_int(struct dm_report *rh, struct dm_pool *mem,
-+			struct dm_report_field *field, const void *data)
-+{
-+	const int value = *(const int *) data;
-+	uint64_t *sortval;
-+	char *repstr;
-+
-+	if (!(repstr = dm_pool_zalloc(rh->mem, 23))) {
-+		log_error("dm_report_field_int: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {
-+		log_error("dm_report_field_int: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (dm_snprintf(repstr, 22, "%d", value) < 0) {
-+		log_error("dm_report_field_int: int too big: %d", value);
-+		return 0;
-+	}
-+
-+	*sortval = (const uint64_t) value;
-+	field->sort_value = sortval;
-+	field->report_string = repstr;
-+
-+	return 1;
-+}
-+
-+int dm_report_field_uint64(struct dm_report *rh, struct dm_pool *mem,
-+			   struct dm_report_field *field, const void *data)
-+{
-+	const int value = *(const uint64_t *) data;
-+	uint64_t *sortval;
-+	char *repstr;
-+
-+	if (!(repstr = dm_pool_zalloc(rh->mem, 22))) {
-+		log_error("dm_report_field_uint64: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
-+		log_error("dm_report_field_uint64: dm_pool_alloc failed");
-+		return 0;
-+	}
-+
-+	if (dm_snprintf(repstr, 21, "%d", value) < 0) {
-+		log_error("dm_report_field_uint64: uint64 too big: %d", value);
-+		return 0;
-+	}
-+
-+	*sortval = (const uint64_t) value;
-+	field->sort_value = sortval;
-+	field->report_string = repstr;
-+
-+	return 1;
-+}
-+
-+/*
-+ * Helper functions for custom report functions
-+ */
-+void dm_report_field_set_string(struct dm_report_field *field,
-+				const char *string)
-+{
-+	field->report_string = string;
-+}
-+
-+void dm_report_field_set_sort_value(struct dm_report_field *field,
-+				    const void *value)
-+{
-+	field->sort_value = value;
-+}
-+
-+int dm_report_field_raw(struct dm_report *rh, struct dm_pool *mem,
-+			struct dm_report_field *field, const void *data)
-+{
-+	field->report_string = (const char *) data;
-+	field->sort_value = data;
-+	return 1;
-+}
-+
-+/*
-+ * comparison operators to set a condition to display row
-+ */
-+static char _cmp_op_chars[] = "=!><~^";
-+
-+static struct {
-+	const char *string;
-+	uint32_t flags;
-+} _cmp_op[] = {
-+	{ "=", FLD_CMP_EQUAL },
-+	{ "!=", FLD_CMP_NOT|FLD_CMP_EQUAL },
-+	{ ">", FLD_CMP_GT|FLD_NUMBER },
-+	{ ">=", FLD_CMP_GT|FLD_CMP_EQUAL|FLD_NUMBER },
-+	{ "<", FLD_CMP_LT|FLD_NUMBER },
-+	{ "<=", FLD_CMP_LT|FLD_CMP_EQUAL|FLD_NUMBER },
-+	{ "=~", FLD_CMP_SUBSTR|FLD_STRING },
-+	{ "!~", FLD_CMP_SUBSTR|FLD_CMP_NOT|FLD_STRING },
-+	{ "=~^", FLD_CMP_PREFIX|FLD_STRING },
-+	{ "!~^", FLD_CMP_PREFIX|FLD_CMP_NOT|FLD_STRING },
-+	{ NULL, 0 }
-+};
-+
-+static int _cmp_op_char(const char c)
-+{
-+	char *p = _cmp_op_chars;
-+
-+	while (*p) {
-+		if (*p == c)
-+			return 1;
-+		p++;
-+	}
-+
-+	return 0;
-+}
-+
-+static uint32_t _cmp_op_flags(struct dm_report *rh, const char *s, int len)
-+{
-+	int i;
-+	char *buf;
-+
-+	for (i = 0; _cmp_op[i].string; i++)
-+		if (!strncmp(s, _cmp_op[i].string, len))
-+			return _cmp_op[i].flags;
-+
-+	if (!(buf = dm_pool_zalloc(rh->mem, len + 1))) {
-+		log_error("dm_report: log message allocation failed");
-+		return 0;
-+	}
-+	memcpy(buf, s, len);
-+	log_error("dm_report: wrong comparison operator %s", buf);
-+	dm_pool_free(rh->mem, buf);
-+	return 0;
-+}
-+
-+/*
-+ * show help message
-+ */
-+static void _display_operators(void)
-+{
-+	int i;
-+
-+	log_print(" ");
-+	log_print("Comparison operators");
-+
-+	for (i = 0; _cmp_op[i].string; i++)
-+		log_print("- %s %s%s", _cmp_op[i].string,
-+			_cmp_op[i].flags & FLD_NUMBER ? "(number only)" : "",
-+			_cmp_op[i].flags & FLD_STRING ? "(string only)" : "");
-+}
-+
-+static void _display_fields(struct dm_report *rh)
-+{
-+	uint32_t f;
-+	const struct dm_report_object_type *type;
-+	const char *desc, *last_desc = "";
-+
-+	for (f = 0; f < rh->num_fields; f++) {
-+		if ((type = _find_type(rh, rh->fields[f].type)) && type->desc)
-+			desc = type->desc;
-+		else
-+			desc = " ";
-+		if (desc != last_desc) {
-+			if (*last_desc)
-+				log_print(" ");
-+			log_print("%s Fields", desc);
-+		}
-+
-+		log_print("- %s", rh->fields[f].id);
-+		last_desc = desc;
-+	}
-+
-+	_display_operators();
-+}
-+
-+/*
-+ * Initialise report handle
-+ */
-+
-+static uint32_t _translate_flags(uint32_t flags)
-+{
-+	/* translate public flags (DM_REPORT_) to internal flags (FLD_) */
-+	static uint32_t _map[] = {
-+		DM_REPORT_FIELD_ALIGN_LEFT, FLD_ALIGN_LEFT,
-+		DM_REPORT_FIELD_ALIGN_RIGHT, FLD_ALIGN_RIGHT,
-+		DM_REPORT_FIELD_STRING, FLD_STRING,
-+		DM_REPORT_FIELD_NUMBER, FLD_NUMBER,
-+		0, 0,
-+	};
-+	uint32_t f = 0, *m;
-+
-+	for (m = _map; *m; m += 2)
-+		if (flags & *m)
-+			f |= *(m + 1);
-+
-+	return f;
-+}
-+
-+static int _copy_field(struct dm_report *rh, struct field_properties *dest,
-+		       uint32_t field_num)
-+{
-+	dest->field_num = field_num;
-+	dest->width = rh->fields[field_num].width;
-+	dest->flags = _translate_flags(rh->fields[field_num].flags);
-+
-+	/* set object type method */
-+	dest->type = _find_type(rh, rh->fields[field_num].type);
-+	if (!dest->type) {
-+		log_error("dm_report: field not match: %s",
-+			  rh->fields[field_num].id);
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+static int _field_match(struct dm_report *rh,
-+			const char *field, size_t flen,
-+			const char *cmp, size_t clen, uint32_t cflags)
-+{
-+	uint32_t f, l;
-+	struct field_properties *fp;
-+
-+	if (!flen)
-+		return 0;
-+
-+	for (f = 0; f < rh->num_fields; 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;
-+
-+			/* comparison operator */
-+			fp->flags |= cflags;
-+			if (fp->flags & FLD_NUMBER && fp->flags & FLD_STRING) {
-+				log_error("dm_report: operator type conflict");
-+				if (cflags & FLD_NUMBER)
-+					log_error("for number only");
-+				else /* FLD_STRING */
-+					log_error("for string only");
-+			}
-+
-+			if (!(fp->cmp = dm_pool_zalloc(rh->mem, clen + 1))) {
-+				log_error("dm_report: "
-+					  "condition string allocation "
-+					  "failed");
-+				return 0;
-+			}
-+			memcpy(fp->cmp, cmp, clen);
-+
-+			list_add(&rh->field_props, &fp->list);
-+			return 1;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int _add_sort_key(struct dm_report *rh, uint32_t field_num,
-+			 uint32_t flags)
-+{
-+	struct field_properties *fp, *found = NULL;
-+
-+	list_iterate_items(fp, &rh->field_props) {
-+		if (fp->field_num == field_num) {
-+			found = fp;
-+			break;
-+		}
-+	}
-+
-+	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->flags & FLD_SORT_KEY) {
-+		log_error("dm_report: Ignoring duplicate sort field: %s",
-+			  rh->fields[field_num].id);
-+		return 1;
-+	}
-+
-+	found->flags |= FLD_SORT_KEY;
-+	found->sort_posn = rh->keys_count++;
-+	found->flags |= flags;
-+
-+	return 1;
-+}
-+
-+static int _key_match(struct dm_report *rh, const char *key, size_t len)
-+{
-+	uint32_t f, l;
-+	uint32_t flags;
-+
-+	if (!len)
-+		return 0;
-+
-+	if (*key == '+') {
-+		key++;
-+		len--;
-+		flags = FLD_ASCENDING;
-+	} else if (*key == '-') {
-+		key++;
-+		len--;
-+		flags = FLD_DESCENDING;
-+	} else
-+		flags = FLD_ASCENDING;
-+
-+	if (!len) {
-+		log_error("dm_report: Missing sort field name");
-+		return 0;
-+	}
-+
-+	for (f = 0; f < rh->num_fields; 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)) {
-+			return _add_sort_key(rh, f, flags);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int _parse_options(struct dm_report *rh, const char *format)
-+{
-+	const char *ws;		/* Word start */
-+	const char *we = format;	/* Word end */
-+	const char *cs, *ce;	/* Comparison word start/end */
-+	uint32_t flags;
-+
-+	while (*we) {
-+		flags = 0;
-+
-+		/* Allow consecutive commas */
-+		while (*we && *we == ',')
-+			we++;
-+
-+		/* prefix of condition to mark the field hidden */
-+		if (*we == '-') {
-+			flags |= FLD_HIDDEN;
-+			we++;
-+		}
-+
-+		/* start of the field name */
-+		ws = we;
-+		while (*we && *we != ',' && !_cmp_op_char(*we))
-+			we++;
-+
-+		/* comparison operator and string if any */
-+		cs = ce = NULL;
-+		if (_cmp_op_char(*we)) {
-+			cs = ce = we;
-+			while (*ce && *ce != ',' && _cmp_op_char(*ce))
-+				ce++;
-+			flags |= _cmp_op_flags(rh, cs, ce - cs);
-+
-+			cs = ce;
-+			while (*ce && *ce != ',')
-+				ce++;
-+		}
-+
-+		if (!_field_match(rh, ws, (size_t) (we - ws),
-+				  cs, (size_t) (ce - cs), flags)) {
-+			_display_fields(rh);
-+			log_print(" ");
-+			log_error("dm_report: Unrecognised field: %.*s",
-+				  (int) (we - ws), ws);
-+			return 0;
-+		}
-+
-+		if (ce)
-+			we = ce;
-+	}
-+
-+	return 1;
-+}
-+
-+static int _parse_keys(struct dm_report *rh, const char *keys)
-+{
-+	const char *ws;		/* Word start */
-+	const char *we = keys;	/* Word end */
-+
-+	while (*we) {
-+		/* Allow consecutive commas */
-+		while (*we && *we == ',')
-+			we++;
-+		ws = we;
-+		while (*we && *we != ',')
-+			we++;
-+		if (!_key_match(rh, ws, (size_t) (we - ws))) {
-+			log_error("dm_report: Unrecognised field: %.*s",
-+				  (int) (we - ws), ws);
-+			return 0;
-+		}
-+	}
-+
-+	return 1;
-+}
-+
-+#define ALIGN_MASK (DM_REPORT_FIELD_ALIGN_LEFT|DM_REPORT_FIELD_ALIGN_RIGHT)
-+#define TYPE_MASK (DM_REPORT_FIELD_NUMBER|DM_REPORT_FIELD_STRING)
-+
-+/*
-+ * Check the field/type definition as much as possible
-+ * to omit checks in the later stage or avoid unexpected failures
-+ */
-+static int _check_definition(const struct dm_report_field_type *fds,
-+			     int num_fds,
-+			     const struct dm_report_object_type *types,
-+			     int num_types)
-+{
-+	int i, ret = 0;
-+
-+	for (i = 0; i < num_fds; i++) {
-+		if (!fds[i].report_fn) {
-+			log_error("dm_report: report_fn isn't defined for %s",
-+				  fds[i].id);
-+			ret = 1;
-+		}
-+
-+		if (!(fds[i].flags & TYPE_MASK)) {
-+			log_error("dm_report: field %s type unspecified",
-+				  fds[i].id);
-+			ret = 1;
-+		}
-+		if ((fds[i].flags & TYPE_MASK) == TYPE_MASK) {
-+			log_error("dm_report: field %s type conflict",
-+				  fds[i].id);
-+			ret = 1;
-+		}
-+
-+		if (!(fds[i].flags & ALIGN_MASK)) {
-+			log_error("dm_report: field %s alignment unspecified",
-+				  fds[i].id);
-+			ret = 1;
-+		}
-+		if ((fds[i].flags & ALIGN_MASK) == ALIGN_MASK) {
-+			log_error("dm_report: field %s alignment conflict",
-+				  fds[i].id);
-+			ret = 1;
-+		}
-+	}
-+
-+	for (i = 0; i < num_types; i++) {
-+		if (hweight32(types[i].id) != 1) {
-+			log_error("dm_report: object type %d isn't power of 2",
-+				  types[i].id);
-+			ret = 1;
-+		}
-+		if (!types[i].get) {
-+			log_error("dm_report: get isn't defined for object "
-+				  "type %d", types[i].id);
-+			ret = 1;
-+		}
-+	}
-+
-+	return ret;
-+}
-+
-+struct dm_report *dm_report_init(
-+		  const char *format, const char *keys,
-+		  uint32_t *report_types,
-+		  const char *separator,
-+		  int aligned, int buffered, int headings,
-+		  const struct dm_report_field_type *fds, int num_fds,
-+		  const struct dm_report_object_type *types, int num_types,
-+		  void *private)
-+{
-+	struct dm_report *rh;
-+	const struct dm_report_object_type *type;
-+
-+	if (_check_definition(fds, num_fds, types, num_types))
-+		return 0;
-+
-+	if (!(rh = dm_malloc(sizeof(*rh)))) {
-+		log_error("dm_report_init: dm_malloc failed");
-+		return 0;
-+	}
-+	memset(rh, 0, sizeof(*rh));
-+
-+	/*
-+	 * rh->report_types is updated in _parse_options() and _parse_keys()
-+	 * to contain all types corresponding to the fields specified by
-+	 * options or keys.
-+	 */
-+	if (report_types)
-+		rh->report_types = *report_types;
-+
-+	rh->separator = separator;
-+	rh->fields = fds;
-+	rh->num_fields = num_fds;
-+	rh->types = types;
-+	rh->num_types = num_types;
-+	rh->private = private;
-+
-+	if (aligned)
-+		rh->flags |= RH_ALIGNED;
-+
-+	if (buffered)
-+		rh->flags |= RH_BUFFERED | RH_SORT_REQUIRED;
-+
-+	if (headings)
-+		rh->flags |= RH_HEADINGS;
-+
-+	list_init(&rh->field_props);
-+	list_init(&rh->rows);
-+
-+	if ((type = _find_type(rh, rh->report_types)) && type->prefix)
-+		rh->field_prefix = type->prefix;
-+	else
-+		rh->field_prefix = "";
-+
-+	if (!(rh->mem = dm_pool_create("report", 10 * 1024))) {
-+		log_error("dm_report_init: allocation of memory pool failed");
-+		return NULL;
-+	}
-+
-+	/* Generate list of fields for output based on format string & flags */
-+	if (!_parse_options(rh, format))
-+		return NULL;
-+
-+	if (!_parse_keys(rh, keys))
-+		return NULL;
-+
-+	/* Return updated types value for further compatility check by caller */
-+	if (report_types)
-+		*report_types = rh->report_types;
-+
-+	return rh;
-+}
-+
-+void dm_report_free(struct dm_report *rh)
-+{
-+	dm_pool_destroy(rh->mem);
-+
-+	return;
-+}
-+
-+/*
-+ * Create a row of data for an object
-+ */
-+static int _compare_field_number(uint64_t a, uint64_t b, uint32_t flags)
-+{
-+	switch (flags & FLD_CMP_MASK) {
-+	case FLD_CMP_EQUAL:
-+		return a == b;
-+	case FLD_CMP_NOT|FLD_CMP_EQUAL:
-+		return a != b;
-+	case FLD_CMP_GT:
-+		return a > b;
-+	case FLD_CMP_GT|FLD_CMP_EQUAL:
-+		return a >= b;
-+	case FLD_CMP_LT:
-+		return a < b;
-+	case FLD_CMP_LT|FLD_CMP_EQUAL:
-+		return a <= b;
-+	}
-+	return 0;
-+}
-+
-+static int _compare_field_string(const char *a, const char *b, uint32_t flags)
-+{
-+	switch (flags & FLD_CMP_MASK) {
-+	case FLD_CMP_EQUAL:
-+		return !strcmp(a, b);
-+	case FLD_CMP_NOT|FLD_CMP_EQUAL:
-+		return strcmp(a, b);
-+	case FLD_CMP_PREFIX:
-+		return !strncmp(b, a, strlen(b));
-+	case FLD_CMP_PREFIX|FLD_CMP_NOT:
-+		return strncmp(b, a, strlen(b));
-+	case FLD_CMP_SUBSTR:
-+		return strstr(a, b) != NULL;
-+	case FLD_CMP_SUBSTR|FLD_CMP_NOT:
-+		return strstr(a, b) == NULL;
-+	}
-+	return 0;
-+}
-+
-+static int _compare_field(struct dm_report_field *field,
-+			  struct field_properties *fp)
-+{
-+	if (!field->sort_value) {
-+		log_error("dm_report: field without value: %d",
-+			  field->props->field_num);
-+		return 0;
-+	}
-+
-+	if (field->props->flags & FLD_NUMBER) {
-+		const uint64_t numa = *(const uint64_t *)field->sort_value;
-+		const uint64_t numb = strtoul(fp->cmp, NULL, 0);
-+		return _compare_field_number(numa, numb, fp->flags);
-+	} else {	/* FLD_STRING */
-+		const char *stra = (const char *) field->sort_value;
-+		const char *strb = fp->cmp;
-+		return _compare_field_string(stra, strb, fp->flags);
-+	}
-+}
-+
-+static void * _report_get_field_data(struct dm_report *rh,
-+			      struct field_properties *fp, void *object)
-+{
-+	void *ret = fp->type->get(object);
-+
-+	if (!ret)
-+		return NULL;
-+
-+	return ret + rh->fields[fp->field_num].offset;
-+}
-+
-+int dm_report_object(struct dm_report *rh, void *object)
-+{
-+	struct field_properties *fp;
-+	struct row *row;
-+	struct dm_report_field *field;
-+	void *data = NULL;
-+
-+	if (!(row = dm_pool_zalloc(rh->mem, sizeof(*row)))) {
-+		log_error("dm_report_object: struct row allocation failed");
-+		return 0;
-+	}
-+
-+	row->rh = rh;
-+
-+	if ((rh->flags & RH_SORT_REQUIRED) &&
-+	    !(row->sort_fields =
-+		dm_pool_zalloc(rh->mem, sizeof(struct dm_report_field *) *
-+			       rh->keys_count))) {
-+		log_error("dm_report_object: "
-+			  "row sort value structure allocation failed");
-+		return 0;
-+	}
-+
-+	list_init(&row->fields);
-+	list_add(&rh->rows, &row->list);
-+
-+	/* For each field to be displayed, call its report_fn */
-+	list_iterate_items(fp, &rh->field_props) {
-+		if (!(field = dm_pool_zalloc(rh->mem, sizeof(*field)))) {
-+			log_error("dm_report_object: "
-+				  "struct dm_report_field allocation failed");
-+			return 0;
-+		}
-+		field->props = fp;
-+
-+		data = _report_get_field_data(rh, fp, object);
-+		if (!data)
-+			return 0;
-+
-+		if (!rh->fields[fp->field_num].report_fn(rh, rh->mem,
-+							 field, data)) {
-+			log_error("dm_report_object: "
-+				  "report function failed for field %s",
-+				  rh->fields[fp->field_num].id);
-+			return 0;
-+		}
-+
-+		if ((fp->flags & FLD_CMP_MASK) && !_compare_field(field, fp)) {
-+			list_del(&row->list);
-+			return 0;
-+		}
-+
-+		if ((strlen(field->report_string) > field->props->width))
-+			field->props->width = strlen(field->report_string);
-+
-+		if ((rh->flags & RH_SORT_REQUIRED) &&
-+		    (field->props->flags & FLD_SORT_KEY)) {
-+			(*row->sort_fields)[field->props->sort_posn] = field;
-+		}
-+		list_add(&row->fields, &field->list);
-+	}
-+
-+	if (!(rh->flags & RH_BUFFERED))
-+		return dm_report_output(rh);
-+
-+	return 1;
-+}
-+
-+/*
-+ * Print row of headings
-+ */
-+static int _report_headings(void *handle)
-+{
-+	struct dm_report *rh = handle;
-+	struct field_properties *fp;
-+	const char *heading;
-+	char buf[1024];
-+
-+	if (rh->flags & RH_HEADINGS_PRINTED)
-+		return 1;
-+
-+	rh->flags |= RH_HEADINGS_PRINTED;
-+
-+	if (!(rh->flags & RH_HEADINGS))
-+		return 1;
-+
-+	if (!dm_pool_begin_object(rh->mem, 128)) {
-+		log_error("dm_report: "
-+			  "dm_pool_begin_object failed for headings");
-+		return 0;
-+	}
-+
-+	/* First heading line */
-+	list_iterate_items(fp, &rh->field_props) {
-+		if (fp->flags & FLD_HIDDEN)
-+			continue;
-+
-+		heading = rh->fields[fp->field_num].heading;
-+		if (rh->flags & RH_ALIGNED) {
-+			if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
-+					 fp->width, fp->width, heading) < 0)
-+				goto bad_snprintf;
-+			if (!dm_pool_grow_object(rh->mem, buf, fp->width))
-+				goto bad_grow;
-+		} else if (!dm_pool_grow_object(rh->mem, heading,
-+						strlen(heading)))
-+			goto bad_grow;
-+
-+		if (!list_end(&rh->field_props, &fp->list))
-+			if (!dm_pool_grow_object(rh->mem, rh->separator,
-+					      strlen(rh->separator)))
-+				goto bad_grow;
-+	}
-+	if (!dm_pool_grow_object(rh->mem, "\0", 1))
-+		goto bad_grow;
-+	log_print("%s", (char *) dm_pool_end_object(rh->mem));
-+
-+	return 1;
-+
-+      bad_snprintf:
-+	log_error("dm_report: snprintf heading failed");
-+      bad_grow:
-+	log_error("dm_report: Failed to generate report headings for printing");
-+	dm_pool_abandon_object(rh->mem);
-+	return 0;
-+}
-+
-+/*
-+ * Sort rows of data
-+ */
-+static int _row_compare(const void *a, const void *b)
-+{
-+	const struct row *rowa = *(const struct row **) a;
-+	const struct row *rowb = *(const struct row **) b;
-+	const struct dm_report_field *sfa, *sfb;
-+	int32_t cnt = -1;
-+
-+	for (cnt = 0; cnt < rowa->rh->keys_count; cnt++) {
-+		sfa = (*rowa->sort_fields)[cnt];
-+		sfb = (*rowb->sort_fields)[cnt];
-+		if (sfa->props->flags & FLD_NUMBER) {
-+			const uint64_t numa =
-+			    *(const uint64_t *) sfa->sort_value;
-+			const uint64_t numb =
-+			    *(const uint64_t *) sfb->sort_value;
-+
-+			if (numa == numb)
-+				continue;
-+
-+			if (sfa->props->flags & FLD_ASCENDING) {
-+				return (numa > numb) ? 1 : -1;
-+			} else {	/* FLD_DESCENDING */
-+				return (numa < numb) ? 1 : -1;
-+			}
-+		} else {	/* FLD_STRING */
-+			const char *stra = (const char *) sfa->sort_value;
-+			const char *strb = (const char *) sfb->sort_value;
-+			int cmp = strcmp(stra, strb);
-+
-+			if (!cmp)
-+				continue;
-+
-+			if (sfa->props->flags & FLD_ASCENDING) {
-+				return (cmp > 0) ? 1 : -1;
-+			} else {	/* FLD_DESCENDING */
-+				return (cmp < 0) ? 1 : -1;
-+			}
-+		}
-+	}
-+
-+	return 0;		/* Identical */
-+}
-+
-+static int _sort_rows(struct dm_report *rh)
-+{
-+	struct row *(*rows)[];
-+	uint32_t count = 0;
-+	struct row *row;
-+
-+	if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *
-+				list_size(&rh->rows)))) {
-+		log_error("dm_report: sort array allocation failed");
-+		return 0;
-+	}
-+
-+	list_iterate_items(row, &rh->rows)
-+		(*rows)[count++] = row;
-+
-+	qsort(rows, count, sizeof(**rows), _row_compare);
-+
-+	list_init(&rh->rows);
-+	while (count--)
-+		list_add_h(&rh->rows, &(*rows)[count]->list);
-+
-+	return 1;
-+}
-+
-+/*
-+ * Produce report output
-+ */
-+int dm_report_output(struct dm_report *rh)
-+{
-+	struct list *fh, *rowh, *ftmp, *rtmp;
-+	struct row *row = NULL;
-+	struct dm_report_field *field;
-+	const char *repstr;
-+	char buf[4096];
-+	int width;
-+
-+	if (list_empty(&rh->rows))
-+		return 1;
-+
-+	/* Sort rows */
-+	if ((rh->flags & RH_SORT_REQUIRED))
-+		_sort_rows(rh);
-+
-+	/* If headings not printed yet, calculate field widths and print them */
-+	if (!(rh->flags & RH_HEADINGS_PRINTED))
-+		_report_headings(rh);
-+
-+	/* Print and clear buffer */
-+	list_iterate_safe(rowh, rtmp, &rh->rows) {
-+		if (!dm_pool_begin_object(rh->mem, 512)) {
-+			log_error("dm_report: "
-+				  "dm_pool_begin_object failed for row");
-+			return 0;
-+		}
-+		row = list_item(rowh, struct row);
-+		list_iterate_safe(fh, ftmp, &row->fields) {
-+			field = list_item(fh, struct dm_report_field);
-+			if (field->props->flags & FLD_HIDDEN)
-+				continue;
-+
-+			repstr = field->report_string;
-+			width = field->props->width;
-+			if (!(rh->flags & RH_ALIGNED)) {
-+				if (!dm_pool_grow_object(rh->mem, repstr,
-+						      strlen(repstr)))
-+					goto bad_grow;
-+			} else if (field->props->flags & FLD_ALIGN_LEFT) {
-+				if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
-+						 width, width, repstr) < 0)
-+					goto bad_snprintf;
-+				if (!dm_pool_grow_object(rh->mem, buf, width))
-+					goto bad_grow;
-+			} else if (field->props->flags & FLD_ALIGN_RIGHT) {
-+				if (dm_snprintf(buf, sizeof(buf), "%*.*s",
-+						 width, width, repstr) < 0)
-+					goto bad_snprintf;
-+				if (!dm_pool_grow_object(rh->mem, buf, width))
-+					goto bad_grow;
-+			}
-+
-+			if (!list_end(&row->fields, fh))
-+				if (!dm_pool_grow_object(rh->mem, rh->separator,
-+						      strlen(rh->separator)))
-+					goto bad_grow;
-+			list_del(&field->list);
-+		}
-+		if (!dm_pool_grow_object(rh->mem, "\0", 1))
-+			goto bad_grow;
-+		log_print("%s", (char *) dm_pool_end_object(rh->mem));
-+		list_del(&row->list);
-+	}
-+
-+	if (row)
-+		dm_pool_free(rh->mem, row);
-+
-+	return 1;
-+
-+      bad_snprintf:
-+	log_error("dm_report: snprintf row failed");
-+      bad_grow:
-+	log_error("dm_report: Failed to generate row for printing");
-+	dm_pool_abandon_object(rh->mem);
-+	return 0;
-+}
-Index: device-mapper/lib/Makefile.in
-===================================================================
---- device-mapper.orig/lib/Makefile.in	2007-01-12 15:21:52.000000000 -0500
-+++ device-mapper/lib/Makefile.in	2007-01-12 15:36:55.000000000 -0500
-@@ -24,6 +24,7 @@ SOURCES =\
- 	libdm-file.c \
- 	libdm-deptree.c \
- 	libdm-string.c \
-+	libdm-report.c \
- 	mm/dbg_malloc.c \
- 	mm/pool.c \
- 	$(interface)/libdm-iface.c
-Index: device-mapper/lib/.exported_symbols
-===================================================================
---- device-mapper.orig/lib/.exported_symbols	2007-01-12 15:21:52.000000000 -0500
-+++ device-mapper/lib/.exported_symbols	2007-01-12 15:36:55.000000000 -0500
-@@ -115,3 +115,16 @@ dm_split_lvm_name
- dm_split_words
- dm_snprintf
- dm_basename
-+dm_report_init
-+dm_report_object
-+dm_report_output
-+dm_report_free
-+dm_report_get_private
-+dm_report_field_string
-+dm_report_field_int32
-+dm_report_field_uint32
-+dm_report_field_int
-+dm_report_field_uint64
-+dm_report_field_raw
-+dm_report_field_set_string
-+dm_report_field_set_sort_value
diff --git a/a/3.hdr b/a/3.hdr
deleted file mode 100644
index 4b86001..0000000
--- a/a/3.hdr
+++ /dev/null
@@ -1,4 +0,0 @@
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
diff --git a/a/3.txt b/a/3.txt
deleted file mode 100644
index 8b13789..0000000
--- a/a/3.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/a/content_digest b/N1/content_digest
index ab2495f..fedade0 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,9 +1,8 @@
  "From\0Jun'ichi Nomura <j-nomura@ce.jp.nec.com>\0"
  "Subject\0[PATCH] (1/4) dm_report support in libdevmapper\0"
  "Date\0Fri, 12 Jan 2007 18:13:28 -0500\0"
- "To\0device-mapper development <dm-devel@redhat.com>"
- " LVM2 development <lvm-devel@redhat.com>\0"
- "\01:1\0"
+ "To\0lvm-devel@redhat.com\0"
+ "\00:1\0"
  "b\0"
  "Hi,\n"
  "\n"
@@ -23,1282 +22,13 @@
  "\n"
  "Thanks,\n"
  "-- \n"
- Jun'ichi Nomura, NEC Corporation of America
- "\01:2\0"
- "fn\001-libdm-report.patch\0"
- "b\0"
- "New dm_report API.\n"
- "The code is based on LVM2 reporter function and act much like\n"
- "lvs/pvs/vgs commands.\n"
- "\n"
- "Main APIs are:\n"
- "  - dm_report_init\n"
- "      Register definition of reported object types and fields\n"
- "      and set options.\n"
- "      Returns a handle for following calls.\n"
- "  - dm_report_object\n"
- "      Generate report for one object.\n"
- "      The result will be sorted and bufferred until dm_report_output is called\n"
- "      if requested.\n"
- "  - dm_report_output\n"
- "      Output bufferred report.\n"
- "  - dm_report_free\n"
- "      Abandon the report handle.\n"
- "\n"
- "There are some other functions for types and fields definition.\n"
- "\n"
- "Details can be found in the patch.\n"
- "\n"
- "And each field name passed by format parameter of dm_report_init can be\n"
- "followed by the following comparison operator and the value or string:\n"
- "    =   : equal to the value or string\n"
- "    !=  : not equal to the value or string\n"
- "    >=  : greater than or equal to the value\n"
- "    <=  : lesser than or equal to the value\n"
- "    <   : lesser than the value\n"
- "    >   : greater than the value\n"
- "    =~  : contains the string\n"
- "    !~  : not contain the string\n"
- "    =~^ : contains the string as prefix\n"
- "    !~^ : not contain the string as prefix\n"
- "    \n"
- "If the field name is prefixed by \"-\" in \"-o\" option string,\n"
- "the field is used only to check the condition and not displayed.\n"
- "\n"
- "\n"
- "\n"
- "Index: device-mapper/lib/libdevmapper.h\n"
- "===================================================================\n"
- "--- device-mapper.orig/lib/libdevmapper.h\t2007-01-12 15:21:52.000000000 -0500\n"
- "+++ device-mapper/lib/libdevmapper.h\t2007-01-12 15:36:55.000000000 -0500\n"
- "@@ -1,6 +1,7 @@\n"
- " /*\n"
- "  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.\n"
- "- * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.\n"
- "+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.\n"
- "+ * Copyright (C) 2007 NEC Corporation\n"
- "  *\n"
- "  * This file is part of the device-mapper userspace tools.\n"
- "  *\n"
- "@@ -623,4 +624,68 @@ int dm_snprintf(char *buf, size_t bufsiz\n"
- "  */\n"
- " char *dm_basename(const char *path);\n"
- " \n"
- "+/*********************\n"
- "+ * report function\n"
- "+ *********************/\n"
- "+\n"
- "+struct dm_report_field;\n"
- "+struct dm_report;\n"
- "+\n"
- "+/* Definition of reported object */\n"
- "+struct dm_report_object_type {\n"
- "+\tuint32_t id;\t\t/* must be a power of 2 */\n"
- "+\tconst char *desc;\t/* description of the object type */\n"
- "+\tconst char *prefix;\t/* default prefix of id string (if any) */\n"
- "+\tvoid * (*get) (void *object); /* callback from report_object() */\n"
- "+};\n"
- "+\n"
- "+/* Definition of field */\n"
- "+#define DM_REPORT_FIELD_ALIGN_LEFT\t0x00000001\n"
- "+#define DM_REPORT_FIELD_ALIGN_RIGHT\t0x00000002\n"
- "+#define DM_REPORT_FIELD_STRING\t0x00000004\n"
- "+#define DM_REPORT_FIELD_NUMBER\t0x00000008\n"
- "+struct dm_report_field_type {\n"
- "+\tuint32_t type;\t\t/* object type id */\n"
- "+\tconst char id[32];\t/* string used to specify the field */\n"
- "+\tunsigned int offset;\t/* byte offset in the object */\n"
- "+\tconst char heading[32];\t/* string printed in header */\n"
- "+\tint width;\t\t/* default width */\n"
- "+\tuint32_t flags;\t\t/* string or number, alignment */\n"
- "+\tint (*report_fn) (struct dm_report * rh, struct dm_pool * mem,\n"
- "+\t\t\t  struct dm_report_field * field, const void *data);\n"
- "+};\n"
- "+\n"
- "+/*\n"
- "+ * Report API\n"
- "+ */\n"
- "+struct dm_report *dm_report_init(const char *format, const char *keys,\n"
- "+\t\t\t\t uint32_t *report_types, const char *separator,\n"
- "+\t\t\t\t int aligned, int buffered, int headings,\n"
- "+\t\t\t\t const struct dm_report_field_type *fds,\n"
- "+\t\t\t\t int num_fds,\n"
- "+\t\t\t\t const struct dm_report_object_type *types,\n"
- "+\t\t\t\t int num_types,\n"
- "+\t\t\t\t void *private);\n"
- "+void dm_report_free(struct dm_report *rh);\n"
- "+int dm_report_object(struct dm_report *rh, void *object);\n"
- "+int dm_report_output(struct dm_report *rh);\n"
- "+void * dm_report_get_private(struct dm_report *rh);\n"
- "+\n"
- "+/* report functions for common types */\n"
- "+int dm_report_field_string(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t   struct dm_report_field *field, const void *data);\n"
- "+int dm_report_field_int32(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t  struct dm_report_field *field, const void *data);\n"
- "+int dm_report_field_uint32(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t   struct dm_report_field *field, const void *data);\n"
- "+int dm_report_field_int(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\tstruct dm_report_field *field, const void *data);\n"
- "+int dm_report_field_uint64(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\tstruct dm_report_field *field, const void *data);\n"
- "+\n"
- "+/* helper functions for custom report functions */\n"
- "+int dm_report_field_raw(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\tstruct dm_report_field *field, const void *data);\n"
- "+void dm_report_field_set_string(struct dm_report_field *field, const char *string);\n"
- "+void dm_report_field_set_sort_value(struct dm_report_field *field, const void *value);\n"
- " #endif\t\t\t\t/* LIB_DEVICE_MAPPER_H */\n"
- "Index: device-mapper/lib/libdm-report.c\n"
- "===================================================================\n"
- "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n"
- "+++ device-mapper/lib/libdm-report.c\t2007-01-12 15:56:04.000000000 -0500\n"
- "@@ -0,0 +1,1111 @@\n"
- "+/*\n"
- "+ * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.\n"
- "+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.\n"
- "+ * Copyright (C) 2007 NEC Corporation\n"
- "+ *\n"
- "+ * This file is part of device-mapper userspace tools.\n"
- "+ * The code is based on LVM2 report function.\n"
- "+ *\n"
- "+ * This copyrighted material is made available to anyone wishing to use,\n"
- "+ * modify, copy, or redistribute it subject to the terms and conditions\n"
- "+ * of the GNU General Public License v.2.\n"
- "+ *\n"
- "+ * You should have received a copy of the GNU General Public License\n"
- "+ * along with this program; if not, write to the Free Software Foundation,\n"
- "+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
- "+ */\n"
- "+\n"
- "+#include \"libdevmapper.h\"\n"
- "+#include \"list.h\"\n"
- "+#include \"log.h\"\n"
- "+\n"
- "+/*\n"
- "+ * Report handle flags\n"
- "+ */\n"
- "+#define RH_SORT_REQUIRED\t0x00000001\n"
- "+#define RH_HEADINGS_PRINTED\t0x00000002\n"
- "+#define RH_BUFFERED\t\t0x00000004\n"
- "+#define RH_ALIGNED\t\t0x00000008\n"
- "+#define RH_HEADINGS\t\t0x00000010\n"
- "+\n"
- "+struct dm_report {\n"
- "+\tstruct dm_pool *mem;\n"
- "+\n"
- "+\tuint32_t report_types;\n"
- "+\tconst char *field_prefix;\n"
- "+\tuint32_t flags;\n"
- "+\tconst char *separator;\n"
- "+\n"
- "+\tuint32_t keys_count;\n"
- "+\n"
- "+\t/* Ordered list of fields needed for this report */\n"
- "+\tstruct list field_props;\n"
- "+\n"
- "+\t/* Rows of report data */\n"
- "+\tstruct list rows;\n"
- "+\n"
- "+\t/* Array of field definitions */\n"
- "+\tconst struct dm_report_field_type *fields;\n"
- "+\tint num_fields;\n"
- "+\tconst struct dm_report_object_type *types;\n"
- "+\tint num_types;\n"
- "+\n"
- "+\t/* To store caller private data */\n"
- "+\tvoid *private;\n"
- "+};\n"
- "+\n"
- "+void * dm_report_get_private(struct dm_report *rh)\n"
- "+{\n"
- "+\treturn rh->private;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Per-field flags\n"
- "+ */\n"
- "+#define FLD_ALIGN_LEFT\t0x00000001\n"
- "+#define FLD_ALIGN_RIGHT\t0x00000002\n"
- "+#define FLD_STRING\t0x00000004\n"
- "+#define FLD_NUMBER\t0x00000008\n"
- "+#define FLD_HIDDEN\t0x00000010\n"
- "+#define FLD_SORT_KEY\t0x00000020\n"
- "+#define FLD_ASCENDING\t0x00000040\n"
- "+#define FLD_DESCENDING\t0x00000080\n"
- "+\n"
- "+#define FLD_CMP_EQUAL\t0x00010000\n"
- "+#define FLD_CMP_NOT\t0x00020000\n"
- "+#define FLD_CMP_GT\t0x00040000\n"
- "+#define FLD_CMP_LT\t0x00080000\n"
- "+#define FLD_CMP_SUBSTR\t0x00100000\n"
- "+#define FLD_CMP_PREFIX\t0x00200000\n"
- "+#define FLD_CMP_MASK\t0x00ff0000\n"
- "+\n"
- "+struct field_properties {\n"
- "+\tstruct list list;\n"
- "+\tuint32_t field_num;\n"
- "+\tuint32_t sort_posn;\n"
- "+\tint width;\n"
- "+\tconst struct dm_report_object_type *type;\n"
- "+\tuint32_t flags;\n"
- "+\tchar *cmp;\n"
- "+};\n"
- "+\n"
- "+/*\n"
- "+ * Report data field\n"
- "+ */\n"
- "+struct dm_report_field {\n"
- "+\tstruct list list;\n"
- "+\tstruct field_properties *props;\n"
- "+\n"
- "+\tconst char *report_string;\t/* Formatted ready for display */\n"
- "+\tconst void *sort_value;\t\t/* Raw value for sorting */\n"
- "+};\n"
- "+\n"
- "+struct row {\n"
- "+\tstruct list list;\n"
- "+\tstruct dm_report *rh;\n"
- "+\tstruct list fields;\t\t\t  /* Fields in display order */\n"
- "+\tstruct dm_report_field *(*sort_fields)[]; /* Fields in sort order */\n"
- "+};\n"
- "+\n"
- "+static const struct dm_report_object_type *_find_type(struct dm_report *rh,\n"
- "+\t\t\t\t\t\t      uint32_t report_type)\n"
- "+{\n"
- "+\tconst struct dm_report_object_type *t;\n"
- "+\n"
- "+\tfor (t = rh->types; t < rh->types + rh->num_types; t++)\n"
- "+\t\tif (t->id == report_type)\n"
- "+\t\t\treturn t;\n"
- "+\n"
- "+\treturn NULL;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Data-munging functions to prepare each data type for display and sorting\n"
- "+ */\n"
- "+\n"
- "+int dm_report_field_string(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t   struct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tchar *repstr;\n"
- "+\n"
- "+\tif (!(repstr = dm_pool_strdup(rh->mem, *(const char **) data))) {\n"
- "+\t\tlog_error(\"dm_report_field_string: dm_pool_strdup failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tfield->report_string = repstr;\n"
- "+\tfield->sort_value = (const void *) field->report_string;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+int dm_report_field_uint32(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t   struct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tconst uint32_t value = *(const uint32_t *) data;\n"
- "+\tuint64_t *sortval;\n"
- "+\tchar *repstr;\n"
- "+\n"
- "+\tif (!(repstr = dm_pool_zalloc(rh->mem, 12))) {\n"
- "+\t\tlog_error(\"dm_report_field_uint32: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {\n"
- "+\t\tlog_error(\"dm_report_field_uint32: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (dm_snprintf(repstr, 11, \"%u\", value) < 0) {\n"
- "+\t\tlog_error(\"dm_report_field_uint32: uint32 too big: %u\", value);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\t*sortval = (const uint64_t) value;\n"
- "+\tfield->sort_value = sortval;\n"
- "+\tfield->report_string = repstr;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+int dm_report_field_int32(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t  struct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tconst int32_t value = *(const int32_t *) data;\n"
- "+\tuint64_t *sortval;\n"
- "+\tchar *repstr;\n"
- "+\n"
- "+\tif (!(repstr = dm_pool_zalloc(rh->mem, 13))) {\n"
- "+\t\tlog_error(\"dm_report_field_int32: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {\n"
- "+\t\tlog_error(\"dm_report_field_int32: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (dm_snprintf(repstr, 12, \"%d\", value) < 0) {\n"
- "+\t\tlog_error(\"dm_report_field_int32: int32 too big: %d\", value);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\t*sortval = (const uint64_t) value;\n"
- "+\tfield->sort_value = sortval;\n"
- "+\tfield->report_string = repstr;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+int dm_report_field_int(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\tstruct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tconst int value = *(const int *) data;\n"
- "+\tuint64_t *sortval;\n"
- "+\tchar *repstr;\n"
- "+\n"
- "+\tif (!(repstr = dm_pool_zalloc(rh->mem, 23))) {\n"
- "+\t\tlog_error(\"dm_report_field_int: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {\n"
- "+\t\tlog_error(\"dm_report_field_int: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (dm_snprintf(repstr, 22, \"%d\", value) < 0) {\n"
- "+\t\tlog_error(\"dm_report_field_int: int too big: %d\", value);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\t*sortval = (const uint64_t) value;\n"
- "+\tfield->sort_value = sortval;\n"
- "+\tfield->report_string = repstr;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+int dm_report_field_uint64(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\t   struct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tconst int value = *(const uint64_t *) data;\n"
- "+\tuint64_t *sortval;\n"
- "+\tchar *repstr;\n"
- "+\n"
- "+\tif (!(repstr = dm_pool_zalloc(rh->mem, 22))) {\n"
- "+\t\tlog_error(\"dm_report_field_uint64: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {\n"
- "+\t\tlog_error(\"dm_report_field_uint64: dm_pool_alloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (dm_snprintf(repstr, 21, \"%d\", value) < 0) {\n"
- "+\t\tlog_error(\"dm_report_field_uint64: uint64 too big: %d\", value);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\t*sortval = (const uint64_t) value;\n"
- "+\tfield->sort_value = sortval;\n"
- "+\tfield->report_string = repstr;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Helper functions for custom report functions\n"
- "+ */\n"
- "+void dm_report_field_set_string(struct dm_report_field *field,\n"
- "+\t\t\t\tconst char *string)\n"
- "+{\n"
- "+\tfield->report_string = string;\n"
- "+}\n"
- "+\n"
- "+void dm_report_field_set_sort_value(struct dm_report_field *field,\n"
- "+\t\t\t\t    const void *value)\n"
- "+{\n"
- "+\tfield->sort_value = value;\n"
- "+}\n"
- "+\n"
- "+int dm_report_field_raw(struct dm_report *rh, struct dm_pool *mem,\n"
- "+\t\t\tstruct dm_report_field *field, const void *data)\n"
- "+{\n"
- "+\tfield->report_string = (const char *) data;\n"
- "+\tfield->sort_value = data;\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * comparison operators to set a condition to display row\n"
- "+ */\n"
- "+static char _cmp_op_chars[] = \"=!><~^\";\n"
- "+\n"
- "+static struct {\n"
- "+\tconst char *string;\n"
- "+\tuint32_t flags;\n"
- "+} _cmp_op[] = {\n"
- "+\t{ \"=\", FLD_CMP_EQUAL },\n"
- "+\t{ \"!=\", FLD_CMP_NOT|FLD_CMP_EQUAL },\n"
- "+\t{ \">\", FLD_CMP_GT|FLD_NUMBER },\n"
- "+\t{ \">=\", FLD_CMP_GT|FLD_CMP_EQUAL|FLD_NUMBER },\n"
- "+\t{ \"<\", FLD_CMP_LT|FLD_NUMBER },\n"
- "+\t{ \"<=\", FLD_CMP_LT|FLD_CMP_EQUAL|FLD_NUMBER },\n"
- "+\t{ \"=~\", FLD_CMP_SUBSTR|FLD_STRING },\n"
- "+\t{ \"!~\", FLD_CMP_SUBSTR|FLD_CMP_NOT|FLD_STRING },\n"
- "+\t{ \"=~^\", FLD_CMP_PREFIX|FLD_STRING },\n"
- "+\t{ \"!~^\", FLD_CMP_PREFIX|FLD_CMP_NOT|FLD_STRING },\n"
- "+\t{ NULL, 0 }\n"
- "+};\n"
- "+\n"
- "+static int _cmp_op_char(const char c)\n"
- "+{\n"
- "+\tchar *p = _cmp_op_chars;\n"
- "+\n"
- "+\twhile (*p) {\n"
- "+\t\tif (*p == c)\n"
- "+\t\t\treturn 1;\n"
- "+\t\tp++;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static uint32_t _cmp_op_flags(struct dm_report *rh, const char *s, int len)\n"
- "+{\n"
- "+\tint i;\n"
- "+\tchar *buf;\n"
- "+\n"
- "+\tfor (i = 0; _cmp_op[i].string; i++)\n"
- "+\t\tif (!strncmp(s, _cmp_op[i].string, len))\n"
- "+\t\t\treturn _cmp_op[i].flags;\n"
- "+\n"
- "+\tif (!(buf = dm_pool_zalloc(rh->mem, len + 1))) {\n"
- "+\t\tlog_error(\"dm_report: log message allocation failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\tmemcpy(buf, s, len);\n"
- "+\tlog_error(\"dm_report: wrong comparison operator %s\", buf);\n"
- "+\tdm_pool_free(rh->mem, buf);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * show help message\n"
- "+ */\n"
- "+static void _display_operators(void)\n"
- "+{\n"
- "+\tint i;\n"
- "+\n"
- "+\tlog_print(\" \");\n"
- "+\tlog_print(\"Comparison operators\");\n"
- "+\n"
- "+\tfor (i = 0; _cmp_op[i].string; i++)\n"
- "+\t\tlog_print(\"- %s %s%s\", _cmp_op[i].string,\n"
- "+\t\t\t_cmp_op[i].flags & FLD_NUMBER ? \"(number only)\" : \"\",\n"
- "+\t\t\t_cmp_op[i].flags & FLD_STRING ? \"(string only)\" : \"\");\n"
- "+}\n"
- "+\n"
- "+static void _display_fields(struct dm_report *rh)\n"
- "+{\n"
- "+\tuint32_t f;\n"
- "+\tconst struct dm_report_object_type *type;\n"
- "+\tconst char *desc, *last_desc = \"\";\n"
- "+\n"
- "+\tfor (f = 0; f < rh->num_fields; f++) {\n"
- "+\t\tif ((type = _find_type(rh, rh->fields[f].type)) && type->desc)\n"
- "+\t\t\tdesc = type->desc;\n"
- "+\t\telse\n"
- "+\t\t\tdesc = \" \";\n"
- "+\t\tif (desc != last_desc) {\n"
- "+\t\t\tif (*last_desc)\n"
- "+\t\t\t\tlog_print(\" \");\n"
- "+\t\t\tlog_print(\"%s Fields\", desc);\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tlog_print(\"- %s\", rh->fields[f].id);\n"
- "+\t\tlast_desc = desc;\n"
- "+\t}\n"
- "+\n"
- "+\t_display_operators();\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Initialise report handle\n"
- "+ */\n"
- "+\n"
- "+static uint32_t _translate_flags(uint32_t flags)\n"
- "+{\n"
- "+\t/* translate public flags (DM_REPORT_) to internal flags (FLD_) */\n"
- "+\tstatic uint32_t _map[] = {\n"
- "+\t\tDM_REPORT_FIELD_ALIGN_LEFT, FLD_ALIGN_LEFT,\n"
- "+\t\tDM_REPORT_FIELD_ALIGN_RIGHT, FLD_ALIGN_RIGHT,\n"
- "+\t\tDM_REPORT_FIELD_STRING, FLD_STRING,\n"
- "+\t\tDM_REPORT_FIELD_NUMBER, FLD_NUMBER,\n"
- "+\t\t0, 0,\n"
- "+\t};\n"
- "+\tuint32_t f = 0, *m;\n"
- "+\n"
- "+\tfor (m = _map; *m; m += 2)\n"
- "+\t\tif (flags & *m)\n"
- "+\t\t\tf |= *(m + 1);\n"
- "+\n"
- "+\treturn f;\n"
- "+}\n"
- "+\n"
- "+static int _copy_field(struct dm_report *rh, struct field_properties *dest,\n"
- "+\t\t       uint32_t field_num)\n"
- "+{\n"
- "+\tdest->field_num = field_num;\n"
- "+\tdest->width = rh->fields[field_num].width;\n"
- "+\tdest->flags = _translate_flags(rh->fields[field_num].flags);\n"
- "+\n"
- "+\t/* set object type method */\n"
- "+\tdest->type = _find_type(rh, rh->fields[field_num].type);\n"
- "+\tif (!dest->type) {\n"
- "+\t\tlog_error(\"dm_report: field not match: %s\",\n"
- "+\t\t\t  rh->fields[field_num].id);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+static int _field_match(struct dm_report *rh,\n"
- "+\t\t\tconst char *field, size_t flen,\n"
- "+\t\t\tconst char *cmp, size_t clen, uint32_t cflags)\n"
- "+{\n"
- "+\tuint32_t f, l;\n"
- "+\tstruct field_properties *fp;\n"
- "+\n"
- "+\tif (!flen)\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tfor (f = 0; f < rh->num_fields; f++) {\n"
- "+\t\tif ((!strncasecmp(rh->fields[f].id, field, flen) &&\n"
- "+\t\t     strlen(rh->fields[f].id) == flen) ||\n"
- "+\t\t    (l = strlen(rh->field_prefix),\n"
- "+\t\t     !strncasecmp(rh->field_prefix, rh->fields[f].id, l) &&\n"
- "+\t\t     !strncasecmp(rh->fields[f].id + l, field, flen) &&\n"
- "+\t\t     strlen(rh->fields[f].id) == l + flen)) {\n"
- "+\t\t\trh->report_types |= rh->fields[f].type;\n"
- "+\t\t\tif (!(fp = dm_pool_zalloc(rh->mem, sizeof(*fp)))) {\n"
- "+\t\t\t\tlog_error(\"dm_report: \"\n"
- "+\t\t\t\t\t  \"struct field_properties allocation \"\n"
- "+\t\t\t\t\t  \"failed\");\n"
- "+\t\t\t\treturn 0;\n"
- "+\t\t\t}\n"
- "+\t\t\tif (!_copy_field(rh, fp, f))\n"
- "+\t\t\t\treturn 0;\n"
- "+\n"
- "+\t\t\t/* comparison operator */\n"
- "+\t\t\tfp->flags |= cflags;\n"
- "+\t\t\tif (fp->flags & FLD_NUMBER && fp->flags & FLD_STRING) {\n"
- "+\t\t\t\tlog_error(\"dm_report: operator type conflict\");\n"
- "+\t\t\t\tif (cflags & FLD_NUMBER)\n"
- "+\t\t\t\t\tlog_error(\"for number only\");\n"
- "+\t\t\t\telse /* FLD_STRING */\n"
- "+\t\t\t\t\tlog_error(\"for string only\");\n"
- "+\t\t\t}\n"
- "+\n"
- "+\t\t\tif (!(fp->cmp = dm_pool_zalloc(rh->mem, clen + 1))) {\n"
- "+\t\t\t\tlog_error(\"dm_report: \"\n"
- "+\t\t\t\t\t  \"condition string allocation \"\n"
- "+\t\t\t\t\t  \"failed\");\n"
- "+\t\t\t\treturn 0;\n"
- "+\t\t\t}\n"
- "+\t\t\tmemcpy(fp->cmp, cmp, clen);\n"
- "+\n"
- "+\t\t\tlist_add(&rh->field_props, &fp->list);\n"
- "+\t\t\treturn 1;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int _add_sort_key(struct dm_report *rh, uint32_t field_num,\n"
- "+\t\t\t uint32_t flags)\n"
- "+{\n"
- "+\tstruct field_properties *fp, *found = NULL;\n"
- "+\n"
- "+\tlist_iterate_items(fp, &rh->field_props) {\n"
- "+\t\tif (fp->field_num == field_num) {\n"
- "+\t\t\tfound = fp;\n"
- "+\t\t\tbreak;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tif (!found) {\n"
- "+\t\trh->report_types |= rh->fields[field_num].type;\n"
- "+\t\tif (!(found = dm_pool_zalloc(rh->mem, sizeof(*found)))) {\n"
- "+\t\t\tlog_error(\"dm_report: \"\n"
- "+\t\t\t\t  \"struct field_properties allocation failed\");\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\t\tif (!_copy_field(rh, found, field_num))\n"
- "+\t\t\treturn 0;\n"
- "+\n"
- "+\t\t/* Add as a non-display field */\n"
- "+\t\tfound->flags |= FLD_HIDDEN;\n"
- "+\n"
- "+\t\tlist_add(&rh->field_props, &found->list);\n"
- "+\t}\n"
- "+\n"
- "+\tif (found->flags & FLD_SORT_KEY) {\n"
- "+\t\tlog_error(\"dm_report: Ignoring duplicate sort field: %s\",\n"
- "+\t\t\t  rh->fields[field_num].id);\n"
- "+\t\treturn 1;\n"
- "+\t}\n"
- "+\n"
- "+\tfound->flags |= FLD_SORT_KEY;\n"
- "+\tfound->sort_posn = rh->keys_count++;\n"
- "+\tfound->flags |= flags;\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+static int _key_match(struct dm_report *rh, const char *key, size_t len)\n"
- "+{\n"
- "+\tuint32_t f, l;\n"
- "+\tuint32_t flags;\n"
- "+\n"
- "+\tif (!len)\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tif (*key == '+') {\n"
- "+\t\tkey++;\n"
- "+\t\tlen--;\n"
- "+\t\tflags = FLD_ASCENDING;\n"
- "+\t} else if (*key == '-') {\n"
- "+\t\tkey++;\n"
- "+\t\tlen--;\n"
- "+\t\tflags = FLD_DESCENDING;\n"
- "+\t} else\n"
- "+\t\tflags = FLD_ASCENDING;\n"
- "+\n"
- "+\tif (!len) {\n"
- "+\t\tlog_error(\"dm_report: Missing sort field name\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tfor (f = 0; f < rh->num_fields; f++) {\n"
- "+\t\tif ((!strncasecmp(rh->fields[f].id, key, len) &&\n"
- "+\t\t     strlen(rh->fields[f].id) == len) ||\n"
- "+\t\t    (l = strlen(rh->field_prefix),\n"
- "+\t\t     !strncasecmp(rh->field_prefix, rh->fields[f].id, l) &&\n"
- "+\t\t     !strncasecmp(rh->fields[f].id + l, key, len) &&\n"
- "+\t\t     strlen(rh->fields[f].id) == l + len)) {\n"
- "+\t\t\treturn _add_sort_key(rh, f, flags);\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int _parse_options(struct dm_report *rh, const char *format)\n"
- "+{\n"
- "+\tconst char *ws;\t\t/* Word start */\n"
- "+\tconst char *we = format;\t/* Word end */\n"
- "+\tconst char *cs, *ce;\t/* Comparison word start/end */\n"
- "+\tuint32_t flags;\n"
- "+\n"
- "+\twhile (*we) {\n"
- "+\t\tflags = 0;\n"
- "+\n"
- "+\t\t/* Allow consecutive commas */\n"
- "+\t\twhile (*we && *we == ',')\n"
- "+\t\t\twe++;\n"
- "+\n"
- "+\t\t/* prefix of condition to mark the field hidden */\n"
- "+\t\tif (*we == '-') {\n"
- "+\t\t\tflags |= FLD_HIDDEN;\n"
- "+\t\t\twe++;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\t/* start of the field name */\n"
- "+\t\tws = we;\n"
- "+\t\twhile (*we && *we != ',' && !_cmp_op_char(*we))\n"
- "+\t\t\twe++;\n"
- "+\n"
- "+\t\t/* comparison operator and string if any */\n"
- "+\t\tcs = ce = NULL;\n"
- "+\t\tif (_cmp_op_char(*we)) {\n"
- "+\t\t\tcs = ce = we;\n"
- "+\t\t\twhile (*ce && *ce != ',' && _cmp_op_char(*ce))\n"
- "+\t\t\t\tce++;\n"
- "+\t\t\tflags |= _cmp_op_flags(rh, cs, ce - cs);\n"
- "+\n"
- "+\t\t\tcs = ce;\n"
- "+\t\t\twhile (*ce && *ce != ',')\n"
- "+\t\t\t\tce++;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (!_field_match(rh, ws, (size_t) (we - ws),\n"
- "+\t\t\t\t  cs, (size_t) (ce - cs), flags)) {\n"
- "+\t\t\t_display_fields(rh);\n"
- "+\t\t\tlog_print(\" \");\n"
- "+\t\t\tlog_error(\"dm_report: Unrecognised field: %.*s\",\n"
- "+\t\t\t\t  (int) (we - ws), ws);\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (ce)\n"
- "+\t\t\twe = ce;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+static int _parse_keys(struct dm_report *rh, const char *keys)\n"
- "+{\n"
- "+\tconst char *ws;\t\t/* Word start */\n"
- "+\tconst char *we = keys;\t/* Word end */\n"
- "+\n"
- "+\twhile (*we) {\n"
- "+\t\t/* Allow consecutive commas */\n"
- "+\t\twhile (*we && *we == ',')\n"
- "+\t\t\twe++;\n"
- "+\t\tws = we;\n"
- "+\t\twhile (*we && *we != ',')\n"
- "+\t\t\twe++;\n"
- "+\t\tif (!_key_match(rh, ws, (size_t) (we - ws))) {\n"
- "+\t\t\tlog_error(\"dm_report: Unrecognised field: %.*s\",\n"
- "+\t\t\t\t  (int) (we - ws), ws);\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+#define ALIGN_MASK (DM_REPORT_FIELD_ALIGN_LEFT|DM_REPORT_FIELD_ALIGN_RIGHT)\n"
- "+#define TYPE_MASK (DM_REPORT_FIELD_NUMBER|DM_REPORT_FIELD_STRING)\n"
- "+\n"
- "+/*\n"
- "+ * Check the field/type definition as much as possible\n"
- "+ * to omit checks in the later stage or avoid unexpected failures\n"
- "+ */\n"
- "+static int _check_definition(const struct dm_report_field_type *fds,\n"
- "+\t\t\t     int num_fds,\n"
- "+\t\t\t     const struct dm_report_object_type *types,\n"
- "+\t\t\t     int num_types)\n"
- "+{\n"
- "+\tint i, ret = 0;\n"
- "+\n"
- "+\tfor (i = 0; i < num_fds; i++) {\n"
- "+\t\tif (!fds[i].report_fn) {\n"
- "+\t\t\tlog_error(\"dm_report: report_fn isn't defined for %s\",\n"
- "+\t\t\t\t  fds[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (!(fds[i].flags & TYPE_MASK)) {\n"
- "+\t\t\tlog_error(\"dm_report: field %s type unspecified\",\n"
- "+\t\t\t\t  fds[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\t\tif ((fds[i].flags & TYPE_MASK) == TYPE_MASK) {\n"
- "+\t\t\tlog_error(\"dm_report: field %s type conflict\",\n"
- "+\t\t\t\t  fds[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (!(fds[i].flags & ALIGN_MASK)) {\n"
- "+\t\t\tlog_error(\"dm_report: field %s alignment unspecified\",\n"
- "+\t\t\t\t  fds[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\t\tif ((fds[i].flags & ALIGN_MASK) == ALIGN_MASK) {\n"
- "+\t\t\tlog_error(\"dm_report: field %s alignment conflict\",\n"
- "+\t\t\t\t  fds[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tfor (i = 0; i < num_types; i++) {\n"
- "+\t\tif (hweight32(types[i].id) != 1) {\n"
- "+\t\t\tlog_error(\"dm_report: object type %d isn't power of 2\",\n"
- "+\t\t\t\t  types[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\t\tif (!types[i].get) {\n"
- "+\t\t\tlog_error(\"dm_report: get isn't defined for object \"\n"
- "+\t\t\t\t  \"type %d\", types[i].id);\n"
- "+\t\t\tret = 1;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+struct dm_report *dm_report_init(\n"
- "+\t\t  const char *format, const char *keys,\n"
- "+\t\t  uint32_t *report_types,\n"
- "+\t\t  const char *separator,\n"
- "+\t\t  int aligned, int buffered, int headings,\n"
- "+\t\t  const struct dm_report_field_type *fds, int num_fds,\n"
- "+\t\t  const struct dm_report_object_type *types, int num_types,\n"
- "+\t\t  void *private)\n"
- "+{\n"
- "+\tstruct dm_report *rh;\n"
- "+\tconst struct dm_report_object_type *type;\n"
- "+\n"
- "+\tif (_check_definition(fds, num_fds, types, num_types))\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tif (!(rh = dm_malloc(sizeof(*rh)))) {\n"
- "+\t\tlog_error(\"dm_report_init: dm_malloc failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\tmemset(rh, 0, sizeof(*rh));\n"
- "+\n"
- "+\t/*\n"
- "+\t * rh->report_types is updated in _parse_options() and _parse_keys()\n"
- "+\t * to contain all types corresponding to the fields specified by\n"
- "+\t * options or keys.\n"
- "+\t */\n"
- "+\tif (report_types)\n"
- "+\t\trh->report_types = *report_types;\n"
- "+\n"
- "+\trh->separator = separator;\n"
- "+\trh->fields = fds;\n"
- "+\trh->num_fields = num_fds;\n"
- "+\trh->types = types;\n"
- "+\trh->num_types = num_types;\n"
- "+\trh->private = private;\n"
- "+\n"
- "+\tif (aligned)\n"
- "+\t\trh->flags |= RH_ALIGNED;\n"
- "+\n"
- "+\tif (buffered)\n"
- "+\t\trh->flags |= RH_BUFFERED | RH_SORT_REQUIRED;\n"
- "+\n"
- "+\tif (headings)\n"
- "+\t\trh->flags |= RH_HEADINGS;\n"
- "+\n"
- "+\tlist_init(&rh->field_props);\n"
- "+\tlist_init(&rh->rows);\n"
- "+\n"
- "+\tif ((type = _find_type(rh, rh->report_types)) && type->prefix)\n"
- "+\t\trh->field_prefix = type->prefix;\n"
- "+\telse\n"
- "+\t\trh->field_prefix = \"\";\n"
- "+\n"
- "+\tif (!(rh->mem = dm_pool_create(\"report\", 10 * 1024))) {\n"
- "+\t\tlog_error(\"dm_report_init: allocation of memory pool failed\");\n"
- "+\t\treturn NULL;\n"
- "+\t}\n"
- "+\n"
- "+\t/* Generate list of fields for output based on format string & flags */\n"
- "+\tif (!_parse_options(rh, format))\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\tif (!_parse_keys(rh, keys))\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\t/* Return updated types value for further compatility check by caller */\n"
- "+\tif (report_types)\n"
- "+\t\t*report_types = rh->report_types;\n"
- "+\n"
- "+\treturn rh;\n"
- "+}\n"
- "+\n"
- "+void dm_report_free(struct dm_report *rh)\n"
- "+{\n"
- "+\tdm_pool_destroy(rh->mem);\n"
- "+\n"
- "+\treturn;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Create a row of data for an object\n"
- "+ */\n"
- "+static int _compare_field_number(uint64_t a, uint64_t b, uint32_t flags)\n"
- "+{\n"
- "+\tswitch (flags & FLD_CMP_MASK) {\n"
- "+\tcase FLD_CMP_EQUAL:\n"
- "+\t\treturn a == b;\n"
- "+\tcase FLD_CMP_NOT|FLD_CMP_EQUAL:\n"
- "+\t\treturn a != b;\n"
- "+\tcase FLD_CMP_GT:\n"
- "+\t\treturn a > b;\n"
- "+\tcase FLD_CMP_GT|FLD_CMP_EQUAL:\n"
- "+\t\treturn a >= b;\n"
- "+\tcase FLD_CMP_LT:\n"
- "+\t\treturn a < b;\n"
- "+\tcase FLD_CMP_LT|FLD_CMP_EQUAL:\n"
- "+\t\treturn a <= b;\n"
- "+\t}\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int _compare_field_string(const char *a, const char *b, uint32_t flags)\n"
- "+{\n"
- "+\tswitch (flags & FLD_CMP_MASK) {\n"
- "+\tcase FLD_CMP_EQUAL:\n"
- "+\t\treturn !strcmp(a, b);\n"
- "+\tcase FLD_CMP_NOT|FLD_CMP_EQUAL:\n"
- "+\t\treturn strcmp(a, b);\n"
- "+\tcase FLD_CMP_PREFIX:\n"
- "+\t\treturn !strncmp(b, a, strlen(b));\n"
- "+\tcase FLD_CMP_PREFIX|FLD_CMP_NOT:\n"
- "+\t\treturn strncmp(b, a, strlen(b));\n"
- "+\tcase FLD_CMP_SUBSTR:\n"
- "+\t\treturn strstr(a, b) != NULL;\n"
- "+\tcase FLD_CMP_SUBSTR|FLD_CMP_NOT:\n"
- "+\t\treturn strstr(a, b) == NULL;\n"
- "+\t}\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int _compare_field(struct dm_report_field *field,\n"
- "+\t\t\t  struct field_properties *fp)\n"
- "+{\n"
- "+\tif (!field->sort_value) {\n"
- "+\t\tlog_error(\"dm_report: field without value: %d\",\n"
- "+\t\t\t  field->props->field_num);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (field->props->flags & FLD_NUMBER) {\n"
- "+\t\tconst uint64_t numa = *(const uint64_t *)field->sort_value;\n"
- "+\t\tconst uint64_t numb = strtoul(fp->cmp, NULL, 0);\n"
- "+\t\treturn _compare_field_number(numa, numb, fp->flags);\n"
- "+\t} else {\t/* FLD_STRING */\n"
- "+\t\tconst char *stra = (const char *) field->sort_value;\n"
- "+\t\tconst char *strb = fp->cmp;\n"
- "+\t\treturn _compare_field_string(stra, strb, fp->flags);\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+static void * _report_get_field_data(struct dm_report *rh,\n"
- "+\t\t\t      struct field_properties *fp, void *object)\n"
- "+{\n"
- "+\tvoid *ret = fp->type->get(object);\n"
- "+\n"
- "+\tif (!ret)\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\treturn ret + rh->fields[fp->field_num].offset;\n"
- "+}\n"
- "+\n"
- "+int dm_report_object(struct dm_report *rh, void *object)\n"
- "+{\n"
- "+\tstruct field_properties *fp;\n"
- "+\tstruct row *row;\n"
- "+\tstruct dm_report_field *field;\n"
- "+\tvoid *data = NULL;\n"
- "+\n"
- "+\tif (!(row = dm_pool_zalloc(rh->mem, sizeof(*row)))) {\n"
- "+\t\tlog_error(\"dm_report_object: struct row allocation failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\trow->rh = rh;\n"
- "+\n"
- "+\tif ((rh->flags & RH_SORT_REQUIRED) &&\n"
- "+\t    !(row->sort_fields =\n"
- "+\t\tdm_pool_zalloc(rh->mem, sizeof(struct dm_report_field *) *\n"
- "+\t\t\t       rh->keys_count))) {\n"
- "+\t\tlog_error(\"dm_report_object: \"\n"
- "+\t\t\t  \"row sort value structure allocation failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tlist_init(&row->fields);\n"
- "+\tlist_add(&rh->rows, &row->list);\n"
- "+\n"
- "+\t/* For each field to be displayed, call its report_fn */\n"
- "+\tlist_iterate_items(fp, &rh->field_props) {\n"
- "+\t\tif (!(field = dm_pool_zalloc(rh->mem, sizeof(*field)))) {\n"
- "+\t\t\tlog_error(\"dm_report_object: \"\n"
- "+\t\t\t\t  \"struct dm_report_field allocation failed\");\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\t\tfield->props = fp;\n"
- "+\n"
- "+\t\tdata = _report_get_field_data(rh, fp, object);\n"
- "+\t\tif (!data)\n"
- "+\t\t\treturn 0;\n"
- "+\n"
- "+\t\tif (!rh->fields[fp->field_num].report_fn(rh, rh->mem,\n"
- "+\t\t\t\t\t\t\t field, data)) {\n"
- "+\t\t\tlog_error(\"dm_report_object: \"\n"
- "+\t\t\t\t  \"report function failed for field %s\",\n"
- "+\t\t\t\t  rh->fields[fp->field_num].id);\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif ((fp->flags & FLD_CMP_MASK) && !_compare_field(field, fp)) {\n"
- "+\t\t\tlist_del(&row->list);\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif ((strlen(field->report_string) > field->props->width))\n"
- "+\t\t\tfield->props->width = strlen(field->report_string);\n"
- "+\n"
- "+\t\tif ((rh->flags & RH_SORT_REQUIRED) &&\n"
- "+\t\t    (field->props->flags & FLD_SORT_KEY)) {\n"
- "+\t\t\t(*row->sort_fields)[field->props->sort_posn] = field;\n"
- "+\t\t}\n"
- "+\t\tlist_add(&row->fields, &field->list);\n"
- "+\t}\n"
- "+\n"
- "+\tif (!(rh->flags & RH_BUFFERED))\n"
- "+\t\treturn dm_report_output(rh);\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Print row of headings\n"
- "+ */\n"
- "+static int _report_headings(void *handle)\n"
- "+{\n"
- "+\tstruct dm_report *rh = handle;\n"
- "+\tstruct field_properties *fp;\n"
- "+\tconst char *heading;\n"
- "+\tchar buf[1024];\n"
- "+\n"
- "+\tif (rh->flags & RH_HEADINGS_PRINTED)\n"
- "+\t\treturn 1;\n"
- "+\n"
- "+\trh->flags |= RH_HEADINGS_PRINTED;\n"
- "+\n"
- "+\tif (!(rh->flags & RH_HEADINGS))\n"
- "+\t\treturn 1;\n"
- "+\n"
- "+\tif (!dm_pool_begin_object(rh->mem, 128)) {\n"
- "+\t\tlog_error(\"dm_report: \"\n"
- "+\t\t\t  \"dm_pool_begin_object failed for headings\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* First heading line */\n"
- "+\tlist_iterate_items(fp, &rh->field_props) {\n"
- "+\t\tif (fp->flags & FLD_HIDDEN)\n"
- "+\t\t\tcontinue;\n"
- "+\n"
- "+\t\theading = rh->fields[fp->field_num].heading;\n"
- "+\t\tif (rh->flags & RH_ALIGNED) {\n"
- "+\t\t\tif (dm_snprintf(buf, sizeof(buf), \"%-*.*s\",\n"
- "+\t\t\t\t\t fp->width, fp->width, heading) < 0)\n"
- "+\t\t\t\tgoto bad_snprintf;\n"
- "+\t\t\tif (!dm_pool_grow_object(rh->mem, buf, fp->width))\n"
- "+\t\t\t\tgoto bad_grow;\n"
- "+\t\t} else if (!dm_pool_grow_object(rh->mem, heading,\n"
- "+\t\t\t\t\t\tstrlen(heading)))\n"
- "+\t\t\tgoto bad_grow;\n"
- "+\n"
- "+\t\tif (!list_end(&rh->field_props, &fp->list))\n"
- "+\t\t\tif (!dm_pool_grow_object(rh->mem, rh->separator,\n"
- "+\t\t\t\t\t      strlen(rh->separator)))\n"
- "+\t\t\t\tgoto bad_grow;\n"
- "+\t}\n"
- "+\tif (!dm_pool_grow_object(rh->mem, \"\\0\", 1))\n"
- "+\t\tgoto bad_grow;\n"
- "+\tlog_print(\"%s\", (char *) dm_pool_end_object(rh->mem));\n"
- "+\n"
- "+\treturn 1;\n"
- "+\n"
- "+      bad_snprintf:\n"
- "+\tlog_error(\"dm_report: snprintf heading failed\");\n"
- "+      bad_grow:\n"
- "+\tlog_error(\"dm_report: Failed to generate report headings for printing\");\n"
- "+\tdm_pool_abandon_object(rh->mem);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Sort rows of data\n"
- "+ */\n"
- "+static int _row_compare(const void *a, const void *b)\n"
- "+{\n"
- "+\tconst struct row *rowa = *(const struct row **) a;\n"
- "+\tconst struct row *rowb = *(const struct row **) b;\n"
- "+\tconst struct dm_report_field *sfa, *sfb;\n"
- "+\tint32_t cnt = -1;\n"
- "+\n"
- "+\tfor (cnt = 0; cnt < rowa->rh->keys_count; cnt++) {\n"
- "+\t\tsfa = (*rowa->sort_fields)[cnt];\n"
- "+\t\tsfb = (*rowb->sort_fields)[cnt];\n"
- "+\t\tif (sfa->props->flags & FLD_NUMBER) {\n"
- "+\t\t\tconst uint64_t numa =\n"
- "+\t\t\t    *(const uint64_t *) sfa->sort_value;\n"
- "+\t\t\tconst uint64_t numb =\n"
- "+\t\t\t    *(const uint64_t *) sfb->sort_value;\n"
- "+\n"
- "+\t\t\tif (numa == numb)\n"
- "+\t\t\t\tcontinue;\n"
- "+\n"
- "+\t\t\tif (sfa->props->flags & FLD_ASCENDING) {\n"
- "+\t\t\t\treturn (numa > numb) ? 1 : -1;\n"
- "+\t\t\t} else {\t/* FLD_DESCENDING */\n"
- "+\t\t\t\treturn (numa < numb) ? 1 : -1;\n"
- "+\t\t\t}\n"
- "+\t\t} else {\t/* FLD_STRING */\n"
- "+\t\t\tconst char *stra = (const char *) sfa->sort_value;\n"
- "+\t\t\tconst char *strb = (const char *) sfb->sort_value;\n"
- "+\t\t\tint cmp = strcmp(stra, strb);\n"
- "+\n"
- "+\t\t\tif (!cmp)\n"
- "+\t\t\t\tcontinue;\n"
- "+\n"
- "+\t\t\tif (sfa->props->flags & FLD_ASCENDING) {\n"
- "+\t\t\t\treturn (cmp > 0) ? 1 : -1;\n"
- "+\t\t\t} else {\t/* FLD_DESCENDING */\n"
- "+\t\t\t\treturn (cmp < 0) ? 1 : -1;\n"
- "+\t\t\t}\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\t\t/* Identical */\n"
- "+}\n"
- "+\n"
- "+static int _sort_rows(struct dm_report *rh)\n"
- "+{\n"
- "+\tstruct row *(*rows)[];\n"
- "+\tuint32_t count = 0;\n"
- "+\tstruct row *row;\n"
- "+\n"
- "+\tif (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *\n"
- "+\t\t\t\tlist_size(&rh->rows)))) {\n"
- "+\t\tlog_error(\"dm_report: sort array allocation failed\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tlist_iterate_items(row, &rh->rows)\n"
- "+\t\t(*rows)[count++] = row;\n"
- "+\n"
- "+\tqsort(rows, count, sizeof(**rows), _row_compare);\n"
- "+\n"
- "+\tlist_init(&rh->rows);\n"
- "+\twhile (count--)\n"
- "+\t\tlist_add_h(&rh->rows, &(*rows)[count]->list);\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Produce report output\n"
- "+ */\n"
- "+int dm_report_output(struct dm_report *rh)\n"
- "+{\n"
- "+\tstruct list *fh, *rowh, *ftmp, *rtmp;\n"
- "+\tstruct row *row = NULL;\n"
- "+\tstruct dm_report_field *field;\n"
- "+\tconst char *repstr;\n"
- "+\tchar buf[4096];\n"
- "+\tint width;\n"
- "+\n"
- "+\tif (list_empty(&rh->rows))\n"
- "+\t\treturn 1;\n"
- "+\n"
- "+\t/* Sort rows */\n"
- "+\tif ((rh->flags & RH_SORT_REQUIRED))\n"
- "+\t\t_sort_rows(rh);\n"
- "+\n"
- "+\t/* If headings not printed yet, calculate field widths and print them */\n"
- "+\tif (!(rh->flags & RH_HEADINGS_PRINTED))\n"
- "+\t\t_report_headings(rh);\n"
- "+\n"
- "+\t/* Print and clear buffer */\n"
- "+\tlist_iterate_safe(rowh, rtmp, &rh->rows) {\n"
- "+\t\tif (!dm_pool_begin_object(rh->mem, 512)) {\n"
- "+\t\t\tlog_error(\"dm_report: \"\n"
- "+\t\t\t\t  \"dm_pool_begin_object failed for row\");\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\t\trow = list_item(rowh, struct row);\n"
- "+\t\tlist_iterate_safe(fh, ftmp, &row->fields) {\n"
- "+\t\t\tfield = list_item(fh, struct dm_report_field);\n"
- "+\t\t\tif (field->props->flags & FLD_HIDDEN)\n"
- "+\t\t\t\tcontinue;\n"
- "+\n"
- "+\t\t\trepstr = field->report_string;\n"
- "+\t\t\twidth = field->props->width;\n"
- "+\t\t\tif (!(rh->flags & RH_ALIGNED)) {\n"
- "+\t\t\t\tif (!dm_pool_grow_object(rh->mem, repstr,\n"
- "+\t\t\t\t\t\t      strlen(repstr)))\n"
- "+\t\t\t\t\tgoto bad_grow;\n"
- "+\t\t\t} else if (field->props->flags & FLD_ALIGN_LEFT) {\n"
- "+\t\t\t\tif (dm_snprintf(buf, sizeof(buf), \"%-*.*s\",\n"
- "+\t\t\t\t\t\t width, width, repstr) < 0)\n"
- "+\t\t\t\t\tgoto bad_snprintf;\n"
- "+\t\t\t\tif (!dm_pool_grow_object(rh->mem, buf, width))\n"
- "+\t\t\t\t\tgoto bad_grow;\n"
- "+\t\t\t} else if (field->props->flags & FLD_ALIGN_RIGHT) {\n"
- "+\t\t\t\tif (dm_snprintf(buf, sizeof(buf), \"%*.*s\",\n"
- "+\t\t\t\t\t\t width, width, repstr) < 0)\n"
- "+\t\t\t\t\tgoto bad_snprintf;\n"
- "+\t\t\t\tif (!dm_pool_grow_object(rh->mem, buf, width))\n"
- "+\t\t\t\t\tgoto bad_grow;\n"
- "+\t\t\t}\n"
- "+\n"
- "+\t\t\tif (!list_end(&row->fields, fh))\n"
- "+\t\t\t\tif (!dm_pool_grow_object(rh->mem, rh->separator,\n"
- "+\t\t\t\t\t\t      strlen(rh->separator)))\n"
- "+\t\t\t\t\tgoto bad_grow;\n"
- "+\t\t\tlist_del(&field->list);\n"
- "+\t\t}\n"
- "+\t\tif (!dm_pool_grow_object(rh->mem, \"\\0\", 1))\n"
- "+\t\t\tgoto bad_grow;\n"
- "+\t\tlog_print(\"%s\", (char *) dm_pool_end_object(rh->mem));\n"
- "+\t\tlist_del(&row->list);\n"
- "+\t}\n"
- "+\n"
- "+\tif (row)\n"
- "+\t\tdm_pool_free(rh->mem, row);\n"
- "+\n"
- "+\treturn 1;\n"
- "+\n"
- "+      bad_snprintf:\n"
- "+\tlog_error(\"dm_report: snprintf row failed\");\n"
- "+      bad_grow:\n"
- "+\tlog_error(\"dm_report: Failed to generate row for printing\");\n"
- "+\tdm_pool_abandon_object(rh->mem);\n"
- "+\treturn 0;\n"
- "+}\n"
- "Index: device-mapper/lib/Makefile.in\n"
- "===================================================================\n"
- "--- device-mapper.orig/lib/Makefile.in\t2007-01-12 15:21:52.000000000 -0500\n"
- "+++ device-mapper/lib/Makefile.in\t2007-01-12 15:36:55.000000000 -0500\n"
- "@@ -24,6 +24,7 @@ SOURCES =\\\n"
- " \tlibdm-file.c \\\n"
- " \tlibdm-deptree.c \\\n"
- " \tlibdm-string.c \\\n"
- "+\tlibdm-report.c \\\n"
- " \tmm/dbg_malloc.c \\\n"
- " \tmm/pool.c \\\n"
- " \t$(interface)/libdm-iface.c\n"
- "Index: device-mapper/lib/.exported_symbols\n"
- "===================================================================\n"
- "--- device-mapper.orig/lib/.exported_symbols\t2007-01-12 15:21:52.000000000 -0500\n"
- "+++ device-mapper/lib/.exported_symbols\t2007-01-12 15:36:55.000000000 -0500\n"
- "@@ -115,3 +115,16 @@ dm_split_lvm_name\n"
- " dm_split_words\n"
- " dm_snprintf\n"
- " dm_basename\n"
- "+dm_report_init\n"
- "+dm_report_object\n"
- "+dm_report_output\n"
- "+dm_report_free\n"
- "+dm_report_get_private\n"
- "+dm_report_field_string\n"
- "+dm_report_field_int32\n"
- "+dm_report_field_uint32\n"
- "+dm_report_field_int\n"
- "+dm_report_field_uint64\n"
- "+dm_report_field_raw\n"
- "+dm_report_field_set_string\n"
- +dm_report_field_set_sort_value
- "\01:3\0"
- "b\0"
+ "Jun'ichi Nomura, NEC Corporation of America\n"
+ "-------------- next part --------------\n"
+ "A non-text attachment was scrubbed...\n"
+ "Name: 01-libdm-report.patch\n"
+ "Type: text/x-patch\n"
+ "Size: 33117 bytes\n"
+ "Desc: not available\n"
+ URL: <http://listman.redhat.com/archives/lvm-devel/attachments/20070112/6486edb7/attachment.bin>
 
-7756bdc8b52f946e2b8e13166ebb2a88631e9920bba874db046bc1fdcec642ea
+69b21ff7cec78358a4bb95a15535594b07d401c6f9e2f49c73902e9e852743be

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.