summaryrefslogtreecommitdiffstats
path: root/extras/create_new_xlator/generate_xlator.py
diff options
context:
space:
mode:
authorPoornima G <pgurusid@redhat.com>2015-12-15 00:19:41 -0500
committerJeff Darcy <jdarcy@redhat.com>2016-03-22 11:51:07 -0700
commit056bce103c31be8416bd3ede93c7258c5b3f8554 (patch)
tree419d25f903163237abad2b2e4e9041bec556a6ad /extras/create_new_xlator/generate_xlator.py
parent2eb8758bbc88b182bf0e33506b8352cd82c7ec2e (diff)
extras: Ease creation of new xlators
Add a python generator that creates a template for new xlator. Co-Authored by Jeff Darcy. Change-Id: I10820c0483794dcd450656684cf954f7b8f159e0 Signed-off-by: Poornima G <pgurusid@redhat.com> Reviewed-on: http://review.gluster.org/13061 Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'extras/create_new_xlator/generate_xlator.py')
-rwxr-xr-xextras/create_new_xlator/generate_xlator.py205
1 files changed, 205 insertions, 0 deletions
diff --git a/extras/create_new_xlator/generate_xlator.py b/extras/create_new_xlator/generate_xlator.py
new file mode 100755
index 00000000000..30bcdd81c92
--- /dev/null
+++ b/extras/create_new_xlator/generate_xlator.py
@@ -0,0 +1,205 @@
+#!/usr/bin/python
+import os
+import re
+import sys
+import string
+import time
+path = os.path.abspath(os.path.dirname(__file__)) + '/../../libglusterfs/src'
+sys.path.append(path)
+from generator import ops, xlator_cbks, xlator_dumpops
+from config import fops, xl_cbk, dumpops
+
+MAKEFILE_FMT = """
+xlator_LTLIBRARIES = @XL_NAME@.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/@XL_TYPE@
+@XL_NAME_NO_HYPHEN@_la_LDFLAGS = -module -avoid-version
+@XL_NAME_NO_HYPHEN@_la_SOURCES = @XL_NAME@.c
+@XL_NAME_NO_HYPHEN@_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+noinst_HEADERS = @XL_NAME@.h @XL_NAME@-mem-types.h @XL_NAME@-messages.h
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
+AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS)
+CLEANFILES =
+"""
+
+fop_subs = {}
+cbk_subs = {}
+fn_subs = {}
+
+
+def get_error_arg(type_str):
+ if type_str.find(" *") != -1:
+ return "NULL"
+ return "-1"
+
+
+def get_param(names, types):
+ # Convert two separate tuples to one of (name, type) sub-tuples.
+ as_tuples = zip(types, names)
+ # Convert each sub-tuple into a "type name" string.
+ as_strings = map(string.join, as_tuples)
+ # Join all of those into one big string.
+ return string.join(as_strings, ",\n\t")
+
+
+def generate(tmpl, name, table):
+ w_arg_names = [a[1] for a in table[name] if a[0] == 'fop-arg']
+ w_arg_types = [a[2] for a in table[name] if a[0] == 'fop-arg']
+ u_arg_names = [a[1] for a in table[name] if a[0] == 'cbk-arg']
+ u_arg_types = [a[2] for a in table[name] if a[0] == 'cbk-arg']
+ fn_arg_names = [a[1] for a in table[name] if a[0] == 'fn-arg']
+ fn_arg_types = [a[2] for a in table[name] if a[0] == 'fn-arg']
+ ret_type = [a[1] for a in table[name] if a[0] == 'ret-val']
+ ret_var = [a[2] for a in table[name] if a[0] == 'ret-val']
+
+ sdict = {}
+ #Parameters are (t1, var1), (t2, var2)...
+ #Args are (var1, var2,...)
+ sdict["@WIND_ARGS@"] = string.join(w_arg_names, ", ")
+ sdict["@UNWIND_ARGS@"] = string.join(u_arg_names, ", ")
+ sdict["@ERROR_ARGS@"] = string.join(map(get_error_arg, u_arg_types), ", ")
+ sdict["@WIND_PARAMS@"] = get_param(w_arg_names, w_arg_types)
+ sdict["@UNWIND_PARAMS@"] = get_param(u_arg_names, u_arg_types)
+ sdict["@FUNC_PARAMS@"] = get_param(fn_arg_names, fn_arg_types)
+ sdict["@NAME@"] = name
+ sdict["@FOP_PREFIX@"] = fop_prefix
+ sdict["@RET_TYPE@"] = string.join(ret_type, "")
+ sdict["@RET_VAR@"] = string.join(ret_var, "")
+
+ for old, new in sdict.iteritems():
+ tmpl = tmpl.replace(old, new)
+ # TBD: reindent/reformat the result for maximum readability.
+ return tmpl
+
+
+def gen_xlator():
+ xl = open(src_dir_path+"/"+xl_name+".c", 'w+')
+
+ print >> xl, COPYRIGHT
+ print >> xl, fragments["INCLUDE_IN_SRC_FILE"].replace("@XL_NAME@",
+ xl_name)
+
+ #Generate cbks and fops
+ for fop in fops:
+ print >> xl, generate(fragments["CBK_TEMPLATE"], fop, ops)
+ print >> xl, generate(fragments["FOP_TEMPLATE"], fop, ops)
+
+ for cbk in xl_cbk:
+ print >> xl, generate(fragments["FUNC_TEMPLATE"], cbk,
+ xlator_cbks)
+
+ for dops in dumpops:
+ print >> xl, generate(fragments["FUNC_TEMPLATE"], dops,
+ xlator_dumpops)
+
+ print >> xl, fragments["XLATOR_METHODS"]
+
+ #Generate fop table
+ print >> xl, "struct xlator_fops fops = {"
+ for fop in fops:
+ print >> xl, " .{0:20} = {1}_{2},".format(fop, fop_prefix, fop)
+ print >> xl, "};"
+
+ #Generate xlator_cbks table
+ print >> xl, "struct xlator_cbks cbks = {"
+ for cbk in xl_cbk:
+ print >> xl, " .{0:20} = {1}_{2},".format(cbk, fop_prefix, cbk)
+ print >> xl, "};"
+
+ #Generate xlator_dumpops table
+ print >> xl, "struct xlator_dumpops dumpops = {"
+ for dops in dumpops:
+ print >> xl, " .{0:20} = {1}_{2},".format(dops, fop_prefix, dops)
+ print >> xl, "};"
+
+ xl.close()
+
+
+def create_dir_struct():
+ if not os.path.exists(dir_path+"/src"):
+ os.makedirs(dir_path+"/src")
+
+
+def gen_header_files():
+ upname = xl_name_no_hyphen.upper()
+ h = open(src_dir_path+"/"+xl_name+".h", 'w+')
+ print >> h, COPYRIGHT
+ txt = fragments["HEADER_FMT"].replace("@HFL_NAME@", upname)
+ txt2 = fragments["INCLUDE_IN_HEADER_FILE"].replace("@XL_NAME@", xl_name)
+ txt = txt.replace("@INCLUDE_SECT@",txt2)
+ print >> h, txt
+ h.close()
+
+ h = open(src_dir_path+"/"+xl_name+"-mem-types.h", 'w+')
+ print >> h, COPYRIGHT
+ txt = fragments["HEADER_FMT"].replace("@HFL_NAME@", upname+"_MEM_TYPES")
+ txt = txt.replace("@INCLUDE_SECT@", '#include "mem-types.h"')
+ print >> h, txt
+ h.close()
+
+ h = open(src_dir_path+"/"+xl_name+"-messages.h", 'w+')
+ print >> h, COPYRIGHT
+ txt = fragments["HEADER_FMT"].replace("@HFL_NAME@", upname+"_MESSAGES")
+ txt = txt.replace("@INCLUDE_SECT@", '')
+ print >> h, txt
+ h.close()
+
+
+def gen_makefiles():
+ m = open(dir_path+"/Makefile.am", 'w+')
+ print >> m, "SUBDIRS = src\n\nCLEANFILES ="
+ m.close()
+
+ m = open(src_dir_path+"/Makefile.am", 'w+')
+ txt = MAKEFILE_FMT.replace("@XL_NAME@", xl_name)
+ txt = txt.replace("@XL_NAME_NO_HYPHEN@", xl_name_no_hyphen)
+ txt = txt.replace("@XL_TYPE@",xlator_type)
+ print >> m, txt
+ m.close()
+
+def get_copyright ():
+ return fragments["CP"].replace("@CURRENT_YEAR@",
+ time.strftime("%Y"))
+
+def load_fragments ():
+ pragma_re = re.compile('pragma fragment (.*)')
+ cur_symbol = None
+ cur_value = ""
+ result = {}
+ basepath = os.path.abspath(os.path.dirname(__file__))
+ fragpath = basepath + "/new-xlator-tmpl.c"
+ for line in open(fragpath,"r").readlines():
+ m = pragma_re.search(line)
+ if m:
+ if cur_symbol:
+ result[cur_symbol] = cur_value
+ cur_symbol = m.group(1)
+ cur_value = ""
+ else:
+ cur_value += line
+ if cur_symbol:
+ result[cur_symbol] = cur_value
+ return result
+
+if __name__ == '__main__':
+
+ if len(sys.argv) < 3:
+ print "USAGE: ./gen_xlator <XLATOR_DIR> <XLATOR_NAME> <FOP_PREFIX>"
+ sys.exit(0)
+
+ xl_name = sys.argv[2]
+ xl_name_no_hyphen = xl_name.replace("-", "_")
+ if sys.argv[1].endswith('/'):
+ dir_path = sys.argv[1] + xl_name
+ else:
+ dir_path = sys.argv[1] + "/" + xl_name
+ xlator_type = os.path.basename(sys.argv[1])
+ fop_prefix = sys.argv[3]
+ src_dir_path = dir_path + "/src"
+
+ fragments = load_fragments()
+
+ COPYRIGHT = get_copyright()
+ create_dir_struct()
+ gen_xlator()
+ gen_header_files()
+ gen_makefiles()