Welcome to mirror list, hosted at ThFree Co, Russian Federation.

make_free_functions.py « scripts - github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: aed899ed2d91b7f3f69d8e82fb01c67e5b16df24 (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
#!/usr/bin/python
# Look for all static member functions marked LLFIO_MAKE_FREE_FUNCTION and make them free
# (C) 2017 Niall Douglas

from __future__ import print_function
import glob, re

for header in glob.glob("../include/afio/*/*.hpp"):
    with open(header, "rt") as ih:
        lines = ih.readlines()
    current_class = None
    functions_to_be_freed = []
    functions_to_be_freed_begin = -1
    functions_to_be_freed_end = -1
    for lineidx in range(0, len(lines)):
        if lines[lineidx].startswith('class'):
            current_class = lines[lineidx][6:lines[lineidx].find(':')]
            current_class = current_class.replace('LLFIO_DECL', '').lstrip().rstrip()
        if 'LLFIO_MAKE_FREE_FUNCTION' in lines[lineidx] and re.match('\s*LLFIO_MAKE_FREE_FUNCTION', lines[lineidx]):
            function = ''
            for n in range(1, 100):
               if 'LLFIO_REQUIRES' in lines[lineidx+n]:
                   continue
               function += lines[lineidx+n]
               if lineidx+n+1 >= len(lines):
                   print(lines[lineidx:])
                   raise Exception()
               if '{' in lines[lineidx+n+1] or ';' in lines[lineidx+n]:
                   break
            function = function.replace('//\n', '')
            function = function.replace('\n', '')
            function = function.replace(';', '')
            docs = ''
            if '*/' in lines[lineidx-1] or '//!' in lines[lineidx-1]:
                for n in range(1, 100):
                   if '//!' in lines[lineidx-n] or '/*!' in lines[lineidx-n]:
                       docs = ''.join(lines[lineidx-n:lineidx])
                       # Remove any indent
                       docs = docs.replace('\n  ', '\n')[2:]
                       break
            functions_to_be_freed.append((current_class, function, docs))
        elif '// BEGIN make_free_functions.py' in lines[lineidx]:
            functions_to_be_freed_begin = lineidx
        elif '// END make_free_functions.py' in lines[lineidx]:
            functions_to_be_freed_end = lineidx
    if functions_to_be_freed:
        if functions_to_be_freed_begin != -1:
            del lines[functions_to_be_freed_begin+1:functions_to_be_freed_end]
        else:
            # Place just before the last LLFIO_V2_NAMESPACE_END
            functions_to_be_freed_begin = len(lines)-1
            while not lines[functions_to_be_freed_begin].startswith('LLFIO_V2_NAMESPACE_END'):
                functions_to_be_freed_begin = functions_to_be_freed_begin - 1
            lines.insert(functions_to_be_freed_begin, '// END make_free_functions.py\n\n')
            lines.insert(functions_to_be_freed_begin, '// BEGIN make_free_functions.py\n')
        idx = functions_to_be_freed_begin + 1
        for classname, function, docs in functions_to_be_freed:
            print((classname, function))
            function = function.replace('virtual ', '')
            function = function.replace('override', '')
            function = function.replace('LLFIO_HEADERS_ONLY_MEMFUNC_SPEC ', '')
            function = function.replace('LLFIO_HEADERS_ONLY_VIRTUAL_SPEC ', '')
            completion_template = 'template <class CompletionRoutine>' in function
            function = function.replace('template <class CompletionRoutine> ', '')
            is_static = 'static ' in function
            function = function.replace('static ', '')
            function = function.lstrip()
            if not function.startswith('inline'):
                function = 'inline ' + function
            if completion_template:
                function = 'template <class CompletionRoutine> ' + function
            def replace(function, item):
                function = function.replace(' '+item+' ', ' '+classname+'::'+item+' ')
                function = function.replace('('+item+' ', '('+classname+'::'+item+' ')
                function = function.replace('<'+item+',', '<'+classname+'::'+item+',')
                function = function.replace('<'+item+'>', '<'+classname+'::'+item+'>')
                function = function.replace(' '+item+'>', ' '+classname+'::'+item+'>')
                return function
            function = replace(function, 'path_view_type')
            function = replace(function, 'extent_type')
            function = replace(function, 'size_type')
            function = replace(function, 'buffer_type')
            function = replace(function, 'const_buffer_type')
            function = replace(function, 'enumerate_info')
            function = replace(function, 'buffers_type')
            function = replace(function, 'const_buffers_type')
            function = replace(function, 'io_state_ptr')
            function = function.replace('path_view_type()', classname+'::path_view_type()')
            function = function.replace(' io_result<', ' '+classname+'::io_result<')
            function = function.replace(' io_request<', ' '+classname+'::io_request<')
            function = function.replace('(io_request<', '('+classname+'::io_request<')
            function = function.replace('<io_state_ptr<', '<'+classname+'::io_state_ptr<')
            function = function.replace('<awaitable<', '<'+classname+'::awaitable<')
            function = function.replace(' mode ', ' '+classname+'::mode ')
            function = function.replace(' mode::', ' '+classname+'::mode::')
            function = function.replace(' creation ', ' '+classname+'::creation ')
            function = function.replace(' creation::', ' '+classname+'::creation::')
            function = function.replace(' caching ', ' '+classname+'::caching ')
            function = function.replace(' caching::', ' '+classname+'::caching::')
            function = function.replace(' flag ', ' '+classname+'::flag ')
            function = function.replace(' flag::', ' '+classname+'::flag::')
            function = function.replace(' filter ', ' '+classname+'::filter ')
            function = function.replace(' filter::', ' '+classname+'::filter::')
            if function[-2] == ';':
                function=function[:-2]
            elif '}' in function:
                function = function[:function.rfind('{')] + function[function.rfind('}')+1:]
            function = function.rstrip()
            idx1 = function.rfind('const')
            idx2 = function.rfind(')')
            is_const = False
            if idx1 > idx2:
                function = function[:idx1] + function[idx1+6:]
                function = function.rstrip()
                is_const = True
            idx1 = function.rfind('= 0')
            if idx1 > idx2:
                function = function[:idx1] + function[idx1+3:]
                function = function.rstrip()
            if is_static:
                call = function
                impl = "\n{\n  return "+classname+"::"
            else:
                call = function
                idx1 = function.find('(')
                idx2 = function.rfind(')')
                function = function[:idx1+1] + (('const ' + classname) if is_const else classname) + (' &self, ' if idx1+1 != idx2 else ' &self') + function[idx1+1:]
                impl = "\n{\n  return self."
                idx1 = docs.find('\\param')
                if idx1 != -1:
                    docs = docs[:idx1] + '\param self The object whose member function to call.\n' + docs[idx1:]
            
            #print(call)
            call = re.sub(r'^.+?(?= [^ ]+\()', '', call)  # remove anything before the function call
            #print(call)
            call = re.sub(r'(?<=\) ).*', '', call)  # remove anything after the function call
            #print(call)
            call = re.sub(r'".*?"', '', call)  # remove any string literals
            #print(call)
            call = re.sub(r'\s?=.+?(?:\(.*?\))?(?=[,)])', '', call)  # remove all default initialisers
            #print(call)
            impl += re.match(r'.+\(', call).group(0).lstrip()
            first = True
            for par in re.finditer(r'\w*[,)]', call):
                if not first:
                    impl += ' '
                else:
                    first = False
                p = par.group(0)
                if p == ')':
                    impl += ')'
                else:
                    impl += 'std::forward<decltype('+p[:-1]+')>('+p[:-1]+')'+p[-1]
            impl += ";\n}\n"
            lines.insert(idx, function+impl)
            lines.insert(idx, docs)
            idx = idx + 2
        with open(header, "wt") as oh:
            oh.writelines(lines)