Commit 7add2e47 authored by Mike Hommey's avatar Mike Hommey
Browse files

Bug 751865 - Avoid Preprocessor.py applying filters to file names given on the command line. r=ted

parent 83278f08
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ class Preprocessor:
      args = [sys.stdin]
    includes.extend(args)
    for f in includes:
      self.do_include(f)
      self.do_include(f, False)
    pass

  def getCommandLineParser(self, unescapeDefines = False):
@@ -414,7 +414,7 @@ class Preprocessor:
  def filter_attemptSubstitution(self, aLine):
    return self.filter_substitution(aLine, fatal=False)
  # File ops
  def do_include(self, args):
  def do_include(self, args, filters=True):
    """
    Preprocess a given file.
    args can either be a file name, or a file-like object.
@@ -427,10 +427,13 @@ class Preprocessor:
    if isName:
      try:
        args = str(args)
        if filters:
          args = self.applyFilters(args)
        if not os.path.isabs(args):
          args = os.path.join(self.context['DIRECTORY'], args)
        args = open(args, 'rU')
      except Preprocessor.Error:
        raise
      except:
        raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
    self.checkLineNumbers = bool(re.search('\.(js|java)(?:\.in)?$', args.name))
@@ -476,7 +479,7 @@ def preprocess(includes=[sys.stdin], defines={},
  pp.setMarker(marker)
  pp.out = output
  for f in includes:
    pp.do_include(f)
    pp.do_include(f, False)

if __name__ == "__main__":
  main()
+92 −0
Original line number Diff line number Diff line
from __future__ import with_statement
import unittest

from StringIO import StringIO
@@ -13,6 +14,33 @@ class NamedIO(StringIO):
    self.name = name
    StringIO.__init__(self, content)

class MockedOpen(object):
  """
  Context manager diverting the open builtin such that opening files
  can open NamedIO instances given when creating a MockedOpen.

  with MockedOpen(NamedIO('foo', 'foo'), NamedIO('bar', 'bar')):
    f = open('foo', 'r')

  will thus assign the NamedIO instance for the file 'foo' to f.
  """
  def __init__(self, *files):
    self.files = {}
    for f in files:
      self.files[os.path.abspath(f.name)] = f
  def __call__(self, name, args):
    absname = os.path.abspath(name)
    if absname in self.files:
      return self.files[absname]
    return self.open(name, args)
  def __enter__(self):
    import __builtin__
    self.open = __builtin__.open
    __builtin__.open = self
  def __exit__(self, type, value, traceback):
    import __builtin__
    __builtin__.open = self.open

class TestPreprocessor(unittest.TestCase):
  """
  Unit tests for the Context class
@@ -499,5 +527,69 @@ octal value is not equal
    self.pp.do_include(f)
    self.assertEqual(self.pp.out.getvalue(), "octal value is not equal\n")

  def test_undefined_variable(self):
    f = NamedIO("undefined_variable.in", """#filter substitution
@foo@
""")
    try:
      self.pp.do_include(f)
    except Preprocessor.Error, exception:
      self.assertEqual(exception.key, 'UNDEFINED_VAR')
    else:
      self.fail("Expected a Preprocessor.Error")

  def test_include(self):
    with MockedOpen(NamedIO("foo/test", """#define foo foobarbaz
#include @inc@
@bar@
"""),
                      NamedIO("bar", """#define bar barfoobaz
@foo@
""")):
      f = NamedIO("include.in", """#filter substitution
#define inc ../bar
#include foo/test""")
      self.pp.do_include(f)
      self.assertEqual(self.pp.out.getvalue(), """foobarbaz
barfoobaz
""")

  def test_include_missing_file(self):
    f = NamedIO("include_missing_file.in", "#include foo")
    try:
      self.pp.do_include(f)
    except Preprocessor.Error, exception:
      self.assertEqual(exception.key, 'FILE_NOT_FOUND')
    else:
      self.fail("Expected a Preprocessor.Error")

  def test_include_undefined_variable(self):
    f = NamedIO("include_undefined_variable.in", """#filter substitution
#include @foo@
""")
    try:
      self.pp.do_include(f)
    except Preprocessor.Error, exception:
      self.assertEqual(exception.key, 'UNDEFINED_VAR')
    else:
      self.fail("Expected a Preprocessor.Error")

  def test_include_literal_at(self):
    with MockedOpen(NamedIO("@foo@", "#define foo foobarbaz")):
      f = NamedIO("include_literal_at.in", """#include @foo@
#filter substitution
@foo@
""")
      self.pp.do_include(f)
      self.assertEqual(self.pp.out.getvalue(), """foobarbaz
""")

  def test_command_line_literal_at(self):
    with MockedOpen(NamedIO("@foo@.in", """@foo@
""")):
      self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
      self.assertEqual(self.pp.out.getvalue(), """foobarbaz
""")

if __name__ == '__main__':
  unittest.main()
+7 −4
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ class Preprocessor:
      args = [sys.stdin]
    includes.extend(args)
    for f in includes:
      self.do_include(f)
      self.do_include(f, False)
    pass

  def getCommandLineParser(self, unescapeDefines = False):
@@ -414,7 +414,7 @@ class Preprocessor:
  def filter_attemptSubstitution(self, aLine):
    return self.filter_substitution(aLine, fatal=False)
  # File ops
  def do_include(self, args):
  def do_include(self, args, filters=True):
    """
    Preprocess a given file.
    args can either be a file name, or a file-like object.
@@ -427,10 +427,13 @@ class Preprocessor:
    if isName:
      try:
        args = str(args)
        if filters:
          args = self.applyFilters(args)
        if not os.path.isabs(args):
          args = os.path.join(self.context['DIRECTORY'], args)
        args = open(args, 'rU')
      except Preprocessor.Error:
        raise
      except:
        raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
    self.checkLineNumbers = bool(re.search('\.(js|java)(?:\.in)?$', args.name))
@@ -476,7 +479,7 @@ def preprocess(includes=[sys.stdin], defines={},
  pp.setMarker(marker)
  pp.out = output
  for f in includes:
    pp.do_include(f)
    pp.do_include(f, False)

if __name__ == "__main__":
  main()