summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2008-04-23 04:57:00 +0000
committerCharles Harris <charlesr.harris@gmail.com>2008-04-23 04:57:00 +0000
commit99f7707f80dafab4709fd4e833766a24a40ecfc7 (patch)
tree951a8129708d4ea8bb86029ca470099cb870d267 /numpy
parent54b45e71fdf03556c39a27e53751d3199d21d64c (diff)
downloadnumpy-99f7707f80dafab4709fd4e833766a24a40ecfc7.tar.gz
Add nested loops to the template processor.
The syntax is to separate the nested loops with lines containing strings like #repeat = 1# #repeat = 2# ... The number doesn't really matter, but it helps document the depth. Example: The file containing /**begin repeat * # a = 1,2,3# * # b = 1,2,3# * # repeat = 1# * # c = 1,2# * # d = 1,2# */ @a@@b@@c@@d@ /**end repeat**/ produces #line 1 "template.c.src" /* ***************************************************************************** ** This file was autogenerated from a template DO NOT EDIT!!!! ** ** Changes should be made to the original source (.src) file ** ***************************************************************************** */ #line 8 1111 #line 8 1122 #line 8 2211 #line 8 2222 #line 8 3311 #line 8 3322
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)
+