diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-06-12 20:17:34 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-12 20:17:34 -0600 |
commit | f2f5cfcab003a56f6294a34155083f101e29e957 (patch) | |
tree | cfcf2a8b5660d6c2ca12f025793ec30bf80a0997 | |
parent | 26049e08d3dc0e82c8be187f43c8a26248526f5d (diff) | |
parent | 8d41d3b7d27bb0202a153d734e6d26ff271c78c9 (diff) | |
download | numpy-f2f5cfcab003a56f6294a34155083f101e29e957.tar.gz |
Merge pull request #11319 from charris/revert-problem-f2py-fixes
REL, REV: Revert f2py fixes that exposed SciPy bug.
-rwxr-xr-x | numpy/f2py/crackfortran.py | 85 | ||||
-rw-r--r-- | numpy/f2py/tests/test_quoted_character.py | 30 |
2 files changed, 37 insertions, 78 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py index 19ce8c145..78802ef07 100755 --- a/numpy/f2py/crackfortran.py +++ b/numpy/f2py/crackfortran.py @@ -346,6 +346,8 @@ def readfortrancode(ffile, dowithline=show, istop=1): cont = 0 finalline = '' ll = '' + commentline = re.compile( + r'(?P<line>([^"]*["][^"]*["][^"!]*|[^\']*\'[^\']*\'[^\'!]*|[^!\'"]*))!{1}(?P<rest>.*)') includeline = re.compile( r'\s*include\s*(\'|")(?P<name>[^\'"]*)(\'|")', re.I) cont1 = re.compile(r'(?P<line>.*)&\s*\Z') @@ -389,10 +391,17 @@ def readfortrancode(ffile, dowithline=show, istop=1): break l = l[:-1] if not strictf77: - (l, rl) = split_by_unquoted(l, '!') - l += ' ' - if rl[:5].lower() == '!f2py': # f2py directive - l, _ = split_by_unquoted(l + 4 * ' ' + rl[5:], '!') + r = commentline.match(l) + if r: + l = r.group('line') + ' ' # Strip comments starting with `!' + rl = r.group('rest') + if rl[:4].lower() == 'f2py': # f2py directive + l = l + 4 * ' ' + r = commentline.match(rl[4:]) + if r: + l = l + r.group('line') + else: + l = l + rl[4:] if l.strip() == '': # Skip empty line cont = 0 continue @@ -609,25 +618,6 @@ multilinepattern = re.compile( r"\s*(?P<before>''')(?P<this>.*?)(?P<after>''')\s*\Z", re.S), 'multiline' ## -def split_by_unquoted(line, characters): - """ - Splits the line into (line[:i], line[i:]), - where i is the index of first occurrence of one of the characters - not within quotes, or len(line) if no such index exists - """ - assert not (set('"\'') & set(characters)), "cannot split by unquoted quotes" - r = re.compile( - r"\A(?P<before>({single_quoted}|{double_quoted}|{not_quoted})*)" - r"(?P<after>{char}.*)\Z".format( - not_quoted="[^\"'{}]".format(re.escape(characters)), - char="[{}]".format(re.escape(characters)), - single_quoted=r"('([^'\\]|(\\.))*')", - double_quoted=r'("([^"\\]|(\\.))*")')) - m = r.match(line) - if m: - d = m.groupdict() - return (d["before"], d["after"]) - return (line, "") def _simplifyargs(argsline): a = [] @@ -652,17 +642,12 @@ def crackline(line, reset=0): global filepositiontext, currentfilename, neededmodule, expectbegin global skipblocksuntil, skipemptyends, previous_context, gotnextfile - _, has_semicolon = split_by_unquoted(line, ";") - if has_semicolon and not (f2pyenhancementspattern[0].match(line) or - multilinepattern[0].match(line)): - # XXX: non-zero reset values need testing - assert reset == 0, repr(reset) - # split line on unquoted semicolons - line, semicolon_line = split_by_unquoted(line, ";") - while semicolon_line: - crackline(line, reset) - line, semicolon_line = split_by_unquoted(semicolon_line[1:], ";") - crackline(line, reset) + if ';' in line and not (f2pyenhancementspattern[0].match(line) or + multilinepattern[0].match(line)): + for l in line.split(';'): + # XXX: non-zero reset values need testing + assert reset == 0, repr(reset) + crackline(l, reset) return if reset < 0: groupcounter = 0 @@ -817,22 +802,26 @@ def markouterparen(line): def markoutercomma(line, comma=','): l = '' f = 0 - before, after = split_by_unquoted(line, comma + '()') - l += before - while after: - if (after[0] == comma) and (f == 0): - l += '@' + comma + '@' - else: - l += after[0] - if after[0] == '(': - f += 1 - elif after[0] == ')': - f -= 1 - before, after = split_by_unquoted(after[1:], comma + '()') - l += before - assert not f, repr((f, line, l)) + cc = '' + for c in line: + if (not cc or cc == ')') and c == '(': + f = f + 1 + cc = ')' + elif not cc and c == '\'' and (not l or l[-1] != '\\'): + f = f + 1 + cc = '\'' + elif c == cc: + f = f - 1 + if f == 0: + cc = '' + elif c == comma and f == 0: + l = l + '@' + comma + '@' + continue + l = l + c + assert not f, repr((f, line, l, cc)) return l + def unmarkouterparen(line): r = line.replace('@(@', '(').replace('@)@', ')') return r diff --git a/numpy/f2py/tests/test_quoted_character.py b/numpy/f2py/tests/test_quoted_character.py deleted file mode 100644 index 09fc7328f..000000000 --- a/numpy/f2py/tests/test_quoted_character.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import division, absolute_import, print_function - -import sys -import pytest - -from numpy.testing import assert_equal -from . import util - -class TestQuotedCharacter(util.F2PyTest): - code = """ - SUBROUTINE FOO(OUT1, OUT2, OUT3, OUT4, OUT5, OUT6) - CHARACTER SINGLE, DOUBLE, SEMICOL, EXCLA, OPENPAR, CLOSEPAR - PARAMETER (SINGLE="'", DOUBLE='"', SEMICOL=';', EXCLA="!", - 1 OPENPAR="(", CLOSEPAR=")") - CHARACTER OUT1, OUT2, OUT3, OUT4, OUT5, OUT6 -Cf2py intent(out) OUT1, OUT2, OUT3, OUT4, OUT5, OUT6 - OUT1 = SINGLE - OUT2 = DOUBLE - OUT3 = SEMICOL - OUT4 = EXCLA - OUT5 = OPENPAR - OUT6 = CLOSEPAR - RETURN - END - """ - - @pytest.mark.skipif(sys.platform=='win32', - reason='Fails with MinGW64 Gfortran (Issue #9673)') - def test_quoted_character(self): - assert_equal(self.module.foo(), (b"'", b'"', b';', b'!', b'(', b')')) |