10config_file = sys.argv[2]
12if os.path.exists(root+
'/config.json'):
13 config_file = root +
'/config.json'
16with open(config_file,
'r', encoding=
'utf-8')
as load_f:
18 data = json.load(load_f)
20decro_list = [
'const',
'static',
'inline',
'virtual',
'constexpr']
21type_list = [
'void',
'bool',
'int',
'double',
'kids_real',
'kids_complex',
22 'std::string',
'std::map',
'enum',
'class',
'namespace']
25 decro1, decro2 =
'',
''
28 res = re.search(
'<(.*?)>', line, re.S)
32 line = re.sub(old,
'<__>', line)
34 tmpsx = re.split(
'\(|;|\{', line)
35 tmps0 = tmpsx[0].split(
' ')
36 while '' in tmps0: tmps0.remove(
'')
54 xxx2 = re.split(
'=', xxx)[0]
55 tmps0 = re.split(
' |,|;', xxx2)
56 while '' in tmps0: tmps0.remove(
'')
66 typeinfo = re.sub(
'<__>', old, typeinfo)
68 if se_type ==
'_fun' and typeinfo ==
'':
71 return decro1, typeinfo, decro2, flags, se_type
75 this function remove c-style comment of in the text
77 pn1 = re.compile(
'//.*')
78 pn2 = re.compile(
'\/\*(?:[^\*]|\*+[^\/\*])*\*+\/')
79 txt = re.sub(pn1,
'', txt)
80 txt = re.sub(pn2,
'', txt)
85 this function split comma, such as
86 <double, std::string>, <std::map<int, double>>, <<int>, 2>
90 res = re.search(
'(<[^<]*?>)', line, re.S)
93 _dd += [ line[i1:i2] ]
95 line = line[:i1] +
"I__%d__I"%len(_dd) + line[i2:]
96 res = re.search(
'(<[^<]*?>)', line, re.S)
98 line = re.sub(
',',
'@', line)
101 line = line.replace(
"I__%d__I"%len(_dd), _dd[-1])
104 return line.split(
'@')
107 typi = re.sub(
' +?',
' ', typi)
108 typi = re.sub(
'(\w) (\w)',
r'\1I__0__I\2', typi)
109 typi = re.sub(
' ',
'', typi)
110 typi = re.sub(
'I__0__I',
' ', typi)
115 this function split (unique) typeinfo & variable name.
122 const std::sting &abc_d[];
126 _tmps = re.split(
';|=', term)[0].strip()
130 res = re.search(
'\[.*?$', _tmps, re.S)
133 _tmps, liter = _tmps[:i1], _tmps[i1:i2]
135 res = re.search(
'[\w]*?$', _tmps, re.S)
138 typi = _tmps[:i1] + liter
147 this function split multiple typeinfo & variable name.
149 "const int *a, b, **c;"
159 res = re.search(
'(\W)*?$', type0, re.S)
165 for i
in range(1, len(_tmps)):
166 res = re.search(
'^(\W)*?\w', _tmps[i], re.S)
171 typex += _tmps[i][i1:i2-1]
172 namex = _tmps[i][i2-1:]
177 return arg_type, arg_name
187 ds[i+1] = ds[i][ks[i]]
190 ds[i+1] = ds[i][ks[i]]
192 if ks[-1]
not in ds[-1]:
195 if(isinstance(c, list)):
197 if(isinstance(c, set)):
199 if(isinstance(c, str)):
200 ds[-1][ks[-1]] +=
'\n' + c
201 if(isinstance(c, dict)):
202 ds[-1][ks[-1]] = dict( ds[-1][ks[-1]].items() + c.items())
209 for i
in range(istart, len(lines)):
210 cnt_1 += lines[i].count(
'(')
211 cnt_2 += lines[i].count(
'{')
212 max_1 = max(max_1, cnt_1)
213 max_2 = max(max_2, cnt_2)
214 cnt_1 -= lines[i].count(
')')
215 cnt_2 -= lines[i].count(
'}')
216 if cnt_1 == 0
and cnt_2 == 0:
217 return i, max_1, max_2
228 return arg_type, arg_name
235 scope_attr = init_attr
237 if il >= len(lines):
break
240 if line.strip() ==
'' or line[0] ==
'#':
245 if 'public:' in line:
246 scope_attr =
'public'
249 if 'protected:' in line:
250 scope_attr =
'protected'
253 if 'private:' in line:
254 scope_attr =
'private'
258 if 'DEFINE_POINTER' in line:
259 tmps = re.split(
' |,|\(|\)', line)
260 while '' in tmps: tmps.remove(
'')
264 {flag: {
'_type':
'EigMX<%s>'%tmps[1],
'_raw': line.strip(),
'_attr': scope_attr}}
271 content =
'\n'.join(lines[il:il2+1])
275 if m1 == 0
and se_type !=
'_var':
278 arg_type, arg_name = [], []
279 if se_type ==
'_fun' or se_type ==
'_init':
284 flag : {
'_type': typi,
'_raw': content.strip(),
'_attr': scope_attr
285 ,
'_arg_type':
', '.join(arg_type)
286 ,
'_arg_name':
', '.join(arg_name)
293 f = open(fn,
'r',encoding=
'utf-8')
294 txt =
''.join(f.readlines())
299 "deps": re.findall(
'#include "(.*?)"', txt, re.S)
304 lines = txt.split(
'\n'); il = 0
306 if il >= len(lines):
break
309 if line.strip() ==
'' or line[0] ==
'#':
313 terms = line.split(
' ')
314 if terms[0] ==
'using':
315 while ';' not in lines[il]:
321 if terms[0] ==
'namespace':
323 kstring = kstring +
'.' + flag
324 dict_append(info, kstring, {
'_type':
'namespace',
'_var': []})
326 parse_scope(info, kstring, lines[il+1:il2],
'public')
327 kstring =
'.'.join(kstring.split(
'.')[:-1])
331 if terms[0] ==
'class' or terms[0] ==
'struct' :
335 superclass = terms[4]
336 kstring = kstring +
'.' + flag
337 dict_append(info, kstring, {
'_type': terms[0],
'_superclass': superclass,
338 '_var':[],
'_fun':[],
'_init':[],
'_bind':[],
341 parse_scope(info, kstring, lines[il+1:il2],
'private')
342 kstring =
'.'.join(kstring.split(
'.')[:-1])
348 content =
'\n'.join(lines[il:il2+1])
352 if m1 == 0
and se_type !=
'_var':
357 flag : {
'_type': typi,
'_raw': content.strip(),
'_attr': scope_attr}}
368for i
in data[
'models']:
369 list1 = glob.glob(os.path.abspath(root+
'/'+i))
371 objs += [
'%s.h'%j[:-4] ]
373for i
in data[
'solvers']:
374 list1 = glob.glob(os.path.abspath(root+
'/'+i))
376 objs += [
'%s.h'%j[:-4] ]
388infos = {
'incl': [],
'deps':[],
'': {}}
390 infos1 = {
'incl': [],
'deps':[],
'': {}}
393 infos1[
'incl'] += [ info[
'name'] ]
394 for j
in info[
'deps']:
395 infos1[
'deps'] += [ os.path.abspath(
396 os.path.dirname(info[
'name']) +
'/' + j
398 infos1[
''] = {**infos1[
''], **info[
'']}
400 infos[
'incl'] += infos1[
'incl']
401 infos[
'deps'] += infos1[
'deps']
402 infos[
''] = {**infos[
''], **infos1[
'']}
404 s1 = set(infos[
'deps'])
405 s2 = set(infos[
'incl'])
409 if 'opendf/models' in i
or 'opendf/solvers' in i:
426 if '_superclass' in dd[child]
and dd[child][
'_superclass'] !=
'':
427 return child +
', ' +
get_fathers(dd, dd[child][
'_superclass'])
431 for f
in dd[ns][
'_fun']:
433 if f[i][
'_type']
not in type_list:
435 if 'virtual' in f[i][
'_raw']:
436 virtual_in_name =
'PYBIND11_OVERRIDE'
437 if ') = 0;' in f[i][
'_raw']:
438 virtual_in_name =
'PYBIND11_OVERRIDE_PURE'
440 tag =
'%s(%s)'%(i, f[i][
'_arg_type'])
445 token = f[i][
'_raw'].split(
')')[0] +
')'
446 token = token.replace(
'virtual ',
'')
455 }'''%(token, virtual_in_name,
466 class PyTrampoline_%s : public %s {
468 using %s::%s;'''%(ns, ns, ns, ns)
473 while dd[ns1][
'_superclass'] !=
'':
474 ns1 = dd[ns1][
'_superclass']
502 for f
in dd[ns][
'_init']:
504 print(
'\n .def(py::init<%s>())'%f[i][
'_arg_type'], end=
'')
507 for f
in dd[ns][
'_var']:
509 if f[i][
'_attr'] ==
'public':
510 if f[i][
'_type']
in [
'int',
'double',
'kids_real',
'kids_complex',
511 'std::string',
'bool']
and i[0]!=
'*':
512 print(
'\n .def_readwrite("%s", &%s::%s)'%(
517 for f
in dd[ns][
'_bind']:
519 print(
'\n .def("ref_%s", &%s::ref_%s, py::return_value_policy::reference_internal)'%(
524 for f
in dd[ns][
'_fun']:
526 if f[i][
'_type']
not in type_list
or 'kids_complex*' in f[i][
'_raw']:
529 if i ==
'name' and ns != ns0:
531 if 'static' in f[i][
'_raw']:
532 print(
'\n .def_static("%s", &%s::%s)'%
536 elif '*' not in f[i][
'_arg_type']:
537 print(
'\n .def("%s", static_cast<%s (%s::*)(%s)>(&%s::%s))'%
539 i, f[i][
'_type'], ns, f[i][
'_arg_type'], ns, i
546 for k
in range(len(arg_type)):
547 if arg_type[k][-1] ==
'*':
548 arg_type[k] =
'py::array_t<%s, py::array::c_style | py::array::forcecast>'%arg_type[k][:-1]
549 arg_name1 += [arg_name[k]+
'_arr']
550 arg_name2 += [arg_name[k]+
'_arr.mutable_data()']
552 arg_name1 += [arg_name[k]]
553 arg_name2 += [arg_name[k]]
554 pairs += [arg_type[k] +
' ' + arg_name1[k]]
555 print(
'\n .def("%s", [](%s& self, %s) {\n return self.%s(%s); \n }\n )'%
557 i, ns,
', \n '.join(pairs), i,
', '.join(arg_name2)
562 if dd[ns][
'_superclass'] !=
'':
563 tplname =
'%s, %s'%(ns, dd[ns][
'_superclass'])
564 tplname +=
', PyTrampoline_%s'%(ns)
567 print(
' py::class_<%s>(%s, "%s", py::dynamic_attr())'
568 %(tplname, field, ns), end=
'')
575 while dd[ns1][
'_superclass'] !=
'':
576 ns1 = dd[ns1][
'_superclass']
582#include <pybind11/embed.h>
583#include <pybind11/numpy.h>
584#include <pybind11/eigen.h>
585#include <pybind11/complex.h>
586#include <pybind11/pybind11.h>
587#include <pybind11/stl.h>
589for i
in infos[
'incl']:
590 print(
'#include "%s"'%os.path.relpath(i, root+
'/python'))
595#include "../utils/definitions.h"
597namespace py = pybind11;
600PYBIND11_MODULE(libopendf, m) {
602 #include "opendf_phys.bind"
604 py::module models_m = m.def_submodule("models");
605 py::module solvers_m = m.def_submodule("solvers");
614 if (ns
not in created_class
617 and 'Atomic_BasisSet' not in ns
618 and 'PPIMD' not in ns
620 if dd[ns][
'_superclass'] !=
'':
629 created_class += [ns]
632 if '_type' in dd[ns]
and dd[ns][
'_type'] ==
'class':
creat_trampoline_fun(ns, ns0, dd, coll)
sweep_scope(lines, istart)
parse_scope(info, kstring, lines, init_attr)
safe_split_comma(line_in)
creat_class_(ns, dd, field)
parse_type_and_name_multiple(term)
creat_class_fun(ns, ns0, dd)
parse_decro_type_flag(line)
parse_type_and_name(term)