Skip to content

Instantly share code, notes, and snippets.

@certik
Created June 8, 2011 00:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save certik/1013569 to your computer and use it in GitHub Desktop.
Save certik/1013569 to your computer and use it in GitHub Desktop.
Generate .pxd from Fortran sources
#! /usr/bin/env python
import os
import sys
from optparse import OptionParser
import re
def main():
parser = OptionParser(usage="[options] filename")
# parser.add_option("-n", "--no-upload",
# action="store_false", dest="upload",
# default=True, help="Do not upload the results into the pull request")
# parser.add_option("--reference",
# action="store", type="str", dest="reference",
# default=None, help="Passes this to 'git clone <sympy repo>'")
options, args = parser.parse_args()
if len(args) == 1:
arg, = args
parse_file(arg)
return
elif len(args) == 0:
pass
else:
print "Too many arguments"
sys.exit(1)
parser.print_help()
def parse_file(filename):
code = open(filename).read()
pxd = """\
# This file is automatically generated by fparser from '%s'.
# Do not edit by hand (rerun fparser instead).
from libcpp cimport bool
""" % filename
for subroutine in find_subroutines(code):
pxd += "cdef extern " + get_c_signature(subroutine) + "\n"
name, ext = os.path.splitext(filename)
pxd_filename = name + ".pxd"
open(pxd_filename, "w").write(pxd)
print "'%s' created." % pxd_filename
def find_subroutines(code):
s2 = 0
while True:
s1 = code.find("subroutine", s2)
if s1 == -1:
break
s2 = code.find("end subroutine", s1) + 14
yield code[s1:s2]
def get_c_signature(code):
assert code[:10] == "subroutine"
name = code[11:code.find("(")]
params = get_vars(code[12 + len(name):code.find(")")])
params = [get_param_type(param, code) + param for param in params]
return "void " + name + "(" + ", ".join(params) + ")"
def get_vars(code):
return [x.strip(" &").strip() for x in code.split(",")]
def get_param_type(param, code):
for line in code.split("\n"):
if line.find("intent") != -1:
args = get_vars(line[line.find("::")+2:])
args = [just_name(x) for x in args]
args = [x.lower() for x in args]
if param.lower() in args:
if line.find("c_int") != -1:
return "int *"
elif line.find("c_double") != -1:
return "double *"
elif line.find("c_bool") != -1:
return "bool *"
else:
print line
print param
raise Exception("Unkown type")
print code
print param
raise Exception("Param not found")
def just_name(arg):
i = arg.find("(")
if i != -1:
return arg[:i]
return arg
if __name__ == "__main__":
main()
#! /usr/bin/env python
# Generates .pxd files for dftatom.
from os.path import dirname, abspath
from os import system
root = dirname(dirname(abspath(__file__)))
system("cd %s; utils/fparser src/c_dftatom.f90" % root)
system("cd %s; cp src/c_dftatom.pxd dftatom/rdirac/rdirac.pxd" % root)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment