mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-21 19:35:28 -05:00
Existing text output in GCC has to be implemented by writing sequentially to a pretty_printer instance. This makes it hard to implement some kinds of diagnostic output (see e.g. diagnostic-show-locus.cc). This patch adds more flexible ways of creating text output: - a canvas class, which can be "painted" to via random-access (rather that sequentially) - a table class for 2D grid layout, supporting items that span multiple rows/columns - a widget class for organizing diagrams hierarchically. The patch also expands GCC's diagnostics subsystem so that diagnostics can have "text art" diagrams - think ASCII art, but potentially including some Unicode characters, such as box-drawing chars. The new code is in a new "gcc/text-art" subdirectory and "text_art" namespace. The patch adds a new "-fdiagnostics-text-art-charset=VAL" option, with values: - "none": don't emit diagrams (added to -fdiagnostics-plain-output) - "ascii": use pure ASCII in diagrams - "unicode": allow for conservative use of unicode drawing characters (such as box-drawing characters). - "emoji" (the default): as "unicode", but potentially allow for conservative use of emoji in the output (such as U+26A0 WARNING SIGN). I made it possible to disable emoji separately from unicode as I believe there's a generation gap in acceptance of these characters (some older programmers have a visceral reaction against them, whereas younger programmers may have no problem with them). Diagrams are emitted to stderr by default. With SARIF output they are captured as a location in "relatedLocations", with the diagram as a code block in Markdown within a "markdown" property of a message. This patch doesn't add any such diagram usage to GCC, saving that for followups, apart from adding a plugin to the test suite to exercise the functionality. contrib/ChangeLog: * unicode/gen-box-drawing-chars.py: New file. * unicode/gen-combining-chars.py: New file. * unicode/gen-printable-chars.py: New file. gcc/ChangeLog: * Makefile.in (OBJS-libcommon): Add text-art/box-drawing.o, text-art/canvas.o, text-art/ruler.o, text-art/selftests.o, text-art/style.o, text-art/styled-string.o, text-art/table.o, text-art/theme.o, and text-art/widget.o. * color-macros.h (COLOR_FG_BRIGHT_BLACK): New. (COLOR_FG_BRIGHT_RED): New. (COLOR_FG_BRIGHT_GREEN): New. (COLOR_FG_BRIGHT_YELLOW): New. (COLOR_FG_BRIGHT_BLUE): New. (COLOR_FG_BRIGHT_MAGENTA): New. (COLOR_FG_BRIGHT_CYAN): New. (COLOR_FG_BRIGHT_WHITE): New. (COLOR_BG_BRIGHT_BLACK): New. (COLOR_BG_BRIGHT_RED): New. (COLOR_BG_BRIGHT_GREEN): New. (COLOR_BG_BRIGHT_YELLOW): New. (COLOR_BG_BRIGHT_BLUE): New. (COLOR_BG_BRIGHT_MAGENTA): New. (COLOR_BG_BRIGHT_CYAN): New. (COLOR_BG_BRIGHT_WHITE): New. * common.opt (fdiagnostics-text-art-charset=): New option. (diagnostic-text-art.h): New SourceInclude. (diagnostic_text_art_charset) New Enum and EnumValues. * configure: Regenerate. * configure.ac (gccdepdir): Add text-art to loop. * diagnostic-diagram.h: New file. * diagnostic-format-json.cc (json_emit_diagram): New. (diagnostic_output_format_init_json): Wire it up to context->m_diagrams.m_emission_cb. * diagnostic-format-sarif.cc: Include "diagnostic-diagram.h" and "text-art/canvas.h". (sarif_result::on_nested_diagnostic): Move code to... (sarif_result::add_related_location): ...this new function. (sarif_result::on_diagram): New. (sarif_builder::emit_diagram): New. (sarif_builder::make_message_object_for_diagram): New. (sarif_emit_diagram): New. (diagnostic_output_format_init_sarif): Set context->m_diagrams.m_emission_cb to sarif_emit_diagram. * diagnostic-text-art.h: New file. * diagnostic.cc: Include "diagnostic-text-art.h", "diagnostic-diagram.h", and "text-art/theme.h". (diagnostic_initialize): Initialize context->m_diagrams and call diagnostics_text_art_charset_init. (diagnostic_finish): Clean up context->m_diagrams.m_theme. (diagnostic_emit_diagram): New. (diagnostics_text_art_charset_init): New. * diagnostic.h (text_art::theme): New forward decl. (class diagnostic_diagram): Likewise. (diagnostic_context::m_diagrams): New field. (diagnostic_emit_diagram): New decl. * doc/invoke.texi (Diagnostic Message Formatting Options): Add -fdiagnostics-text-art-charset=. (-fdiagnostics-plain-output): Add -fdiagnostics-text-art-charset=none. * gcc.cc: Include "diagnostic-text-art.h". (driver_handle_option): Handle OPT_fdiagnostics_text_art_charset_. * opts-common.cc (decode_cmdline_options_to_array): Add "-fdiagnostics-text-art-charset=none" to expanded_args for -fdiagnostics-plain-output. * opts.cc: Include "diagnostic-text-art.h". (common_handle_option): Handle OPT_fdiagnostics_text_art_charset_. * pretty-print.cc (pp_unicode_character): New. * pretty-print.h (pp_unicode_character): New decl. * selftest-run-tests.cc: Include "text-art/selftests.h". (selftest::run_tests): Call text_art_tests. * text-art/box-drawing-chars.inc: New file, generated by contrib/unicode/gen-box-drawing-chars.py. * text-art/box-drawing.cc: New file. * text-art/box-drawing.h: New file. * text-art/canvas.cc: New file. * text-art/canvas.h: New file. * text-art/ruler.cc: New file. * text-art/ruler.h: New file. * text-art/selftests.cc: New file. * text-art/selftests.h: New file. * text-art/style.cc: New file. * text-art/styled-string.cc: New file. * text-art/table.cc: New file. * text-art/table.h: New file. * text-art/theme.cc: New file. * text-art/theme.h: New file. * text-art/types.h: New file. * text-art/widget.cc: New file. * text-art/widget.h: New file. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-text-art-ascii-bw.c: New test. * gcc.dg/plugin/diagnostic-test-text-art-ascii-color.c: New test. * gcc.dg/plugin/diagnostic-test-text-art-none.c: New test. * gcc.dg/plugin/diagnostic-test-text-art-unicode-bw.c: New test. * gcc.dg/plugin/diagnostic-test-text-art-unicode-color.c: New test. * gcc.dg/plugin/diagnostic_plugin_test_text_art.c: New test plugin. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add them. libcpp/ChangeLog: * charset.cc (get_cppchar_property): New function template, based on... (cpp_wcwidth): ...this function. Rework to use the above. Include "combining-chars.inc". (cpp_is_combining_char): New function Include "printable-chars.inc". (cpp_is_printable_char): New function * combining-chars.inc: New file, generated by contrib/unicode/gen-combining-chars.py. * include/cpplib.h (cpp_is_combining_char): New function decl. (cpp_is_printable_char): New function decl. * printable-chars.inc: New file, generated by contrib/unicode/gen-printable-chars.py. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
199 lines
6.7 KiB
Plaintext
199 lines
6.7 KiB
Plaintext
# Copyright (C) 2009-2023 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with GCC; see the file COPYING3. If not see
|
|
# <http://www.gnu.org/licenses/>.
|
|
|
|
# Test the functionality of the GCC plugin support
|
|
|
|
load_lib target-supports.exp
|
|
load_lib gcc-dg.exp
|
|
|
|
global TESTING_IN_BUILD_TREE
|
|
global ENABLE_PLUGIN
|
|
|
|
# The plugin testcases currently only work when the build tree is available.
|
|
# Also check whether the host supports plugins.
|
|
if { ![info exists TESTING_IN_BUILD_TREE] || ![info exists ENABLE_PLUGIN] } {
|
|
return
|
|
}
|
|
|
|
# If a testcase doesn't have special options, use these.
|
|
global DEFAULT_CFLAGS
|
|
if ![info exists DEFAULT_CFLAGS] then {
|
|
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
|
|
}
|
|
|
|
# The procedures in plugin-support.exp need these parameters.
|
|
set default_flags $DEFAULT_CFLAGS
|
|
|
|
if $tracelevel then {
|
|
strace $tracelevel
|
|
}
|
|
|
|
# Load support procs.
|
|
load_lib plugin-support.exp
|
|
|
|
# These tests don't run runtest_file_p consistently if it
|
|
# doesn't return the same values, so disable parallelization
|
|
# of this *.exp file. The first parallel runtest to reach
|
|
# this will run all the tests serially.
|
|
if ![gcc_parallel_test_run_p plugin] {
|
|
return
|
|
}
|
|
gcc_parallel_test_enable 0
|
|
|
|
# Specify the plugin source file and the associated test files in a list.
|
|
# plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
|
|
set plugin_test_list [list \
|
|
{ selfassign.c self-assign-test-1.c self-assign-test-2.c } \
|
|
{ ggcplug.c ggcplug-test-1.c } \
|
|
{ one_time_plugin.c one_time-test-1.c } \
|
|
{ start_unit_plugin.c start_unit-test-1.c } \
|
|
{ finish_unit_plugin.c finish_unit-test-1.c } \
|
|
{ wide-int_plugin.c wide-int-test-1.c } \
|
|
{ poly-int-01_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-02_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-03_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-04_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-05_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-06_plugin.c poly-int-test-1.c } \
|
|
{ poly-int-07_plugin.c poly-int-test-1.c } \
|
|
{ crash_test_plugin.c \
|
|
crash-test-ice-stderr.c \
|
|
crash-test-write-though-null-stderr.c \
|
|
crash-test-ice-sarif.c \
|
|
crash-test-write-though-null-sarif.c } \
|
|
{ diagnostic_group_plugin.c \
|
|
diagnostic-group-test-1.c } \
|
|
{ diagnostic_plugin_test_show_locus.c \
|
|
diagnostic-test-show-locus-bw.c \
|
|
diagnostic-test-show-locus-color.c \
|
|
diagnostic-test-show-locus-no-labels.c \
|
|
diagnostic-test-show-locus-bw-line-numbers.c \
|
|
diagnostic-test-show-locus-bw-line-numbers-2.c \
|
|
diagnostic-test-show-locus-color-line-numbers.c \
|
|
diagnostic-test-show-locus-parseable-fixits.c \
|
|
diagnostic-test-show-locus-GCC_EXTRA_DIAGNOSTIC_OUTPUT-fixits-v1.c \
|
|
diagnostic-test-show-locus-GCC_EXTRA_DIAGNOSTIC_OUTPUT-fixits-v2.c \
|
|
diagnostic-test-show-locus-generate-patch.c }\
|
|
{ diagnostic_plugin_test_tree_expression_range.c \
|
|
diagnostic-test-expressions-1.c } \
|
|
{ diagnostic_plugin_show_trees.c \
|
|
diagnostic-test-show-trees-1.c } \
|
|
{ diagnostic_plugin_test_string_literals.c \
|
|
diagnostic-test-string-literals-1.c \
|
|
diagnostic-test-string-literals-2.c \
|
|
diagnostic-test-string-literals-3.c \
|
|
diagnostic-test-string-literals-4.c } \
|
|
{ diagnostic_plugin_test_inlining.c \
|
|
diagnostic-test-inlining-1.c \
|
|
diagnostic-test-inlining-2.c \
|
|
diagnostic-test-inlining-3.c \
|
|
diagnostic-test-inlining-4.c } \
|
|
{ diagnostic_plugin_test_metadata.c diagnostic-test-metadata.c } \
|
|
{ diagnostic_plugin_test_paths.c \
|
|
diagnostic-test-paths-1.c \
|
|
diagnostic-test-paths-2.c \
|
|
diagnostic-test-paths-3.c \
|
|
diagnostic-test-paths-4.c \
|
|
diagnostic-test-paths-5.c \
|
|
diagnostic-path-format-plain.c \
|
|
diagnostic-path-format-none.c \
|
|
diagnostic-path-format-separate-events.c \
|
|
diagnostic-path-format-inline-events-1.c \
|
|
diagnostic-path-format-inline-events-2.c \
|
|
diagnostic-path-format-inline-events-3.c } \
|
|
{ diagnostic_plugin_test_text_art.c \
|
|
diagnostic-test-text-art-none.c \
|
|
diagnostic-test-text-art-ascii-bw.c \
|
|
diagnostic-test-text-art-ascii-color.c \
|
|
diagnostic-test-text-art-unicode-bw.c \
|
|
diagnostic-test-text-art-unicode-color.c } \
|
|
{ location_overflow_plugin.c \
|
|
location-overflow-test-1.c \
|
|
location-overflow-test-2.c \
|
|
location-overflow-test-pr83173.c } \
|
|
{ must_tail_call_plugin.c \
|
|
must-tail-call-1.c \
|
|
must-tail-call-2.c } \
|
|
{ expensive_selftests_plugin.c \
|
|
expensive-selftests-1.c } \
|
|
{ dump_plugin.c \
|
|
dump-1.c \
|
|
dump-2.c } \
|
|
{ analyzer_gil_plugin.c \
|
|
gil-1.c } \
|
|
{ analyzer_known_fns_plugin.c \
|
|
known-fns-1.c } \
|
|
{ analyzer_kernel_plugin.c \
|
|
copy_from_user-1.c \
|
|
infoleak-1.c \
|
|
infoleak-2.c \
|
|
infoleak-3.c \
|
|
infoleak-CVE-2011-1078-1.c \
|
|
infoleak-CVE-2011-1078-2.c \
|
|
infoleak-CVE-2017-18549-1.c \
|
|
infoleak-CVE-2017-18550-1.c \
|
|
infoleak-antipatterns-1.c \
|
|
infoleak-fixit-1.c \
|
|
infoleak-net-ethtool-ioctl.c \
|
|
infoleak-vfio_iommu_type1.c \
|
|
taint-CVE-2011-0521-1-fixed.c \
|
|
taint-CVE-2011-0521-1.c \
|
|
taint-CVE-2011-0521-2-fixed.c \
|
|
taint-CVE-2011-0521-2.c \
|
|
taint-CVE-2011-0521-3-fixed.c \
|
|
taint-CVE-2011-0521-3.c \
|
|
taint-CVE-2011-0521-4.c \
|
|
taint-CVE-2011-0521-5.c \
|
|
taint-CVE-2011-0521-5-fixed.c \
|
|
taint-CVE-2011-0521-6.c \
|
|
taint-antipatterns-1.c } \
|
|
]
|
|
|
|
foreach plugin_test $plugin_test_list {
|
|
# Replace each source file with its full-path name
|
|
for {set i 0} {$i < [llength $plugin_test]} {incr i} {
|
|
set basename [lindex $plugin_test $i]
|
|
set plugin_test [lreplace $plugin_test $i $i $srcdir/$subdir/$basename]
|
|
}
|
|
set plugin_src [lindex $plugin_test 0]
|
|
# If we're only testing specific files and this isn't one of them, skip it.
|
|
if ![runtest_file_p $runtests $plugin_src] then {
|
|
continue
|
|
}
|
|
# Skip tail call tests on targets that do not have sibcall_epilogue.
|
|
if {[regexp ".*must_tail_call_plugin.c" $plugin_src]
|
|
&& [istarget arm*-*-*]
|
|
&& [check_effective_target_arm_thumb1]} then {
|
|
continue
|
|
}
|
|
set plugin_input_tests [lreplace $plugin_test 0 0]
|
|
plugin-test-execute $plugin_src $plugin_input_tests
|
|
}
|
|
|
|
# run the plugindir tests
|
|
|
|
# Initialize `dg'.
|
|
dg-init
|
|
|
|
# Main loop.
|
|
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/plugindir*.\[cSi\]]] \
|
|
"" $DEFAULT_CFLAGS
|
|
|
|
# All done.
|
|
dg-finish
|
|
|
|
gcc_parallel_test_enable 1
|