summaryrefslogtreecommitdiffstats
path: root/extras/create_new_xlator/generate_xlator.py
blob: 983868c04db6d78d2d6429a2be20c7de3622bdc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/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 <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()