1#! /usr/bin/env python3
2
3# Copyright 2007 Google Inc.
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
18# USA.
19
20
21"""Tests for parse_file."""
22
23__author__ = "opensource@google.com"
24
25import unittest
26
27import basics
28import cache_basics
29import parse_file
30import include_server
31import include_analyzer
32
33class parse_file_Test(unittest.TestCase):
34
35  def setUp(self):
36    include_server.print_statistics = False
37    client_root_keeper = basics.ClientRootKeeper()
38    include_server.write_include_closure_file = True
39    self.include_analyzer = include_analyzer.IncludeAnalyzer(client_root_keeper)
40
41  def tearDown(self):
42    pass
43
44  def test_RegularExpressions(self):
45
46    self.assertEqual(parse_file.POUND_SIGN_RE.match(
47        """  #\tinclude blah. blah."""
48        ).group(0), "  #\tinclude blah. blah.")
49
50    self.assertEqual(parse_file.POUND_SIGN_RE.match(
51        """  # gggg include blah. blah."""
52        ), None)
53
54    self.assertEqual(parse_file.POUND_SIGN_RE.match(
55        """  */  /**/ /*  a */ #  	include blah. blah."""
56        ).group(0), '  */  /**/ /*  a */ #  \tinclude blah. blah.')
57
58    self.assertEqual(
59      parse_file.MACRO_EXPR_RE.search("m(a, b) + c + n(d)").groupdict(),
60      {'args': 'a, b', 'symbol': 'm'})
61
62    # The expression we recognize do not include nested parenthesis
63    self.assertEqual(
64      parse_file.MACRO_EXPR_RE.search("m(a, (b)) + c + n(d)").groupdict(),
65      {'args': None, 'symbol': 'm'})
66
67    self.assertEqual(parse_file.MACRO_EXPR_RE.match("random()").group('symbol'),
68                     "random")
69
70    self.assertTrue(parse_file.DIRECTIVE_RE.match(
71	"""  # include <a.c>""").group('angle') == 'a.c')
72    self.assertTrue(parse_file.DIRECTIVE_RE.match(
73	"""  # include mac(a.c, mic)""").group('expr') == 'mac(a.c, mic)')
74    self.assertTrue(parse_file.DIRECTIVE_RE.match(
75	"""  # include "a.c" """).group('quote') == 'a.c')
76    self.assertTrue(parse_file.DIRECTIVE_RE.match(
77	"""  #include "a.c" """).group('quote') == 'a.c')
78    self.assertTrue(parse_file.DIRECTIVE_RE.match(
79	"""  #include"a.c" """).group('quote') == 'a.c')
80
81    self.assertEqual(parse_file.DIRECTIVE_RE.match(
82        """ #define m(a) <a##_post.c> """).group('rhs'),
83                     '<a##_post.c>')
84
85    self.assertEqual(
86      parse_file.DIRECTIVE_RE.match("#define xmlRealloc(ptr, size)"
87                         + " xmlReallocLoc((ptr), (size),"
88                         + " __FILE__, __LINE__)").group('lhs'),
89      "xmlRealloc(ptr, size)")
90
91    self.assertEqual(
92      parse_file.DIRECTIVE_RE.match("#define random() rand()").group('lhs'),
93      "random()")
94
95    self.assertEqual(
96      parse_file.DIRECTIVE_RE.match("#define ABBA ").group('lhs'),
97      "ABBA")
98
99    self.assertEqual(
100      parse_file.DIRECTIVE_RE.match("#define ABBA").group('lhs'),
101      "ABBA")
102
103    self.assertEqual(parse_file.BACKSLASH_RE.sub("",
104"""a\
105b\
106c\
107d"""), "abcd")
108    self.assertEqual(parse_file.BACKSLASH_RE.sub("", """a
109b
110"""),
111				      """a
112b
113""")
114
115    self.assertEqual(parse_file.PAIRED_COMMENT_RE.sub("", "ab/*./*..*/cd"), "abcd")
116    self.assertEqual(parse_file.PAIRED_COMMENT_RE.sub("", "ab/*/cd"), "ab/*/cd")
117
118    self.assertEqual(parse_file.COMMENT_RE.match("ab/*cd").group(), "ab")
119    self.assertEqual(parse_file.COMMENT_RE.match("ab//cd").group(), "ab")
120    self.assertEqual(parse_file.COMMENT_RE.match("ab/cd").group(), "ab/cd")
121
122    self.assertEqual(parse_file.
123      INCLUDE_STRING_RE.match(""" < ab.c>""").group('angle'),
124      "ab.c")
125
126  def test_ParseFile(self):
127
128    includepath_map = cache_basics.MapToIndex()
129    canonical_path = cache_basics.CanonicalPath()
130    parse_file_obj = parse_file.ParseFile(includepath_map)
131
132    symbol_table = {}
133    self.assertEqual(parse_file_obj.Parse(
134      "test_data/more_macros.c", symbol_table),
135      ([], [], ['TEMPLATE_VARNAME(foo)'], []))
136    symbol_table_keys = list(symbol_table.keys())
137    symbol_table_keys.sort()
138    self.assertEqual(symbol_table_keys,
139                     ['AS_STRING', 'AS_STRING_INTERNAL',
140                      'ILLFORMED', 'TEMPLATE_VARNAME'])
141    [([arg], val)] = symbol_table['TEMPLATE_VARNAME']
142    self.assertEqual(arg, '_filename_')
143    self.assertEqual(val, 'AS_STRING(maps/_filename_.tpl.varnames.h)')
144
145    self.assertEqual(parse_file_obj.Parse(
146      "test_data/computed_includes.c", symbol_table),
147      ([],
148       [],
149       [ 'A' , 'm(abc)' ],
150       []))
151    self.assertEqual(symbol_table['A'], ['"p1.h"'])
152    [val] = symbol_table['ILLFORMED']
153    self.assertEqual(val, "(_filename_,(x))   "
154                + "AS_STRING(maps/_filename_.tpl.varnames.h, "
155                + "NOTHANDLED(_filename_))")
156
157unittest.main()
158