Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/tools/diagnostics.py
6162 views
1
# Copyright 2011 The Emscripten Authors. All rights reserved.
2
# Emscripten is available under two separate licenses, the MIT license and the
3
# University of Illinois/NCSA Open Source License. Both these licenses can be
4
# found in the LICENSE file.
5
6
"""Simple color-enabled diagnostics reporting functions.
7
"""
8
9
import logging
10
import os
11
import sys
12
13
from . import colored_logger
14
15
logger = logging.getLogger('diagnostics')
16
tool_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
17
18
# diagnostic levels
19
WARN = 1
20
ERROR = 2
21
22
# color for use for each diagnostic level
23
level_colors = {
24
WARN: colored_logger.MAGENTA,
25
ERROR: colored_logger.RED,
26
}
27
28
level_prefixes = {
29
WARN: 'warning: ',
30
ERROR: 'error: ',
31
}
32
33
34
def diag(level, msg, *args):
35
# Format output message as:
36
# <tool>: <level>: msg
37
# With the `<level>:` part being colored accordingly, and the message itself in bold.
38
prefix = level_prefixes[level]
39
color = level_colors[level]
40
if args:
41
msg = msg % args
42
43
# Add colors
44
prefix = colored_logger.with_bold_color(color, prefix)
45
msg = colored_logger.with_bold(msg)
46
sys.stderr.write(f'{tool_name}: {prefix}{msg}\n')
47
48
49
def error(msg, *args):
50
diag(ERROR, msg, *args)
51
sys.exit(1)
52
53
54
def warn(msg, *args):
55
diag(WARN, msg, *args)
56
57
58
class WarningManager:
59
warnings: dict[str, dict] = {}
60
61
def add_warning(self, name, enabled=True, part_of_all=True, shared=False, error=False):
62
self.warnings[name] = {
63
'enabled': enabled,
64
'part_of_all': part_of_all,
65
# True for flags that are shared with the underlying clang driver
66
'shared': shared,
67
'error': error,
68
}
69
70
def capture_warnings(self, cmd_args):
71
for i in range(len(cmd_args)):
72
if cmd_args[i] == '-w':
73
for warning in self.warnings.values():
74
warning['enabled'] = False
75
continue
76
77
if not cmd_args[i].startswith('-W'):
78
continue
79
80
if cmd_args[i] == '-Wall':
81
for warning in self.warnings.values():
82
if warning['part_of_all']:
83
warning['enabled'] = True
84
continue
85
86
if cmd_args[i] == '-Werror':
87
for warning in self.warnings.values():
88
warning['error'] = True
89
continue
90
91
if cmd_args[i].startswith('-Werror=') or cmd_args[i].startswith('-Wno-error='):
92
warning_name = cmd_args[i].split('=', 1)[1]
93
if warning_name in self.warnings:
94
enabled = not cmd_args[i].startswith('-Wno-')
95
self.warnings[warning_name]['error'] = enabled
96
if enabled:
97
self.warnings[warning_name]['enabled'] = True
98
cmd_args[i] = ''
99
continue
100
101
warning_name = cmd_args[i].removeprefix('-Wno-').removeprefix('-W')
102
enabled = not cmd_args[i].startswith('-Wno-')
103
104
# special case pre-existing warn-absolute-paths
105
if warning_name == 'warn-absolute-paths':
106
self.warnings['absolute-paths']['enabled'] = enabled
107
cmd_args[i] = ''
108
continue
109
110
if warning_name in self.warnings:
111
self.warnings[warning_name]['enabled'] = enabled
112
if not self.warnings[warning_name]['shared']:
113
cmd_args[i] = ''
114
continue
115
116
return cmd_args
117
118
def warning(self, warning_type, message, *args):
119
warning_info = self.warnings[warning_type]
120
msg = (message % args) + ' [-W' + warning_type.lower().replace('_', '-') + ']'
121
if warning_info['enabled']:
122
if warning_info['error']:
123
error(msg + ' [-Werror]')
124
else:
125
warn(msg)
126
else:
127
logger.debug('disabled warning: ' + msg)
128
129
130
def add_warning(name, enabled=True, part_of_all=True, shared=False, error=False):
131
manager.add_warning(name, enabled, part_of_all, shared, error)
132
133
134
def is_enabled(name):
135
return manager.warnings[name]['enabled']
136
137
138
def warning(warning_type, message, *args):
139
manager.warning(warning_type, message, *args)
140
141
142
def capture_warnings(argv):
143
return manager.capture_warnings(argv)
144
145
146
manager = WarningManager()
147
148