#!/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.c.tmpl" 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 ") 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()