Skip to content

Commit e5c41db

Browse files
authored
Add support for clang's color diagnostics flags (#24827)
emcc will not honor the following clang flags: ``` -fcolor-diagnostics -fdiagnostics-color -fdiagnostics-color=always -fno-color-diagnostics -fdiagnostics-color=never -fansi-escape-codes ```
1 parent fe1d2ee commit e5c41db

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

test/test_other.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12370,27 +12370,45 @@ def test_offset_converter_source_map(self, args):
1237012370
self.set_setting('LOAD_SOURCE_MAP')
1237112371
self.do_runf('other/test_offset_converter.c', 'ok', cflags=['-gsource-map', '-DUSE_SOURCE_MAP'] + args)
1237212372

12373+
@crossplatform
1237312374
@no_windows('ptys and select are not available on windows')
12374-
def test_build_error_color(self):
12375+
def test_color_diagnostics(self):
1237512376
create_file('src.c', 'int main() {')
1237612377
returncode, output = self.run_on_pty([EMCC, 'src.c'])
1237712378
self.assertNotEqual(returncode, 0)
1237812379
self.assertIn(b"\x1b[1msrc.c:1:13: \x1b[0m\x1b[0;1;31merror: \x1b[0m\x1b[1mexpected '}'\x1b[0m", output)
1237912380
# Verify that emcc errors show up as red and bold
1238012381
self.assertIn(b"emcc: \x1b[31m\x1b[1m", output)
1238112382

12383+
@crossplatform
1238212384
@parameterized({
12383-
'fno_diagnostics_color': ['-fno-diagnostics-color'],
12384-
'fdiagnostics_color_never': ['-fdiagnostics-color=never'],
12385+
'': ['-fno-diagnostics-color'],
12386+
'never': ['-fdiagnostics-color=never'],
1238512387
})
1238612388
@no_windows('ptys and select are not available on windows')
12387-
def test_pty_no_color(self, flag):
12389+
def test_color_diagnostics_disable(self, flag):
1238812390
create_file('src.c', 'int main() {')
1238912391

1239012392
returncode, output = self.run_on_pty([EMCC, flag, 'src.c'])
1239112393
self.assertNotEqual(returncode, 0)
1239212394
self.assertNotIn(b'\x1b', output)
1239312395

12396+
@crossplatform
12397+
# There are 3 different ways for force color output in clang
12398+
@parameterized({
12399+
'': ['-fcolor-diagnostics'],
12400+
'alt': ['-fdiagnostics-color'],
12401+
'always': ['-fdiagnostics-color=always'],
12402+
})
12403+
def test_color_diagnostics_force(self, flag):
12404+
create_file('src.c', 'int main() {')
12405+
# -fansi-escape-codes is needed here to make this test work on windows, which doesn't
12406+
# use ansi codes by default
12407+
output = self.expect_fail([EMCC, '-fansi-escape-codes', flag, 'src.c'])
12408+
self.assertIn("\x1b[1msrc.c:1:13: \x1b[0m\x1b[0;1;31merror: \x1b[0m\x1b[1mexpected '}'\x1b[0m", output)
12409+
# Verify that emcc errors show up as red and bold
12410+
self.assertIn("emcc: \x1b[31m\x1b[1m", output)
12411+
1239412412
def test_sanitizer_color(self):
1239512413
create_file('src.c', '''
1239612414
#include <emscripten.h>

tools/cmdline.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,12 @@ def consume_arg_file():
513513
options.cpu_profiler = True
514514
elif check_flag('--threadprofiler'):
515515
settings_changes.append('PTHREADS_PROFILING=1')
516+
elif arg in ('-fcolor-diagnostics', '-fdiagnostics-color', '-fdiagnostics-color=always'):
517+
diagnostics.color_enabled = True
518+
elif arg in ('-fno-color-diagnostics', '-fdiagnostics-color=never'):
519+
diagnostics.color_enabled = False
520+
elif arg == '-fansi-escape-codes':
521+
diagnostics.force_ansi = True
516522
elif arg == '-fno-exceptions':
517523
settings.DISABLE_EXCEPTION_CATCHING = 1
518524
settings.DISABLE_EXCEPTION_THROWING = 1

tools/diagnostics.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
import sys
1313
from typing import Dict
1414

15-
1615
WINDOWS = sys.platform.startswith('win')
1716

1817
logger = logging.getLogger('diagnostics')
1918
color_enabled = sys.stderr.isatty()
2019
tool_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
20+
force_ansi = False
2121

2222
# diagnostic levels
2323
WARN = 1
@@ -49,6 +49,7 @@
4949

5050

5151
def output_color_windows(color):
52+
assert not force_ansi
5253
# TODO(sbc): This code is duplicated in colored_logger.py. Refactor.
5354
# wincon.h
5455
FOREGROUND_BLACK = 0x0000 # noqa
@@ -76,6 +77,7 @@ def output_color_windows(color):
7677

7778

7879
def get_color_windows():
80+
assert not force_ansi
7981
SHORT = ctypes.c_short
8082
WORD = ctypes.c_ushort
8183

@@ -106,26 +108,27 @@ class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
106108

107109

108110
def reset_color_windows():
111+
assert not force_ansi
109112
sys.stderr.flush()
110113
hdl = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
111114
ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, default_color)
112115

113116

114117
def output_color(color):
115-
if WINDOWS:
118+
if WINDOWS and not force_ansi:
116119
return output_color_windows(color)
117120
return '\033[3%sm' % color
118121

119122

120123
def bold():
121-
if WINDOWS:
124+
if WINDOWS and not force_ansi:
122125
# AFAICT there is no way to enable bold output on windows
123126
return ''
124127
return '\033[1m'
125128

126129

127130
def reset_color():
128-
if WINDOWS:
131+
if WINDOWS and not force_ansi:
129132
return reset_color_windows()
130133
return '\033[0m'
131134

0 commit comments

Comments
 (0)