[Numpy-svn] r5066 - trunk/numpy/distutils
numpy-svn at scipy.org
numpy-svn at scipy.org
Wed Apr 23 00:57:02 EDT 2008
Author: charris
Date: 2008-04-22 23:57:00 -0500 (Tue, 22 Apr 2008)
New Revision: 5066
Modified:
trunk/numpy/distutils/conv_template.py
Log:
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
Modified: trunk/numpy/distutils/conv_template.py
===================================================================
--- trunk/numpy/distutils/conv_template.py 2008-04-23 00:20:57 UTC (rev 5065)
+++ trunk/numpy/distutils/conv_template.py 2008-04-23 04:57:00 UTC (rev 5066)
@@ -46,7 +46,7 @@
_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 @@
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 @@
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"
+ names[name] = vals
+ names[None] = nsubs
+ loops.append(names)
- # now replace all keys for each of the lists
- mystr = ''
- thissub = [None]
+ # 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 @@
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 @@
return ('#line 1 "%s"\n%s'
% (sourcefile, process_str(''.join(lines))))
+
if __name__ == "__main__":
try:
@@ -200,3 +223,4 @@
allstr = fid.read()
writestr = process_str(allstr)
outfile.write(writestr)
+
More information about the Numpy-svn
mailing list