diff options
| author | Charles Harris <charlesr.harris@gmail.com> | 2008-04-23 04:57:00 +0000 |
|---|---|---|
| committer | Charles Harris <charlesr.harris@gmail.com> | 2008-04-23 04:57:00 +0000 |
| commit | 99f7707f80dafab4709fd4e833766a24a40ecfc7 (patch) | |
| tree | 951a8129708d4ea8bb86029ca470099cb870d267 /numpy/distutils/conv_template.py | |
| parent | 54b45e71fdf03556c39a27e53751d3199d21d64c (diff) | |
| download | numpy-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/distutils/conv_template.py')
| -rw-r--r-- | numpy/distutils/conv_template.py | 114 |
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) + |
