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.