glusterfs/extras/create_new_xlator/generate_xlator.py
Kaleb S. KEITHLEY af0d5a9b53 core: python3
see https://review.gluster.org/#/c/19788/,
    https://review.gluster.org/#/c/19871/,
    https://review.gluster.org/#/c/19952/,
    https://review.gluster.org/#/c/20104/,
    https://review.gluster.org/#/c/20162/,
    https://review.gluster.org/#/c/20185/,
    https://review.gluster.org/#/c/20207/,
    https://review.gluster.org/#/c/20227/,
    https://review.gluster.org/#/c/20307/,
    https://review.gluster.org/#/c/20320/,
    https://review.gluster.org/#/c/20332/,
    https://review.gluster.org/#/c/20364/,
    https://review.gluster.org/#/c/20441/, and
    https://review.gluster.org/#/c/20484

shebangs changed from /usr/bin/python2 to /usr/bin/python3.
(Reminder, various distribution packaging guidelines require use
of explicit python version and don't allow '#!/usr/bin/env python',
regardless of how handy that idiom may be.)

glusterfs.spec(.in) package python{2,3}-gluster and python2 or
python3 dependencies as appropriate.

configure(.ac):
+ test for and use python2 or python3 as appropriate. If build
  machine has python2 and python3, use python3. Override by
  setting PYTHON=/usr/bin/python2 when running configure.
+ PYTHONDEV_CPPFLAGS from python[23]-config --includes is a
  better match to the original python sysconfig.get_python_inc().
  All those other extraneous flags breaks the build.
+ Only change the shebangs once. Changing them over and over
  again, e.g., during a `make glusterrpms` in extras/LinuxRPM
  just sends make (is it really make that's looping?) into an
  infinite loop. If you figure out why, let me know.
+ Oldest python2 is python2.6 on CentOS 6 and Debian 8 (Jessie).
  Everything else has 2.7 or 3.x
+ logic from https://review.gluster.org/c/glusterfs/+/21050, which
  needs to be removed/merged after that patch is merged.

Builds on CentOS 6, CentOS 7, Fedora 28, Fedora rawhide, and the
mysterious RHEL > 7.

Change-Id: Idae21d3b6f58b32372e1daa0d234e491e563198f
updates: #411
Signed-off-by: Kaleb S. KEITHLEY <kkeithle@redhat.com>
2018-09-03 09:14:44 +00:00

209 lines
7.4 KiB
Python
Executable File

#!/usr/bin/python3
from __future__ import print_function
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
MAKEFILE_FMT = """
xlator_LTLIBRARIES = @XL_NAME@.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/@XL_TYPE@
@XL_NAME_NO_HYPHEN@_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
@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 \
-I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/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 = list(zip(types, names))
# Convert each sub-tuple into a "type name" string.
as_strings = [' '.join(item) for item in as_tuples]
# Join all of those into one big string.
return ',\n\t'.join(as_strings)
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@"] = ', '.join(w_arg_names)
sdict["@UNWIND_ARGS@"] = ', '.join(u_arg_names)
sdict["@ERROR_ARGS@"] = ', '.join(list(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@"] = ''.join(ret_type)
sdict["@RET_VAR@"] = ''.join(ret_var)
for old, new in sdict.items():
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(COPYRIGHT, file=xl)
print(fragments["INCLUDE_IN_SRC_FILE"].replace("@XL_NAME@",
xl_name), file=xl)
#Generate cbks and fops
for fop in ops:
print(generate(fragments["CBK_TEMPLATE"], fop, ops), file=xl)
print(generate(fragments["FOP_TEMPLATE"], fop, ops), file=xl)
for cbk in xlator_cbks:
print(generate(fragments["FUNC_TEMPLATE"], cbk,
xlator_cbks), file=xl)
for dops in xlator_dumpops:
print(generate(fragments["FUNC_TEMPLATE"], dops,
xlator_dumpops), file=xl)
#Generate fop table
print("struct xlator_fops fops = {", file=xl)
for fop in ops:
print(" .{0:20} = {1}_{2},".format(fop, fop_prefix, fop), file=xl)
print("};", file=xl)
#Generate xlator_cbks table
print("struct xlator_cbks cbks = {", file=xl)
for cbk in xlator_cbks:
print(" .{0:20} = {1}_{2},".format(cbk, fop_prefix, cbk), file=xl)
print("};", file=xl)
#Generate xlator_dumpops table
print("struct xlator_dumpops dumpops = {", file=xl)
for dops in xlator_dumpops:
print(" .{0:20} = {1}_{2},".format(dops, fop_prefix, dops), file=xl)
print("};", file=xl)
xlator_methods = fragments["XLATOR_METHODS"].replace("@XL_NAME@", xl_name)
xlator_methods = xlator_methods.replace("@FOP_PREFIX@", fop_prefix)
print(xlator_methods, file=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(COPYRIGHT, file=h)
txt = fragments["HEADER_FMT"].replace("@HFL_NAME@", upname)
txt = txt.replace("@XL_NAME@", xl_name)
print(txt, file=h)
h.close()
h = open(src_dir_path+"/"+xl_name+"-mem-types.h", 'w+')
print(COPYRIGHT, file=h)
txt = fragments["MEM_HEADER_FMT"].replace("@HFL_NAME@", upname+"_MEM_TYPES")
txt = txt.replace("@FOP_PREFIX@", fop_prefix)
print(txt, file=h)
h.close()
h = open(src_dir_path+"/"+xl_name+"-messages.h", 'w+')
print(COPYRIGHT, file=h)
txt = fragments["MSG_HEADER_FMT"].replace("@HFL_NAME@", upname+"_MESSAGES")
txt = txt.replace("@FOP_PREFIX@", fop_prefix.upper())
print(txt, file=h)
h.close()
def gen_makefiles():
m = open(dir_path+"/Makefile.am", 'w+')
print("SUBDIRS = src\n\nCLEANFILES =", file=m)
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(txt, file=m)
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()