11 from argparse
import ArgumentParser
14 parser = ArgumentParser()
15 parser.add_argument(
"files", type=str, nargs=
'*', help=
"files to parse")
16 parser.add_argument(
"-o",
"--output", type=str, help=
"output")
17 parser.add_argument(
"-m",
"--module", type=str, help=
"module")
18 parsed = parser.parse_args()
20 output = parsed.output
21 module = parsed.module
32 "int":(
"integer(c_int)",
"c_int"),
33 "long":(
"integer(c_long)",
"c_long"),
34 "short":(
"integer(c_short)",
"c_short"),
35 "_Bool":(
"logical(c_bool)",
"c_bool"),
36 "boolean":(
"logical(c_bool)",
"c_bool"),
37 "double": (
"real(c_double)",
"c_double"),
38 "float":(
"real(c_float)",
"c_float"),
39 "size_t": (
"integer(c_size_t)",
"c_size_t"),
44 "long double": (
"real(c_long_double)",
"c_long_double"),
45 "unsigned long":(
"integer(c_long)",
"c_long"),
46 "unsigned short":(
"integer(c_short)",
"c_short"),
47 "unsigned int":(
"integer(c_int)",
"c_int"),
54 Exception.__init__(self, message)
59 REGEX_RETURNED_TYPE = re.compile(
"^ *([_0-9a-zA-Z ]+ *\**&?)" )
60 REGEX_FUNCTION_NAME = re.compile(
"([0-9a-zA-Z_]+) *\(" )
61 REGEX_ARGUMENTS = re.compile(
"\(([&0-9a-zA-Z_\s\,\*\[\]]*)\).*;$" )
62 REGEX_ARGS = re.compile(
" *([&0-9a-zA-Z_\s\*\[\]]+),?" )
63 REGEX_VAR_TYPE = re.compile(
" *([_0-9a-zA-Z]+)[ |\*]" )
64 REGEX_TYPE = re.compile(
"^ *((const )?\w+)[ \*]?" )
65 REGEX_VAR_NAME = re.compile(
"[ |\*&]([_0-9a-zA-Z]+)(?:\[\])?$" )
68 """Split a long line in a multiline, following Fortran syntax.""" 70 while len(line) > maxlength-1:
71 result += line[0:maxlength-1] +
"&\n" 72 line =
"&"+ line[maxlength-1:]
77 """ Returns the Fortran type corresponding to a C type in the 78 ISO_C_BINDING module and the KIND type """ 83 c_type = REGEX_TYPE.search(declaration).group(1)
84 except AttributeError:
88 if declaration.find(
"[") != -1:
89 array =
", dimension(*)" 94 if declaration.find(
"*") != -1:
97 if ((c_type.find(
"char") != -1)
or (c_type.find(
"char*") != -1))
and (
not returned):
98 if declaration.find(
"**") != -1:
99 return "type(c_ptr), dimension(*)",
"c_ptr" 101 return "character(kind=c_char), dimension(*)",
"c_char" 103 return "type(c_ptr)",
"c_ptr" 106 if len(declaration.split()) >= 3:
107 for each
in TYPES2_DICT:
108 if set(each.split()).issubset(
set(declaration.split())):
109 return TYPES2_DICT[each][0] + array, TYPES2_DICT[each][1]
111 for each
in TYPES_DICT:
112 if each
in c_type.split():
113 return TYPES_DICT[each][0] + array, TYPES_DICT[each][1]
120 type_returned = REGEX_RETURNED_TYPE.search(c_line)
122 function_type = type_returned.group(1)
123 except AttributeError:
124 raise ParsingError,
"Returned type not found "+ c_line
127 if (function_type.find(
"void") != -1)
and (function_type.find(
"*") == -1):
128 f_procedure =
"subroutine " 129 f_the_end =
"end subroutine" 133 f_procedure =
"function " 134 f_the_end =
"end function" 136 returned_type, iso_c =
iso_c_binding(type_returned.group(1),
True)
138 if returned_type.find(
"?") != -1:
140 raise ParsingError,
"Unknown data type: " + type_returned.group(1) +
" " + c_line
143 function_name = REGEX_FUNCTION_NAME.search(c_line)
145 f_name = function_name.group(1)
146 except AttributeError:
147 raise ParsingError,
"Function name not found "+c_line
149 arguments = REGEX_ARGUMENTS.search(c_line)
151 args = REGEX_ARGS.findall(arguments.group(1))
152 except AttributeError:
153 raise ParsingError,
"Arguments not found " + c_line
161 var_type = REGEX_VAR_TYPE.search(arg).group(1)
162 except AttributeError:
163 raise ParsingError,
"Variable type not found " + c_line
166 if iso_c
not in used_types:
167 used_types.append(iso_c)
169 if f_type.find(
"c_") != -1:
174 REGEX_ISO_C = re.compile(
"("+iso_c+
")"+
"([^\w]|$)" )
175 if REGEX_ISO_C.search(f_use) ==
None:
176 f_use +=
", " + iso_c
177 elif f_type.find(
"?") != -1:
178 raise ParsingError,
"Unknown data type: " + arg +
" " + c_line
182 var_name = REGEX_VAR_NAME.search(arg).group(1)
183 except AttributeError:
184 raise ParsingError,
"Variable name not found "+c_line+
" "+arg
188 if (f_type.find(
"(*)") != -1):
191 if (arg.find(
"&") != -1):
196 declarations += 1*TAB + f_type + passvar +
" :: " + var_name +
"\n" 200 args_list +=
", " + var_name
201 interface = 0*TAB +
"! " + c_line +
"\n" 202 first_line = 0*TAB + f_procedure + f_name +
"(" + args_list +
') bind(c,name="{f_name}")'.
format(f_name=f_name)
204 interface +=
multiline(first_line, 79) +
" \n" 206 interface += 1*TAB +
"use iso_c_binding, only: " + f_use +
"\n" 208 interface += 1*TAB + returned_type +
" :: " + f_name +
"\n" 209 interface += declarations
210 interface += 0*TAB + f_the_end +
"\n\n" 215 file_name, file_ext = os.path.splitext(c_file)
216 with open(c_file,
'r') as open_file: 217 text = open_file.read() 219 text = re.sub(
'(?ms).*?extern "C"\s*{',
'', text)
220 text = re.sub(
'(?ms)}.*$',
'', text)
221 text = re.sub(
'(?ms)^\s+',
'', text)
222 lines = [ line.strip()
for line
in text.strip().splitlines() ]
227 module_name = file_name.split(
'/')[-1]+
"_c_binding" 228 with open(f_file_path,
'w')
as f_file:
230 f_file_header =
"! Automatically generated by c2f.py on {time}\n".
format(time=time.asctime(time.localtime()))
231 f_file_header +=
"! Based on file {filename}\n".
format(filename=c_file)
232 f_file_header +=
"! Please do not modify.\n" 234 f_file.write(f_file_header+
"\nmodule {module_name}\nimplicit none\ninterface\n\n".
format(module_name=module_name))
239 except ParsingError, e:
240 print(
"\n----------------------------------------\n"+
241 "Parsing failed for file\n "+c_file+
" : \n"+
str(e)+
242 "\n----------------------------------------\n"+text)
243 f_file.write(
"end interface\nend module {module_name}\n".
format(module_name=module_name))
l_size ! loop over number of fields ke do je do ie to je n if(.NOT. d_comm%R_do_buf(list)) cycle from_pe
def __init__(self, message)
def multiline(line, maxlength)
def iso_c_binding(declaration, returned)