def test_undef(self): """ Tests CPreProcessor #undef preprocessing """ # This tests undef-ing both a defined and not-defined variable. f = StringIO("MY_DEFINE\n#define MY_DEFINE Changed\nMY_DEFINE\n" "#undef MY_DEFINE\nMY_DEFINE\n#undef NO_VARIABLE\n") pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "MY_DEFINE\nChanged\nMY_DEFINE")
def test_conservative_defines(self): """ Tests CPreProcessor #define token replacement """ # Check that it does not replace tokens inside quotes f = StringIO("'MY_VAR' is MY_VAR\n\"MY_VAR\" is MY_VAR still\n") pp = CPreProcessor(f, defines=dict(MY_VAR='set')) self.assertEqual(pp.read().strip(), "'MY_VAR' is set\n\"MY_VAR\" is set still") f = StringIO("This is NOT_MY_VAR, but 'MY_VAR' is MY_VAR\n") pp = CPreProcessor(f, defines=dict(MY_VAR='taken')) self.assertEqual(pp.read().strip(), "This is NOT_MY_VAR, but 'MY_VAR' is taken")
def test_missing_include(self): """ Tests CPreProcessor controllable behavior of missing #includes """ warnings.filterwarnings('error', category=PreProcessorWarning) f = StringIO("#include \"nofile.h\"\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) f.seek(0) pp = CPreProcessor(f, notfound_fatal=False) self.assertRaises(PreProcessorWarning, lambda: pp.read())
def test_ifndef(self): """ Tests CPreProcessor #ifndef/#else#endif preprocessing """ f = StringIO('#ifndef MY_DEFINE\nMY_DEFINE is not set\n' '#else\nPPVAR is set to MY_DEFINE\n#endif\n') pp = CPreProcessor(f) # no defines self.assertEqual(pp.read().strip(), 'MY_DEFINE is not set') f.seek(0) pp = CPreProcessor(f, defines=dict(MY_DEFINE='SUCCESS')) self.assertEqual(pp.read().strip(), 'PPVAR is set to SUCCESS')
def test_not_implemented(self): """ Test error catching for PP features not implemented """ f = StringIO('#define MYVAR 1\n#if (MYVAR == 1)\nCORRECT\n#endif') pp = CPreProcessor(f) self.assertRaises(NotImplementedError, lambda: pp.seek(10)) self.assertRaises(NotImplementedError, pp.read) f = StringIO('#ifdef MYVAR\n#elif defined(NOTMYVAR)\n#else\nline\#endif') pp = CPreProcessor(f) self.assertRaises(NotImplementedError, pp.read)
def test_define(self): """ Tests CPreProcessor #define preprocessing """ f = StringIO('#ifdef MY_DEFINE\nPPVAR is set to MY_DEFINE\n' '#else\nMY_DEFINE is not set\n#endif\n' '#define MY_DEFINE SUCCESS\n#ifdef MY_DEFINE\n' 'PPVAR is set to MY_DEFINE\n#else\nMY_DEFINE is not set\n' '#endif\n') pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), 'MY_DEFINE is not set\nPPVAR is set to SUCCESS')
def test_include_defines(self): """ Tests CPreProcessor passing defines between included files """ pp = CPreProcessor(get_fn('pptest2/pptest1.h')) self.assertEqual(pp.read().strip(), """\ pptest1 line 1 pptest2 line 1 pptest3 line 1 pptest1 line 2 pptest1 line 3 pptest3 line 1 pptest1 line 4""")
def test_simple_include(self): """ Tests CPreProcessor simple #include directive """ pp = CPreProcessor(get_fn('pptest1/pptest1.h')) self.assertEqual(pp.read().strip(), """\ pptest1 line 1 pptest2 line 1 pptest3 line 1 pptest2 line 2 pptest1 line 2 pptest3 line 1 pptest1 line 3""")
def test_undef(self): """ Tests CPreProcessor #undef preprocessing """ # This tests undef-ing both a defined and not-defined variable. f = StringIO("MY_DEFINE\n#define MY_DEFINE Changed\nMY_DEFINE\n" "#undef MY_DEFINE\nMY_DEFINE\n#undef NO_VARIABLE\n") pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "MY_DEFINE\nChanged\nMY_DEFINE") # Make sure undef does not occur where it shouldn't f = StringIO('#define MYVAR something\n#ifdef NOVAR\n#undef MYVAR\n' '#endif\nMYVAR') with CPreProcessor(f) as pp: self.assertEqual(pp.read().strip(), 'something')
def test_define_inside_ifdef(self): """ Tests CPreProcessor #define inside #ifdef/#ifndef """ f = StringIO("#ifdef MY_DEFINE\n#define MY_DEFINE " "Something\n#endif\nMY_DEFINE") pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "MY_DEFINE") f = StringIO("#ifdef MY_DEFINE\n# define MY_DEFINE Something\n" "#endif\nMY_DEFINE\n#ifndef MY_DEFINE\n" "# define MY_DEFINE Something special\n#endif\n" "MY_DEFINE") pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "MY_DEFINE\nSomething special")
def test_include_dir(self): """ Tests CPreProcessor passing include directories to search """ f = StringIO('#include "pptest1.h"') pp = CPreProcessor(f, includes=[get_fn('pptest1')]) self.assertEqual(pp.read().strip(), """\ pptest1 line 1 pptest2 line 1 pptest3 line 1 pptest2 line 2 pptest1 line 2 pptest3 line 1 pptest1 line 3""")
def test_bad_ifdef(self): """ Tests CPreProcessor error processing of bad #ifdef/#ifndef """ f = StringIO("#ifdef\n#endif") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) f = StringIO("#ifndef\n#endif") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) f = StringIO("#ifdef SOME_VAR\ndangling ifdef\n\n\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) warnings.filterwarnings('error', category=PreProcessorWarning) f = StringIO("#ifdef SOME_VAR misplaced comments\n#endif\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorWarning, lambda: pp.read()) f = StringIO("#ifdef SOME_VAR\n#endif misplaced comments\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorWarning, lambda: pp.read())
def test_define(self): """ Tests CPreProcessor #define preprocessing """ f = StringIO('#ifdef MY_DEFINE\nPPVAR is set to MY_DEFINE\n' '#else\nMY_DEFINE is not set\n#endif\n' '#define MY_DEFINE SUCCESS\n#ifdef MY_DEFINE\n' 'PPVAR is set to MY_DEFINE\n#else\nMY_DEFINE is not set\n' '#endif\n') pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), 'MY_DEFINE is not set\nPPVAR is set to SUCCESS') warnings.filterwarnings('error', category=PreProcessorWarning) f = StringIO('#define MYVAR something\nMYVAR\n#define MYVAR ' 'something_else\nMYVAR') with CPreProcessor(f) as pp: self.assertRaises(PreProcessorWarning, pp.read) warnings.filterwarnings('ignore', category=PreProcessorWarning) f.seek(0) with CPreProcessor(f) as pp: self.assertEqual(pp.read().strip(), 'something\nsomething_else')
def test_nested_ifs(self): """ Tests CPreProcessor nested #ifdef and #if """ f = StringIO(""" #ifdef MY_VAR line 1 # if 1 line 2 # endif /* 1 */ #else /* ! MY_VAR */ # if 0 line 3 # else /* ! 0 */ line 4 # endif /* 0 */ #endif /* MY_VAR */ """) pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "line 4") f.seek(0) pp = CPreProcessor(f, defines=dict(MY_VAR=1)) self.assertEqual(pp.read().strip(), "line 1\nline 2")
def test_nested_ifs(self): """ Tests CPreProcessor nested #ifdef and #if """ f = StringIO(""" #ifdef MY_VAR line 1 # if 1 line 2 # endif /* 1 */ #else /* ! MY_VAR */ # if 0 line 3 # else /* ! 0 */ line 4 # endif /* 0 */ #endif /* MY_VAR */ """) pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), "line 4") f.seek(0) pp = CPreProcessor(f, defines=dict(MY_VAR=1)) self.assertEqual(pp.read().strip(), "line 1\nline 2") f = StringIO(""" #ifdef MY_VAR # ifndef MY_VAR_2 MY_VAR defined... MY_VAR_2 not # else MY_VAR defined... MY_VAR_2 also # endif #endif """) pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), '') f.seek(0) pp = CPreProcessor(f, defines=dict(MY_VAR=1)) self.assertEqual(pp.read().strip(), '1 defined... MY_VAR_2 not') f.seek(0) pp = CPreProcessor(f, defines=dict(MY_VAR=1, MY_VAR_2=2)) self.assertEqual(pp.read().strip(), '1 defined... 2 also')
def test_if1_if0(self): """ Tests CPreProcessor use of #if 1 and #if 0 to serve as comments """ f = StringIO('#if 1\n#ifdef MY_DEFINE\nPPVAR is set to MY_DEFINE\n' '#else\nMY_DEFINE is not set\n#endif\n#endif\n') pp = CPreProcessor(f) # no defines self.assertEqual(pp.read().strip(), 'MY_DEFINE is not set') f.seek(0) pp = CPreProcessor(f, defines=dict(MY_DEFINE='SUCCESS')) self.assertEqual(pp.read().strip(), 'PPVAR is set to SUCCESS') f = StringIO('#if 0\n#ifdef MY_DEFINE\nPPVAR is set to MY_DEFINE\n' '#else\nMY_DEFINE is not set\n#endif\n#endif\n') pp = CPreProcessor(f) # no defines self.assertFalse(pp.read().strip()) f.seek(0) pp = CPreProcessor(f, defines=dict(MY_DEFINE='SUCCESS')) self.assertFalse(pp.read().strip())
def test_bad_define_undef(self): """ Tests CPreProcessor error processing of bad #define/#undef """ f = StringIO("#define\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) f = StringIO("#undef\n") pp = CPreProcessor(f) self.assertRaises(PreProcessorError, lambda: pp.read()) warnings.filterwarnings('error', category=PreProcessorWarning) f = StringIO('#undef VAR1 misplaced comments\n') pp = CPreProcessor(f) self.assertRaises(PreProcessorWarning, lambda: pp.read())
class GromacsFile(object): """ A GROMACS file that recognizes the ";" character as a 'comment' token. It can be iterated over and generally treated like a file object, but only spits out strings that have been truncated at its first comment character. There is currently no way to recognize a ; as a _non_ comment character, since allowing an escape character does not seem to be common practice and would likely introduce negative performance implications. Parameters ---------- fname : str or file-like Name of the file to parse or file-like object to parse defines : dict{str : str}, optional List of defines for the preprocessed file, if any includes : list of str, optional List of include files. Default is taken from environment variables GMXDATA or GMXBIN if they are set. Otherwise, it is looked for in /usr, /usr/local, /opt, or /opt/local. If it is still not found, it is looked for relative to whatever ``mdrun`` executable is in your path notfound_fatal : bool, optional If True, missing include files are fatal. If False, they are a warning. Default is True """ def __init__(self, fname, **kwargs): self._handle = CPreProcessor(fname, **kwargs) self.closed = False self.line_number = 0 def __iter__(self): # Iterate over the file, treating an ending \ as a continuation parts = [] for line in self._handle: try: idx = line.index(';') if not parts: yield '%s\n' % line[:idx] else: parts.append('%s' % line[:idx]) yield '%s\n' % ''.join(parts) parts = [] except ValueError: # There is no comment... if line.rstrip('\r\n').endswith('\\'): chars = list(reversed(line.rstrip('\r\n'))) del chars[chars.index('\\')] parts.append('%s ' % ''.join(reversed(chars))) elif parts: parts.append(line) yield ''.join(parts) parts = [] else: yield line @property def included_files(self): return self._handle.included_files def readline(self): parts = [] self.line_number += 1 line = True while line: line = self._handle.readline() try: idx = line.index(';') if not parts: return '%s\n' % line[:idx] else: parts.append('%s' % line[:idx]) return '%s\n' % ''.join(parts) except ValueError: # There is no comment... if line.rstrip('\r\n').endswith('\\'): chars = list(reversed(line.rstrip('\r\n'))) del chars[chars.index('\\')] parts.append('%s ' % ''.join(reversed(chars))) elif parts: parts.append(line) return ''.join(parts) else: return line def readlines(self): return [line for line in self] def read(self): return ''.join(self.readlines()) def close(self): self._handle.close() self.closed = True def __del__(self): try: self.closed or self._handle.close() except AttributeError: # It didn't make it out of the constructor pass
def test_close(self): """ Test closing file object before deleting it """ pp = CPreProcessor(get_fn('pptest1/pptest1.h')) pp.close() del pp
def test_nested_defines(self): """ Tests CPreProcessor nested #define token replacement """ f = StringIO("#define MY_VAR replace1\n#define MY_VAR2 MY_VAR\n" "MY_VAR2\n") pp = CPreProcessor(f) self.assertEqual(pp.read().strip(), 'replace1')
def __init__(self, fname, **kwargs): self._handle = CPreProcessor(fname, **kwargs) self.closed = False self.line_number = 0