[lvm-devel] [PATCH 02/30] Add lvm_object_prop.pl to generate liblvm object property functions.
Dave Wysochanski
dwysocha at redhat.com
Mon May 11 13:01:15 UTC 2009
The intent of this perl code, lvm_object_prop.pl, is to help maintain
liblvm object property consistency with the reporting commands pvs, vgs, lvs.
As new fields get added to columns.h, we should re-run this script on the new
FIELD line(s), take the generated code, edit as appropriate, and place into
appropriate liblvm code file.
This patch adds the perl file, lvm_object_prop.pl. A later patch will
add the files this code generates, namely the liblvm object property
function header and C file, lvm_object_prop.[ch].
NOTE: The term 'attribute' is used in some of the reporting fields (for
example, vg_attr), so we avoid it here and instead use the term 'properties'
or 'prop'.
Signed-off-by: Dave Wysochanski <dwysocha at redhat.com>
---
lib/report/lvm_object_prop.pl | 232 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 232 insertions(+), 0 deletions(-)
create mode 100644 lib/report/lvm_object_prop.pl
diff --git a/lib/report/lvm_object_prop.pl b/lib/report/lvm_object_prop.pl
new file mode 100644
index 0000000..824d33a
--- /dev/null
+++ b/lib/report/lvm_object_prop.pl
@@ -0,0 +1,232 @@
+#!/usr/bin/perl
+#
+# Take the colunms.h file as input and produce a header and
+# default code for liblvm object property accessor and mutator functions.
+# To run: perl lvm_object_prop.pl < columns.h
+#
+# For maintenance purposes, when adding a new line to columns.h,
+# we can pipe the diff to this program to generate the new prototypes
+# and C code, then cut/paste into the proper liblvm files.
+#
+
+sub write_code_header;
+sub write_code_body;
+sub write_code_body_get;
+sub write_code_footer;
+sub write_include_header;
+sub write_include_body;
+sub write_include_footer;
+
+#
+# Open the files and write the headers
+#
+$outfile = "lvm_object_prop";
+open(INCLUDE_FILE, ">./$outfile.h") || die "Cannot open $outfile.h!\n";
+write_include_header(INCLUDE_FILE);
+open(CODE_FILE, ">./$outfile.c") || die "Cannot open $outfile.c!\n";
+write_code_header(CODE_FILE);
+
+#
+# Write the include and code body
+#
+while(<>) {
+ # Skip if line does not begin w/"FIELD" - not perfect but does the job
+ if ($_ !~ /^FIELD/) {
+ next;
+ }
+ # Pull out the actual parameters to the FIELD macro
+ m%FIELD\((.*)\)%;
+ $_ = $1;
+
+ #FIELD(LVS, lv, STR, "LV UUID", lvid.id[1], 38, uuid, "lv_uuid", "Unique identifier")
+ # NOTE: I tried using Text:CSV but could not make it work.
+ # Parse using brute force regex
+ m%(\S+),\s*(\S+),\s*(\S+),\s*(\".*\"),\s*(\S+),\s*(\S+),\s*(\S+),\s*(\".*\"),\s*(\".*\")%;
+ ($type, $strct, $sorttype, $head, $field, $width, $func, $id, $desc) =
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9);
+
+ #
+ # Fixup the id / field name / attribute name
+ #
+
+ # Unquote 'id' (field name) and description
+ $id =~ tr/"//d;
+ $desc =~ tr/"//d;
+
+ # Skip redundant fields
+ if ($id =~ /^(stripesize|regionsize|chunksize)$/) {
+ next;
+ }
+
+ # Map report type to liblvm object name
+ # - PVS, VGS, LVS reports, the liblvm object is pv/vg/lv
+ # - PVSEG, the object is pvseg
+ # - SEG, the object is lvseg
+ # - LABEL, the object is pv
+ if ($type =~ /^PVS$/) {
+ $object = "pv";
+ } elsif ($type =~ /^VGS$/) {
+ $object = "vg";
+ } elsif ($type =~ /^LVS$/) {
+ $object = "lv";
+ } elsif ($type =~ /^LABEL$/) {
+ $object = "pv";
+ } elsif ($type =~ /^SEGS$/) {
+ $object = "lvseg";
+ } elsif ($type =~ /^PVSEGS$/) {
+ $object = "pvseg";
+ } else {
+ print "Skipping type: $type, line: $_\n"; #DEBUG
+ next;
+ }
+
+ # lv_kernel_major and lv_kernel_minor are 'STR' but we make them uint64_t here
+ # as this seems more appropriate and easier to manage.
+ if ($id =~ /^(lv_kernel_major|lv_kernel_minor)$/) {
+ $prop_type = "uint64_t ";
+ } elsif ($sorttype =~ m/STR/) {
+ $prop_type = "char *";
+ } else {
+ $prop_type = "uint64_t ";
+ }
+
+ # Some field names/ids contain the struct name, while others don't.
+ # For consistency, if the field name contains the struct name, remove
+ # it (we always put the object name in the function name.
+ #
+ if ($id =~ /^$strct/) {
+ $id = substr($id,length($strct)+1,length($id));
+ }
+
+ # Write 'get' prototype to header and code to C file.
+ write_include_body(INCLUDE_FILE, $object, $id, $desc, $prop_type);
+ write_code_body(CODE_FILE, $object, $id, $desc, $prop_type, $func, $field);
+}
+
+write_include_footer(INCLUDE_FILE);
+write_code_footer(CODE_FILE);
+close(INCLUDE_FILE);
+close(CODE_FILE);
+
+sub write_include_header
+{
+ my($file) = @_;
+ print $file <<END_INCLUDE_HEADER;
+/*
+ * Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * 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 Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_OBJECT_PROP_H
+#define _LVM_OBJECT_PROP_H
+
+END_INCLUDE_HEADER
+}
+
+sub write_include_body
+{
+ my($file, $object, $id, $desc, $prop_type) = @_;
+ #
+ # Use the description and field name in the comment
+ #
+ print $file "/**\n";
+ print $file " * "."lvm_"."$object"."_{get|set}_$id\n";
+ print $file " * $id - $desc\n";
+ print $file " */\n";
+ # Write out 'get' method prototype
+ $fun_name = "lvm_"."$object"."_get_$id";
+ $fun_args = "(const $object"."_t *$object)";
+ print $file "$prop_type"."$fun_name"."$fun_args".";\n";
+ # Write out 'set' method prototype
+ $fun_name = "lvm_"."$object"."_set_$id";
+ $fun_args = "($object"."_t *$object, const $prop_type"."value)";
+ print $file "int "."$fun_name"."$fun_args".";\n\n";
+}
+
+sub write_include_footer
+{
+ my($file) = @_;
+ print $file <<END_INCLUDE_FOOTER;
+#endif
+END_INCLUDE_FOOTER
+}
+
+sub write_code_header
+{
+ my($file) = @_;
+ print $file <<END_CODE_HEADER;
+/*
+ * Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * 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 Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser 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 "lvm.h"
+#include "lib.h"
+#include "metadata-exported.h"
+
+END_CODE_HEADER
+}
+
+sub write_code_body_get
+{
+ my($file, $object, $func, $field, $fun_name, $prop_type, $id) = @_;
+
+ if ($func =~ /^(int32|uint32|size32|size64)$/) {
+ $code = "\treturn $object->$field;";
+ } else {
+ $code = "\t/* FIXME: implement function body */\n\treturn 0;";
+ }
+ print $file <<END_CODE_GET;
+{
+$code
+}
+END_CODE_GET
+}
+
+sub write_code_body
+{
+ my($file, $object, $id, $desc, $prop_type, $func, $field) = @_;
+ print $file "/**\n";
+ print $file " * "."lvm_"."$object"."_{get|set}_$id\n";
+ print $file " * $id - $desc\n";
+ print $file " */\n";
+ # Write out 'get' method
+ $fun_name = "lvm_"."$object"."_get_$id";
+ $fun_args = "(const $object"."_t *$object)";
+ print $file "$prop_type"."$fun_name"."$fun_args"."\n";
+ write_code_body_get($file, $object, $func, $field, $fun_name, $prop_type, $id);
+
+ # Write out 'set' method; all sets require internal logic so no autogeneration
+ $fun_name = "lvm_"."$object"."_set_$id";
+ $fun_args = "($object"."_t *$object, const $prop_type"."value)";
+ print $file "int "."$fun_name"."$fun_args"."\n";
+ $code = "\t/* FIXME: implement function body */\n\treturn -1;";
+ print $file <<END_CODE_SET;
+{
+$code
+}
+END_CODE_SET
+}
+
+
+sub write_code_footer
+{
+# nothing to do
+}
--
1.6.0.6
More information about the lvm-devel
mailing list