[lvm-devel] master - report: adapt selection code to recognize per-field reserved values

Peter Rajnoha prajnoha at fedoraproject.org
Fri Jul 4 14:00:24 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0956fd230fea550707acb2889223438996102de4
Commit:        0956fd230fea550707acb2889223438996102de4
Parent:        da545ce3b471e76b3ebcfcb5528118d8dd9264df
Author:        Peter Rajnoha <prajnoha at redhat.com>
AuthorDate:    Fri Jul 4 11:21:38 2014 +0200
Committer:     Peter Rajnoha <prajnoha at redhat.com>
CommitterDate: Fri Jul 4 15:50:50 2014 +0200

report: adapt selection code to recognize per-field reserved values

In contrast to per-type reserved values that are applied for all fields
of that type, per-field reserved values are only applied for concrete
field only.

Also add 'struct dm_report_field_reserved_value' to libdm for per-field
reserved value definition. This is defined by field number (an index
in the 'fields' array which is given for the dm_report_init_with_selection
function during report initialization) and the value to use for any
of the specified reserved names.
---
 libdm/libdevmapper.h |   27 ++++++++++++
 libdm/libdm-report.c |  112 +++++++++++++++++++++++++++++++++-----------------
 2 files changed, 101 insertions(+), 38 deletions(-)

diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ad504da..dc3da78 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1633,6 +1633,7 @@ struct dm_report_field;
 #define DM_REPORT_FIELD_ALIGN_LEFT		0x00000001
 #define DM_REPORT_FIELD_ALIGN_RIGHT		0x00000002
 #define DM_REPORT_FIELD_TYPE_MASK		0x00000FF0
+#define DM_REPORT_FIELD_TYPE_NONE		0x00000000
 #define DM_REPORT_FIELD_TYPE_STRING		0x00000010
 #define DM_REPORT_FIELD_TYPE_NUMBER		0x00000020
 #define DM_REPORT_FIELD_TYPE_SIZE		0x00000040
@@ -1658,9 +1659,35 @@ struct dm_report_field_type {
 	const char *desc;	/* description of the field */
 };
 
+/*
+ * Per-field reserved value.
+ */
+struct dm_report_field_reserved_value {
+	/* field_num is the position of the field in 'fields'
+	   array passed to dm_report_init_with_selection */
+	uint32_t field_num;
+	/* the value is of the same type as the field
+	   identified by field_num */
+	const void *value;
+};
+
+/*
+ * Reserved value is a 'value' that is used directly if any of the 'names' is hit.
+ *
+ * If type is any of DM_REPORT_FIELD_TYPE_*, the reserved value is recognized
+ * for all fields of that type.
+ *
+ * If type is DM_REPORT_FIELD_TYPE_NONE, the reserved value is recognized
+ * for the exact field specified - hence the type of the value is automatically
+ * the same as the type of the field itself.
+ *
+ * The array of reserved values is used to initialize reporting with
+ * selection enabled (see also dm_report_init_with_selection function).
+ */
 struct dm_report_reserved_value {
 	const unsigned type;		/* DM_REPORT_FIELD_TYPE_* */
 	const void *value;		/* reserved value:
+						struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE
 						uint64_t for DM_REPORT_FIELD_TYPE_NUMBER
 						uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
 						uint64_t for DM_REPORT_FIELD_TYPE_PERCENT
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 00c3d3f..ad89cf2 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1599,6 +1599,18 @@ static int _tok_op_cmp(const char *s, const char **end)
 	return _tok_op(_op_cmp, s, end, 0);
 }
 
+static char _get_and_skip_quote_char(char const **s)
+{
+	char c = 0;
+
+	if (**s == '"' || **s == '\'') {
+		c = **s;
+		(*s)++;
+	}
+
+	return c;
+}
+
  /*
   *
   * Input:
@@ -1689,38 +1701,62 @@ static const char *_tok_value_string(const char *s,
 	return s;
 }
 
+static const char *_reserved_name(const char **names, const char *s, size_t len)
+{
+	const char **name = names;
+	while (*name) {
+		if ((strlen(*name) == len) && !strncmp(*name, s, len))
+			return *name;
+		name++;
+	}
+	return NULL;
+}
+
 /*
  * Used to replace a string representation of the reserved value
  * found in selection with the exact reserved value of certain type.
  */
-static const char *_get_reserved_value(struct dm_report *rh, unsigned type,
-				       const char *s, const char **begin, const char **end,
-				       const struct dm_report_reserved_value **reserved)
-{
-	const struct dm_report_reserved_value *iter = rh->reserved_values;
-	const char **name;
+static const char *_get_reserved(struct dm_report *rh, unsigned type,
+				 uint32_t field_num, int implicit,
+				 const char *s, const char **begin, const char **end,
+				 const struct dm_report_reserved_value **reserved)
+{
+	const struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
+	const char *tmp_begin, *tmp_end, *tmp_s = s;
+	const char *name = NULL;
+	char c;
 
 	*reserved = NULL;
 
 	if (!iter)
 		return s;
 
-	while (iter->type) {
-		if (iter->type & type) {
-			name = iter->names;
-			while (*name) {
-				if (!strcmp(*name, s)) {
-					*begin = s;
-					*end = s += strlen(*name);
-					*reserved = iter;
-					return s;
-				}
-				name++;
-			}
+	c = _get_and_skip_quote_char(&tmp_s);
+	if (!(tmp_s = _tok_value_string(tmp_s, &tmp_begin, &tmp_end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL)))
+		return s;
+
+	while (iter->value) {
+		if (!iter->type) {
+			/* DM_REPORT_FIELD_TYPE_NONE - per-field reserved value */
+			if (((((const struct dm_report_field_reserved_value *) iter->value)->field_num) == field_num) &&
+			    (name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+				break;
+		} else if (iter->type & type) {
+			/* DM_REPORT_FIELD_TYPE_* - per-type reserved value */
+			if ((name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+				break;
 		}
 		iter++;
 	}
 
+	if (name) {
+		/* found! */
+		*begin = tmp_begin;
+		*end = tmp_end;
+		s = tmp_s;
+		*reserved = iter;
+	}
+
 	return s;
 }
 
@@ -1880,18 +1916,6 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
 	return 1;
 }
 
-static char _get_and_skip_quote_char(char const **s)
-{
-	char c = 0;
-
-	if (**s == '"' || **s == '\'') {
-		c = **s;
-		(*s)++;
-	}
-
-	return c;
-}
-
 /*
  * Input:
  *   ft              - field type for which the value is parsed
@@ -2033,8 +2057,10 @@ bad:
  */
 static const char *_tok_value(struct dm_report *rh,
 			      const struct dm_report_field_type *ft,
-			      const char *s, const char **begin,
-			      const char **end, uint32_t *flags,
+			      uint32_t field_num, int implicit,
+			      const char *s,
+			      const char **begin, const char **end,
+			      uint32_t *flags,
 			      const struct dm_report_reserved_value **reserved,
 			      struct dm_pool *mem, void *custom)
 {
@@ -2046,7 +2072,7 @@ static const char *_tok_value(struct dm_report *rh,
 
 	s = _skip_space(s);
 
-	s = _get_reserved_value(rh, expected_type, s, begin, end, reserved);
+	s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, reserved);
 	if (*reserved) {
 		*flags |= expected_type;
 		return s;
@@ -2149,6 +2175,14 @@ static const char *_tok_field_name(const char *s,
 	return s;
 }
 
+static const void *_get_reserved_value(const struct dm_report_reserved_value *reserved)
+{
+	if (reserved->type)
+		return reserved->value;
+	else
+		return ((const struct dm_report_field_reserved_value *) reserved->value)->value;
+}
+
 static struct field_selection *_create_field_selection(struct dm_report *rh,
 						       uint32_t field_num,
 						       int implicit,
@@ -2229,7 +2263,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
 		switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
 			case DM_REPORT_FIELD_TYPE_STRING:
 				if (reserved) {
-					fs->v.s = (const char *) reserved->value;
+					fs->v.s = (const char *) _get_reserved_value(reserved);
 					dm_pool_free(rh->mem, s);
 				} else {
 					fs->v.s = s;
@@ -2241,7 +2275,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
 				break;
 			case DM_REPORT_FIELD_TYPE_NUMBER:
 				if (reserved)
-					fs->v.i = *(uint64_t *) reserved->value;
+					fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
 				else {
 					if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
 						 (errno == ERANGE)) {
@@ -2257,7 +2291,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
 				break;
 			case DM_REPORT_FIELD_TYPE_SIZE:
 				if (reserved)
-					fs->v.d = (double) * (uint64_t *) reserved->value;
+					fs->v.d = (double) * (uint64_t *) _get_reserved_value(reserved);
 				else {
 					fs->v.d = strtod(s, NULL);
 					if (errno == ERANGE) {
@@ -2276,7 +2310,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
 				break;
 			case DM_REPORT_FIELD_TYPE_PERCENT:
 				if (reserved)
-					fs->v.i = *(uint64_t *) reserved->value;
+					fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
 				else {
 					fs->v.d = strtod(s, NULL);
 					if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
@@ -2508,7 +2542,9 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
 			custom = &str_list;
 		else
 			custom = NULL;
-		if (!(last = _tok_value(rh, ft, last, &vs, &ve, &flags, &reserved, rh->mem, custom)))
+		if (!(last = _tok_value(rh, ft, field_num, implicit,
+					last, &vs, &ve, &flags,
+					&reserved, rh->mem, custom)))
 			goto_bad;
 	}
 




More information about the lvm-devel mailing list