Enable BytesWarnings.
[portage.git] / bin / check-implicit-pointer-usage.py
1 #!/usr/bin/python -bb
2
3 # Ripped from HP and updated from Debian
4 # Update by Gentoo to support unicode output
5
6 #
7 # Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
8 #       David Mosberger <davidm@hpl.hp.com>
9 #
10 # Scan standard input for GCC warning messages that are likely to
11 # source of real 64-bit problems.  In particular, see whether there
12 # are any implicitly declared functions whose return values are later
13 # interpreted as pointers.  Those are almost guaranteed to cause
14 # crashes.
15 #
16
17 from __future__ import print_function
18
19 import re
20 import sys
21
22 implicit_pattern = re.compile("([^:]*):(\d+): warning: implicit declaration "
23                               + "of function [`']([^']*)'")
24 pointer_pattern = (
25     "([^:]*):(\d+): warning: "
26     + "("
27     +  "(assignment"
28     +  "|initialization"
29     +  "|return"
30     +  "|passing arg \d+ of `[^']*'"
31     +  "|passing arg \d+ of pointer to function"
32     +  ") makes pointer from integer without a cast"
33     + "|"
34     + "cast to pointer from integer of different size)")
35
36 if sys.hexversion < 0x3000000:
37     # Use encoded byte strings in python-2.x, since the python ebuilds are
38     # known to remove the encodings module when USE=build is enabled (thus
39     # disabling unicode decoding/encoding). The portage module has a
40     # workaround for this, but currently we don't import that here since we
41     # don't want to trigger potential sandbox violations due to stale pyc
42     # files for the portage module.
43     unicode_quote_open = '\xE2\x80\x98'
44     unicode_quote_close = '\xE2\x80\x99'
45     def write(msg):
46         sys.stdout.write(msg)
47 else:
48     unicode_quote_open = '\u2018'
49     unicode_quote_close = '\u2019'
50     def write(msg):
51         sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
52
53 pointer_pattern = re.compile(pointer_pattern)
54
55 last_implicit_filename = ""
56 last_implicit_linenum = -1
57 last_implicit_func = ""
58
59 while True:
60     if sys.hexversion >= 0x3000000:
61         line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
62     else:
63         line = sys.stdin.readline()
64     if not line:
65         break
66     # translate unicode open/close quotes to ascii ones
67     line = line.replace(unicode_quote_open, "`")
68     line = line.replace(unicode_quote_close, "'")
69     m = implicit_pattern.match(line)
70     if m:
71         last_implicit_filename = m.group(1)
72         last_implicit_linenum = int(m.group(2))
73         last_implicit_func = m.group(3)
74     else:
75         m = pointer_pattern.match(line)
76         if m:
77             pointer_filename = m.group(1)
78             pointer_linenum = int(m.group(2))
79             if (last_implicit_filename == pointer_filename
80                 and last_implicit_linenum == pointer_linenum):
81                 write("Function `%s' implicitly converted to pointer at " \
82                       "%s:%d\n" % (last_implicit_func,
83                                    last_implicit_filename,
84                                    last_implicit_linenum))