summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/distutils/conv_template.py114
1 files changed, 69 insertions, 45 deletions
diff --git a/numpy/distutils/conv_template.py b/numpy/distutils/conv_template.py
index 591ae54ad..f9510b843 100644
--- a/numpy/distutils/conv_template.py
+++ b/numpy/distutils/conv_template.py
@@ -46,7 +46,7 @@ def parse_structure(astr):
_special_names = {}
template_re = re.compile(r"@([\w]+)@")
-named_re = re.compile(r"#([\w]*)=([^#]*?)#")
+named_re = re.compile(r"#\s*([\w]*)\s*=\s*([^#]*)#")
parenrep = re.compile(r"[(]([^)]*?)[)]\*(\d+)")
def paren_repl(obj):
@@ -55,15 +55,15 @@ def paren_repl(obj):
return ','.join([torep]*int(numrep))
plainrep = re.compile(r"([^*]+)\*(\d+)")
-
def conv(astr):
# replaces all occurrences of '(a,b,c)*4' in astr
- # with 'a,b,c,a,b,c,a,b,c,a,b,c'
+ # with 'a,b,c,a,b,c,a,b,c,a,b,c'. The result is
+ # split at ',' and a list of values returned.
astr = parenrep.sub(paren_repl,astr)
# replaces occurences of xxx*3 with xxx, xxx, xxx
astr = ','.join([plainrep.sub(paren_repl,x.strip())
for x in astr.split(',')])
- return astr
+ return astr.split(',')
def unique_key(adict):
# this obtains a unique key given a dictionary
@@ -82,52 +82,75 @@ def unique_key(adict):
return newkey
def expand_sub(substr, namestr, line):
- # find all named replacements
+ # find all named replacements in the various loops.
reps = named_re.findall(namestr)
+ nsubs = None
+ loops = []
names = {}
names.update(_special_names)
- numsubs = None
for rep in reps:
name = rep[0].strip()
- thelist = conv(rep[1])
- names[name] = thelist
-
- # make lists out of string entries in name dictionary
- for name in names.keys():
- entry = names[name]
- entrylist = entry.split(',')
- names[name] = entrylist
- num = len(entrylist)
- if numsubs is None:
- numsubs = num
- elif numsubs != num:
- print namestr
- print substr
+ vals = conv(rep[1])
+ size = len(vals)
+ if name == "repeat" :
+ names[None] = nsubs
+ loops.append(names)
+ nsubs = None
+ names = {}
+ continue
+ if nsubs is None :
+ nsubs = size
+ elif nsubs != size :
+ print name
+ print vals
raise ValueError, "Mismatch in number to replace"
-
- # now replace all keys for each of the lists
- mystr = ''
- thissub = [None]
+ names[name] = vals
+ names[None] = nsubs
+ loops.append(names)
+
+ # generate list of dictionaries, one for each template iteration
+ def merge(d1,d2) :
+ tmp = d1.copy()
+ tmp.update(d2)
+ return tmp
+
+ dlist = [{}]
+ for d in loops :
+ nsubs = d.pop(None)
+ tmp = [{} for i in range(nsubs)]
+ for name, item in d.items() :
+ for i in range(nsubs) :
+ tmp[i][name] = item[i]
+ dlist = [merge(d1,d2) for d1 in dlist for d2 in tmp]
+
+ # now replace all keys for each of the dictionaries
def namerepl(match):
name = match.group(1)
- return names[name][thissub[0]]
- for k in range(numsubs):
- thissub[0] = k
- mystr += ("#line %d\n%s\n\n"
- % (line, template_re.sub(namerepl, substr)))
+ return d[name]
+
+ mystr = []
+ header = "#line %d\n"%line
+ for d in dlist :
+ code = ''.join((header, template_re.sub(namerepl, substr), '\n'))
+ mystr.append(code)
+
return mystr
-_head = \
-"""/* This file was autogenerated from a template DO NOT EDIT!!!!
- Changes should be made to the original source (.src) file
-*/
+header =\
+"""
+/*
+ *****************************************************************************
+ ** This file was autogenerated from a template DO NOT EDIT!!!! **
+ ** Changes should be made to the original source (.src) file **
+ *****************************************************************************
+ */
"""
def get_line_header(str,beg):
extra = []
- ind = beg-1
+ ind = beg - 1
char = str[ind]
while (ind > 0) and (char != '\n'):
extra.insert(0,char)
@@ -136,25 +159,24 @@ def get_line_header(str,beg):
return ''.join(extra)
def process_str(allstr):
- newstr = allstr
- writestr = _head
+ code = [header]
+ struct = parse_structure(allstr)
- struct = parse_structure(newstr)
# return a (sorted) list of tuples for each begin repeat section
# each tuple is the start and end of a region to be template repeated
-
oldend = 0
for sub in struct:
- writestr += newstr[oldend:sub[0]]
- expanded = expand_sub(newstr[sub[1]:sub[2]],
- newstr[sub[0]:sub[1]], sub[4])
- writestr += expanded
+ pref = allstr[oldend:sub[0]]
+ head = allstr[sub[0]:sub[1]]
+ text = allstr[sub[1]:sub[2]]
+ line = sub[4]
oldend = sub[3]
+ code.append(pref)
+ code.extend(expand_sub(text,head,line))
+ code.append(allstr[oldend:])
+ return ''.join(code)
- writestr += newstr[oldend:]
- return writestr
-
include_src_re = re.compile(r"(\n|\A)#include\s*['\"]"
r"(?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
@@ -184,6 +206,7 @@ def process_file(source):
return ('#line 1 "%s"\n%s'
% (sourcefile, process_str(''.join(lines))))
+
if __name__ == "__main__":
try:
@@ -200,3 +223,4 @@ if __name__ == "__main__":
allstr = fid.read()
writestr = process_str(allstr)
outfile.write(writestr)
+