annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/conv_template.py @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 #!/usr/bin/python
Chris@87 2 """
Chris@87 3 takes templated file .xxx.src and produces .xxx file where .xxx is
Chris@87 4 .i or .c or .h, using the following template rules
Chris@87 5
Chris@87 6 /**begin repeat -- on a line by itself marks the start of a repeated code
Chris@87 7 segment
Chris@87 8 /**end repeat**/ -- on a line by itself marks it's end
Chris@87 9
Chris@87 10 After the /**begin repeat and before the */, all the named templates are placed
Chris@87 11 these should all have the same number of replacements
Chris@87 12
Chris@87 13 Repeat blocks can be nested, with each nested block labeled with its depth,
Chris@87 14 i.e.
Chris@87 15 /**begin repeat1
Chris@87 16 *....
Chris@87 17 */
Chris@87 18 /**end repeat1**/
Chris@87 19
Chris@87 20 When using nested loops, you can optionally exlude particular
Chris@87 21 combinations of the variables using (inside the comment portion of the inner loop):
Chris@87 22
Chris@87 23 :exclude: var1=value1, var2=value2, ...
Chris@87 24
Chris@87 25 This will exlude the pattern where var1 is value1 and var2 is value2 when
Chris@87 26 the result is being generated.
Chris@87 27
Chris@87 28
Chris@87 29 In the main body each replace will use one entry from the list of named replacements
Chris@87 30
Chris@87 31 Note that all #..# forms in a block must have the same number of
Chris@87 32 comma-separated entries.
Chris@87 33
Chris@87 34 Example:
Chris@87 35
Chris@87 36 An input file containing
Chris@87 37
Chris@87 38 /**begin repeat
Chris@87 39 * #a = 1,2,3#
Chris@87 40 * #b = 1,2,3#
Chris@87 41 */
Chris@87 42
Chris@87 43 /**begin repeat1
Chris@87 44 * #c = ted, jim#
Chris@87 45 */
Chris@87 46 @a@, @b@, @c@
Chris@87 47 /**end repeat1**/
Chris@87 48
Chris@87 49 /**end repeat**/
Chris@87 50
Chris@87 51 produces
Chris@87 52
Chris@87 53 line 1 "template.c.src"
Chris@87 54
Chris@87 55 /*
Chris@87 56 *********************************************************************
Chris@87 57 ** This file was autogenerated from a template DO NOT EDIT!!**
Chris@87 58 ** Changes should be made to the original source (.src) file **
Chris@87 59 *********************************************************************
Chris@87 60 */
Chris@87 61
Chris@87 62 #line 9
Chris@87 63 1, 1, ted
Chris@87 64
Chris@87 65 #line 9
Chris@87 66 1, 1, jim
Chris@87 67
Chris@87 68 #line 9
Chris@87 69 2, 2, ted
Chris@87 70
Chris@87 71 #line 9
Chris@87 72 2, 2, jim
Chris@87 73
Chris@87 74 #line 9
Chris@87 75 3, 3, ted
Chris@87 76
Chris@87 77 #line 9
Chris@87 78 3, 3, jim
Chris@87 79
Chris@87 80 """
Chris@87 81 from __future__ import division, absolute_import, print_function
Chris@87 82
Chris@87 83
Chris@87 84 __all__ = ['process_str', 'process_file']
Chris@87 85
Chris@87 86 import os
Chris@87 87 import sys
Chris@87 88 import re
Chris@87 89
Chris@87 90 from numpy.distutils.compat import get_exception
Chris@87 91
Chris@87 92 # names for replacement that are already global.
Chris@87 93 global_names = {}
Chris@87 94
Chris@87 95 # header placed at the front of head processed file
Chris@87 96 header =\
Chris@87 97 """
Chris@87 98 /*
Chris@87 99 *****************************************************************************
Chris@87 100 ** This file was autogenerated from a template DO NOT EDIT!!!! **
Chris@87 101 ** Changes should be made to the original source (.src) file **
Chris@87 102 *****************************************************************************
Chris@87 103 */
Chris@87 104
Chris@87 105 """
Chris@87 106 # Parse string for repeat loops
Chris@87 107 def parse_structure(astr, level):
Chris@87 108 """
Chris@87 109 The returned line number is from the beginning of the string, starting
Chris@87 110 at zero. Returns an empty list if no loops found.
Chris@87 111
Chris@87 112 """
Chris@87 113 if level == 0 :
Chris@87 114 loopbeg = "/**begin repeat"
Chris@87 115 loopend = "/**end repeat**/"
Chris@87 116 else :
Chris@87 117 loopbeg = "/**begin repeat%d" % level
Chris@87 118 loopend = "/**end repeat%d**/" % level
Chris@87 119
Chris@87 120 ind = 0
Chris@87 121 line = 0
Chris@87 122 spanlist = []
Chris@87 123 while True:
Chris@87 124 start = astr.find(loopbeg, ind)
Chris@87 125 if start == -1:
Chris@87 126 break
Chris@87 127 start2 = astr.find("*/", start)
Chris@87 128 start2 = astr.find("\n", start2)
Chris@87 129 fini1 = astr.find(loopend, start2)
Chris@87 130 fini2 = astr.find("\n", fini1)
Chris@87 131 line += astr.count("\n", ind, start2+1)
Chris@87 132 spanlist.append((start, start2+1, fini1, fini2+1, line))
Chris@87 133 line += astr.count("\n", start2+1, fini2)
Chris@87 134 ind = fini2
Chris@87 135 spanlist.sort()
Chris@87 136 return spanlist
Chris@87 137
Chris@87 138
Chris@87 139 def paren_repl(obj):
Chris@87 140 torep = obj.group(1)
Chris@87 141 numrep = obj.group(2)
Chris@87 142 return ','.join([torep]*int(numrep))
Chris@87 143
Chris@87 144 parenrep = re.compile(r"[(]([^)]*)[)]\*(\d+)")
Chris@87 145 plainrep = re.compile(r"([^*]+)\*(\d+)")
Chris@87 146 def parse_values(astr):
Chris@87 147 # replaces all occurrences of '(a,b,c)*4' in astr
Chris@87 148 # with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate
Chris@87 149 # empty values, i.e., ()*4 yields ',,,'. The result is
Chris@87 150 # split at ',' and a list of values returned.
Chris@87 151 astr = parenrep.sub(paren_repl, astr)
Chris@87 152 # replaces occurences of xxx*3 with xxx, xxx, xxx
Chris@87 153 astr = ','.join([plainrep.sub(paren_repl, x.strip())
Chris@87 154 for x in astr.split(',')])
Chris@87 155 return astr.split(',')
Chris@87 156
Chris@87 157
Chris@87 158 stripast = re.compile(r"\n\s*\*?")
Chris@87 159 named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#")
Chris@87 160 exclude_vars_re = re.compile(r"(\w*)=(\w*)")
Chris@87 161 exclude_re = re.compile(":exclude:")
Chris@87 162 def parse_loop_header(loophead) :
Chris@87 163 """Find all named replacements in the header
Chris@87 164
Chris@87 165 Returns a list of dictionaries, one for each loop iteration,
Chris@87 166 where each key is a name to be substituted and the corresponding
Chris@87 167 value is the replacement string.
Chris@87 168
Chris@87 169 Also return a list of exclusions. The exclusions are dictionaries
Chris@87 170 of key value pairs. There can be more than one exclusion.
Chris@87 171 [{'var1':'value1', 'var2', 'value2'[,...]}, ...]
Chris@87 172
Chris@87 173 """
Chris@87 174 # Strip out '\n' and leading '*', if any, in continuation lines.
Chris@87 175 # This should not effect code previous to this change as
Chris@87 176 # continuation lines were not allowed.
Chris@87 177 loophead = stripast.sub("", loophead)
Chris@87 178 # parse out the names and lists of values
Chris@87 179 names = []
Chris@87 180 reps = named_re.findall(loophead)
Chris@87 181 nsub = None
Chris@87 182 for rep in reps:
Chris@87 183 name = rep[0]
Chris@87 184 vals = parse_values(rep[1])
Chris@87 185 size = len(vals)
Chris@87 186 if nsub is None :
Chris@87 187 nsub = size
Chris@87 188 elif nsub != size :
Chris@87 189 msg = "Mismatch in number of values:\n%s = %s" % (name, vals)
Chris@87 190 raise ValueError(msg)
Chris@87 191 names.append((name, vals))
Chris@87 192
Chris@87 193
Chris@87 194 # Find any exclude variables
Chris@87 195 excludes = []
Chris@87 196
Chris@87 197 for obj in exclude_re.finditer(loophead):
Chris@87 198 span = obj.span()
Chris@87 199 # find next newline
Chris@87 200 endline = loophead.find('\n', span[1])
Chris@87 201 substr = loophead[span[1]:endline]
Chris@87 202 ex_names = exclude_vars_re.findall(substr)
Chris@87 203 excludes.append(dict(ex_names))
Chris@87 204
Chris@87 205 # generate list of dictionaries, one for each template iteration
Chris@87 206 dlist = []
Chris@87 207 if nsub is None :
Chris@87 208 raise ValueError("No substitution variables found")
Chris@87 209 for i in range(nsub) :
Chris@87 210 tmp = {}
Chris@87 211 for name, vals in names :
Chris@87 212 tmp[name] = vals[i]
Chris@87 213 dlist.append(tmp)
Chris@87 214 return dlist
Chris@87 215
Chris@87 216 replace_re = re.compile(r"@([\w]+)@")
Chris@87 217 def parse_string(astr, env, level, line) :
Chris@87 218 lineno = "#line %d\n" % line
Chris@87 219
Chris@87 220 # local function for string replacement, uses env
Chris@87 221 def replace(match):
Chris@87 222 name = match.group(1)
Chris@87 223 try :
Chris@87 224 val = env[name]
Chris@87 225 except KeyError:
Chris@87 226 msg = 'line %d: no definition of key "%s"'%(line, name)
Chris@87 227 raise ValueError(msg)
Chris@87 228 return val
Chris@87 229
Chris@87 230 code = [lineno]
Chris@87 231 struct = parse_structure(astr, level)
Chris@87 232 if struct :
Chris@87 233 # recurse over inner loops
Chris@87 234 oldend = 0
Chris@87 235 newlevel = level + 1
Chris@87 236 for sub in struct:
Chris@87 237 pref = astr[oldend:sub[0]]
Chris@87 238 head = astr[sub[0]:sub[1]]
Chris@87 239 text = astr[sub[1]:sub[2]]
Chris@87 240 oldend = sub[3]
Chris@87 241 newline = line + sub[4]
Chris@87 242 code.append(replace_re.sub(replace, pref))
Chris@87 243 try :
Chris@87 244 envlist = parse_loop_header(head)
Chris@87 245 except ValueError:
Chris@87 246 e = get_exception()
Chris@87 247 msg = "line %d: %s" % (newline, e)
Chris@87 248 raise ValueError(msg)
Chris@87 249 for newenv in envlist :
Chris@87 250 newenv.update(env)
Chris@87 251 newcode = parse_string(text, newenv, newlevel, newline)
Chris@87 252 code.extend(newcode)
Chris@87 253 suff = astr[oldend:]
Chris@87 254 code.append(replace_re.sub(replace, suff))
Chris@87 255 else :
Chris@87 256 # replace keys
Chris@87 257 code.append(replace_re.sub(replace, astr))
Chris@87 258 code.append('\n')
Chris@87 259 return ''.join(code)
Chris@87 260
Chris@87 261 def process_str(astr):
Chris@87 262 code = [header]
Chris@87 263 code.extend(parse_string(astr, global_names, 0, 1))
Chris@87 264 return ''.join(code)
Chris@87 265
Chris@87 266
Chris@87 267 include_src_re = re.compile(r"(\n|\A)#include\s*['\"]"
Chris@87 268 r"(?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
Chris@87 269
Chris@87 270 def resolve_includes(source):
Chris@87 271 d = os.path.dirname(source)
Chris@87 272 fid = open(source)
Chris@87 273 lines = []
Chris@87 274 for line in fid:
Chris@87 275 m = include_src_re.match(line)
Chris@87 276 if m:
Chris@87 277 fn = m.group('name')
Chris@87 278 if not os.path.isabs(fn):
Chris@87 279 fn = os.path.join(d, fn)
Chris@87 280 if os.path.isfile(fn):
Chris@87 281 print('Including file', fn)
Chris@87 282 lines.extend(resolve_includes(fn))
Chris@87 283 else:
Chris@87 284 lines.append(line)
Chris@87 285 else:
Chris@87 286 lines.append(line)
Chris@87 287 fid.close()
Chris@87 288 return lines
Chris@87 289
Chris@87 290 def process_file(source):
Chris@87 291 lines = resolve_includes(source)
Chris@87 292 sourcefile = os.path.normcase(source).replace("\\", "\\\\")
Chris@87 293 try:
Chris@87 294 code = process_str(''.join(lines))
Chris@87 295 except ValueError:
Chris@87 296 e = get_exception()
Chris@87 297 raise ValueError('In "%s" loop at %s' % (sourcefile, e))
Chris@87 298 return '#line 1 "%s"\n%s' % (sourcefile, code)
Chris@87 299
Chris@87 300
Chris@87 301 def unique_key(adict):
Chris@87 302 # this obtains a unique key given a dictionary
Chris@87 303 # currently it works by appending together n of the letters of the
Chris@87 304 # current keys and increasing n until a unique key is found
Chris@87 305 # -- not particularly quick
Chris@87 306 allkeys = list(adict.keys())
Chris@87 307 done = False
Chris@87 308 n = 1
Chris@87 309 while not done:
Chris@87 310 newkey = "".join([x[:n] for x in allkeys])
Chris@87 311 if newkey in allkeys:
Chris@87 312 n += 1
Chris@87 313 else:
Chris@87 314 done = True
Chris@87 315 return newkey
Chris@87 316
Chris@87 317
Chris@87 318 if __name__ == "__main__":
Chris@87 319
Chris@87 320 try:
Chris@87 321 file = sys.argv[1]
Chris@87 322 except IndexError:
Chris@87 323 fid = sys.stdin
Chris@87 324 outfile = sys.stdout
Chris@87 325 else:
Chris@87 326 fid = open(file, 'r')
Chris@87 327 (base, ext) = os.path.splitext(file)
Chris@87 328 newname = base
Chris@87 329 outfile = open(newname, 'w')
Chris@87 330
Chris@87 331 allstr = fid.read()
Chris@87 332 try:
Chris@87 333 writestr = process_str(allstr)
Chris@87 334 except ValueError:
Chris@87 335 e = get_exception()
Chris@87 336 raise ValueError("In %s loop at %s" % (file, e))
Chris@87 337 outfile.write(writestr)