Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary.
(filename, vars=None, keep_unresolved=True)
| 313 | |
| 314 | |
| 315 | def _parse_makefile(filename, vars=None, keep_unresolved=True): |
| 316 | """Parse a Makefile-style file. |
| 317 | |
| 318 | A dictionary containing name/value pairs is returned. If an |
| 319 | optional dictionary is passed in as the second argument, it is |
| 320 | used instead of a new dictionary. |
| 321 | """ |
| 322 | import re |
| 323 | |
| 324 | if vars is None: |
| 325 | vars = {} |
| 326 | done = {} |
| 327 | notdone = {} |
| 328 | |
| 329 | with open(filename, encoding=sys.getfilesystemencoding(), |
| 330 | errors="surrogateescape") as f: |
| 331 | lines = f.readlines() |
| 332 | |
| 333 | for line in lines: |
| 334 | if line.startswith('#') or line.strip() == '': |
| 335 | continue |
| 336 | m = re.match(_variable_rx, line) |
| 337 | if m: |
| 338 | n, v = m.group(1, 2) |
| 339 | v = v.strip() |
| 340 | # `$$' is a literal `$' in make |
| 341 | tmpv = v.replace('$$', '') |
| 342 | |
| 343 | if "$" in tmpv: |
| 344 | notdone[n] = v |
| 345 | else: |
| 346 | try: |
| 347 | if n in _ALWAYS_STR: |
| 348 | raise ValueError |
| 349 | |
| 350 | v = int(v) |
| 351 | except ValueError: |
| 352 | # insert literal `$' |
| 353 | done[n] = v.replace('$$', '$') |
| 354 | else: |
| 355 | done[n] = v |
| 356 | |
| 357 | # do variable interpolation here |
| 358 | variables = list(notdone.keys()) |
| 359 | |
| 360 | # Variables with a 'PY_' prefix in the makefile. These need to |
| 361 | # be made available without that prefix through sysconfig. |
| 362 | # Special care is needed to ensure that variable expansion works, even |
| 363 | # if the expansion uses the name without a prefix. |
| 364 | renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') |
| 365 | |
| 366 | while len(variables) > 0: |
| 367 | for name in tuple(variables): |
| 368 | value = notdone[name] |
| 369 | m1 = re.search(_findvar1_rx, value) |
| 370 | m2 = re.search(_findvar2_rx, value) |
| 371 | if m1 and m2: |
| 372 | m = m1 if m1.start() < m2.start() else m2 |
no test coverage detected