import sys
import string
from cStringIO import StringIO
class UFuncType:
def __init__(self):
self.type = None
self.fake_type = None
def SetType(self, type):
self.type = type
def SetFake(self, type):
self.fake_type = type
def GetCast(self):
pass
def IsResulte10(self):
if self.type == 'erf' or self.type == 'erd':
return 1
return 0
def IsResult(self):
if self.type == 'rf' or self.type == 'rd':
return 1
return 0
def __GetType(self, type, argumentnumber):
t = type
if t == 'f':
return "float"
if t == 'd':
return "double"
if t == 'i':
return "int"
if t == 'ui':
return "unsigned int"
if t == 'rd':
return "double"
if t == 'erd':
if argumentnumber == 2:
return "int"
return "double"
if t == 'erf':
if argumentnumber == 2:
return "int"
return "float"
if t == 'rf':
return "float"
if t == 'm':
return "gsl_mode_t"
raise ValueError, "Unknown Type %s " % self.type
def GetFakeType(self, argumentnumber):
if self.fake_type:
return self.__GetType(self.fake_type, argumentnumber)
return None
def GetType(self, argumentnumber):
return self.__GetType(self.type, argumentnumber)
def GetNArgs(self):
if self.type == 'rf' or self.type == 'rd':
return 2
if self.type == 'erf' or self.type == 'erd':
return 3
return 1
class UFuncWriter:
_namecheck = "PyGSL_sf_ufunc_"
_namecheck_l = len(_namecheck)
_prototype = "(char **args, int *dimensions, int *steps, void *func)"
def __init__(self, line):
self.description = None
self.funccast = None
self.in_types = []
self.out_types = []
self.error_check = None
self.__faker = 0
description = string.split(line, ':')[0]
assert(description[:self._namecheck_l] == self._namecheck)
self.description = description
description = description[self._namecheck_l:]
self.__definetypes(description)
def __definetypes(self, description):
# Is this type a fakeing one ?
argument_types = string.split(description, "_as_")
#print argument_types,
arguments = None
fakes = None
if len(argument_types) == 1:
self.__faker = 0
arguments = argument_types[0]
elif len(argument_types) == 2:
arguments = argument_types[0]
fakes =argument_types[1]
self.__faker = 1
else:
raise ValueError, "More than one as in Type string!"
if fakes:
self.funccast = self._namecheck + fakes
else:
self.funccast = self._namecheck + arguments
# Split the in from the out args:
#print arguments,
in_types, out_types = string.split(arguments, "_")
#print in_types, out_types
in_fake_types, out_fake_types = None, None
if fakes:
in_fake_types, out_fake_types = string.split(fakes, "_")
assert(len(in_types) == len(in_fake_types))
assert(len(out_types) == len(out_fake_types))
self.__add_types(self.in_types, in_types, in_fake_types)
self.__add_types(self.out_types, out_types, out_fake_types)
# Iterate over the real types.
#print "ins", self.in_types
#print "outs", self.out_types
#print
def __add_types(self, list, arguments, fakes):
i = 0
while i < len(arguments):
tmp = UFuncType()
#multi letter descriptions
typedescr_end = i + 1
t = arguments[i]
if t == 'r' or t == 'u':
typedescr_end = i + 2
if t == 'e':
typedescr_end = i + 3
descr = arguments[i:typedescr_end]
tmp.SetType(descr)
if fakes:
test = fakes[i:typedescr_end]
if test != descr:
tmp.SetFake(test)
list.append(tmp)
i = typedescr_end
def add_in_types(self):
counter = 0
for i in self.in_types:
for j in range(i.GetNArgs()):
if counter > 0:
print ",",
test = 0
try:
fake = i.GetFakeType(j)
if fake:
print "(%s)*((%s *)ip%d)" % (fake, i.GetType(j), counter),
else:
print "*((%s *)ip%d)" % (i.GetType(j),counter),
test = 1
finally:
if test == 0:
sys.stderr.write("self.funccast = %s\n" % self.funccast)
counter += 1
return counter
def function_call_with_flag(self):
print "\t\t{"
print "\t\tint flag;"
counter = 0
# need temporary variables
for i in self.out_types:
if i.IsResult():
print "\t\tgsl_sf_result r%d;" % counter
elif i.IsResulte10():
print "\t\tgsl_sf_result_e10 r%d;" % counter
elif i.GetFakeType(0):
print "%s tmp%d;" % (i.GetFakeType(0), counter)
counter += 1;
print "\t\tflag = ((%s *) func)(" % (self.funccast),
# function call
if self.add_in_types():
print ",",
counter = 0
out_counter = 0
for i in self.out_types:
if counter > 0:
print ",",
test = 0
try:
if i.IsResult():
print "r%d" % counter,
counter += 1
elif i.IsResulte10():
print "r%d" % counter,
counter += 1
elif i.GetFakeType(0):
print "tmp%d" % counter,
counter += 1
else:
print "(%s *)op%d" % (i.GetType(0), out_counter),
test = 1
finally:
if test == 0:
sys.stderr.write("self.funccast = %s\n" % self.funccast)
out_counter += 1
print ")"
print "\t\tif (flag != GSL_SUCCESS){"
out_counter = 0;
for i in self.out_types:
for j in range(i.GetNArgs()):
print "\t\t\t*(%s) op%d = (%s) gsl_nan()" %(i.GetType(j), out_counter, i.GetType(j))
out_counter += 1
print "\t\t\treturn;"
print "\t\t}"
# readout
counter = 0
out_counter = 0
for i in self.out_types:
test = 0
try:
if i.IsResult() or i.IsResulte10():
if i.GetFakeType(0):
print "\t\t*(%s) op%d = (%s) r%d.val;" % (i.GetType(0), out_counter, i.GetType(0), counter)
print "\t\t*(%s) op%d = (%s) r%d.err;" % (i.GetType(1), out_counter+1,i.GetType(1), counter)
else:
print "\t\t*(%s) op%d = r%d.val;" % (i.GetType(0), out_counter, counter)
print "\t\t*(%s) op%d = r%d.err;" % (i.GetType(1), out_counter+1, counter)
counter += 1
out_counter +=2
if i.IsResulte10():
print "\t\t*(int) op%d = r%d.e10;" % (out_counter, counter)
out_counter +=1
elif i.GetFakeType(0):
print "\t\t(%s) op%d = (%s) tmp%d" %(i.GetType(0), out_counter, i.GetType(0), counter),
counter += 1
out_counter += 1
test = 1
finally:
if test == 0:
sys.stderr.write("self.funccast = %s\n" % self.funccast)
out_counter += 1
print "\t\t}"
def function_call_without_flag(self):
fake = self.out_types[0].GetFakeType(0)
if fake:
print "\t\t*(%s *)op0 = (%s)((%s *) func)(" % (fake, self.out_types[0].GetType(0), self.funccast),
else:
print "\t\t*(%s *)op0 = ((%s *) func)(" % (self.out_types[0].GetType(0), self.funccast),
self.add_in_types()
print ");"
def __call__(self):
stream = StringIO()
save = sys.stdout
sys.stdout = stream
counter = 0
in_counter = 0
out_counter = 0
try:
print "void %s (char **args, int *dimensions, int *steps, void *func){" % self.description
print "\tint i, ",
for i in self.in_types:
for j in range(i.GetNArgs()):
if counter > 0:
print ",",
print "is%d=steps[%d]" % (in_counter,counter),
counter += 1
in_counter +=1
for i in self.out_types:
for j in range(i.GetNArgs()):
if counter > 0:
print ",",
print "os%d=steps[%d]" % (out_counter,counter),
counter += 1
out_counter +=1
print ";"
counter = 0
in_counter = 0
out_counter = 0
print "\tchar ",
for i in self.in_types:
for j in range(i.GetNArgs()):
if counter > 0:
print ",",
print "*ip%d=args[%d]" % (in_counter,counter),
counter += 1
in_counter +=1
for i in self.out_types:
for j in range(i.GetNArgs()):
if counter > 0:
print ",",
print "*op%d=args[%d]" % (out_counter,counter),
counter += 1
out_counter +=1
print ";"
print "\tfor(i = 0; i<dimensions[0]; i++){"
counter = 0
in_counter = 0
out_counter = 0
for i in self.in_types:
for j in range(i.GetNArgs()):
print "\t\tip%d+=is%d;" % (in_counter,in_counter)
counter += 1
in_counter +=1
for i in self.out_types:
for j in range(i.GetNArgs()):
print "\t\top%d+=os%d;" % (out_counter,out_counter)
counter += 1
out_counter +=1
#print "x = (float*)ip1;"
#print "mode = (int *) ip2;"
funccast = self.funccast
use_error_flag = 0
if 'r' in funccast or 'e' in funccast:
use_error_flag = 1
self.function_call_with_flag()
else:
test = 0
if len(self.out_types) != 1:
sys.stderr.write("Not wrapping %s!\n" % funccast)
else:
self.function_call_without_flag()
print "\t}"
# uses gsl_sf_result or gsl_sf_result_e10_
#print "flag = ((PyGSL_DOUBLE_FUNC_di_dd *)func)((double)*x, (gsl_mode_t) *mode, &result);"
# Use some heuristics to guess the out type.
#if (flag == GSL_SUCCESS){
# *(float *)op1 = (float)result.val;
# *(float *)op2 = (float)result.err;
# } else {
# *(float *)op1 = (float)gsl_nan();
# *(float *)op2 = (float)gsl_nan();
# invoke_error_handler(__FILE__, __FUNCTION__, i, flag);
# }
#}
print "}"
stream.seek(0)
return stream.read()
finally:
sys.stdout = save
def run():
file = open("sf__ufuncs.txt")
out = open("sf_evals.c", "w")
for line in file.readlines():
out.write(UFuncWriter(line)())
if __name__ == '__main__':
run()
syntax highlighted by Code2HTML, v. 0.9.1