From patchwork Thu Sep 10 20:28:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 516422 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id ED7AD1400A0 for ; Fri, 11 Sep 2015 06:13:05 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=EmdTFRl6; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=scG6LDAAJsZnWKzaXUjl++5tKXyAS8/7cvFSBaz2qEjeve5XA/yP6 kn5zjvNdufne2OBhzoUMi9JKkvn/HuUKC1l0qPiUSiXvq62/L9KLI5YaRF9ID7JA QnkQP5Sfln8WhhEFaxjKTwTajaICpCOfGGABRGRQ0BCax9DxNVMph4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=8ERaaH1R+otVIL8uJE4WHphBG1g=; b=EmdTFRl6EoSGHJqDJJio EOp9pcCiHwTZBvjgNzvJysV8us/gs4aFA6aFwMh6tEE6KJBC1SYQUj7PyuvVbQz4 o1F4hA5bttxThirfQe/fJiPXNI9EfWfcsL4EJQwYryugCV/2lBpoWNVefNINOcrQ obW4nDpOutUUPB2J300HRWs= Received: (qmail 113589 invoked by alias); 10 Sep 2015 20:12:40 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 113554 invoked by uid 89); 10 Sep 2015 20:12:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 10 Sep 2015 20:12:35 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id AB46B80091 for ; Thu, 10 Sep 2015 20:12:34 +0000 (UTC) Received: from c64.redhat.com (vpn-239-137.phx2.redhat.com [10.3.239.137]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8AKCWaL003473; Thu, 10 Sep 2015 16:12:34 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 03/22] Move diagnostic_show_locus and friends out into a new source file Date: Thu, 10 Sep 2015 16:28:14 -0400 Message-Id: <1441916913-11547-4-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1441916913-11547-1-git-send-email-dmalcolm@redhat.com> References: <1441916913-11547-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes The function "diagnostic_show_locus" gains new functionality in the next patch, so this preliminary patch breaks it out into a new source file, diagnostic-show-locus.c, along with a couple of related functions. gcc/ChangeLog: * Makefile.in (OBJS-libcommon): Add diagnostic-show-locus.o. * diagnostic.c (adjust_line): Move to diagnostic-show-locus.c. (diagnostic_show_locus): Likewise. (diagnostic_print_caret_line): Likewise. * diagnostic-show-locus.c: New file. --- gcc/Makefile.in | 3 +- gcc/diagnostic-show-locus.c | 166 ++++++++++++++++++++++++++++++++++++++++++++ gcc/diagnostic.c | 129 ---------------------------------- 3 files changed, 168 insertions(+), 130 deletions(-) create mode 100644 gcc/diagnostic-show-locus.c diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 3d1c1e5..f183b22 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1512,7 +1512,8 @@ OBJS = \ # Objects in libcommon.a, potentially used by all host binaries and with # no target dependencies. -OBJS-libcommon = diagnostic.o diagnostic-color.o pretty-print.o intl.o \ +OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \ + pretty-print.o intl.o \ vec.o input.o version.o hash-table.o ggc-none.o # Objects in libcommon-target.a, used by drivers and by the core diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c new file mode 100644 index 0000000..147a2b8 --- /dev/null +++ b/gcc/diagnostic-show-locus.c @@ -0,0 +1,166 @@ +/* Diagnostic subroutines for printing source-code + Copyright (C) 1999-2015 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis + +This file is part of GCC. + +GCC 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, or (at your option) any later +version. + +GCC 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 +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "version.h" +#include "demangle.h" +#include "intl.h" +#include "backtrace.h" +#include "diagnostic.h" +#include "diagnostic-color.h" + +#ifdef HAVE_TERMIOS_H +# include +#endif + +#ifdef GWINSZ_IN_SYS_IOCTL +# include +#endif + +/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than + MAX_WIDTH by some margin, then adjust the start of the line such + that the COLUMN is smaller than MAX_WIDTH minus the margin. The + margin is either CARET_LINE_MARGIN characters or the difference + between the column and the length of the line, whatever is smaller. + The length of LINE is given by LINE_WIDTH. */ +static const char * +adjust_line (const char *line, int line_width, + int max_width, int *column_p) +{ + int right_margin = CARET_LINE_MARGIN; + int column = *column_p; + + gcc_checking_assert (line_width >= column); + right_margin = MIN (line_width - column, right_margin); + right_margin = max_width - right_margin; + if (line_width >= max_width && column > right_margin) + { + line += column - right_margin; + *column_p = right_margin; + } + return line; +} + +/* Print the physical source line corresponding to the location of + this diagnostic, and a caret indicating the precise column. This + function only prints two caret characters if the two locations + given by DIAGNOSTIC are on the same line according to + diagnostic_same_line(). */ +void +diagnostic_show_locus (diagnostic_context * context, + const diagnostic_info *diagnostic) +{ + if (!context->show_caret + || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION + || diagnostic_location (diagnostic, 0) == context->last_location) + return; + + context->last_location = diagnostic_location (diagnostic, 0); + expanded_location s0 = diagnostic_expand_location (diagnostic, 0); + expanded_location s1 = { }; + /* Zero-initialized. This is checked later by diagnostic_print_caret_line. */ + + if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION) + s1 = diagnostic_expand_location (diagnostic, 1); + + diagnostic_print_caret_line (context, s0, s1, + context->caret_chars[0], + context->caret_chars[1]); +} + +/* Print (part) of the source line given by xloc1 with caret1 pointing + at the column. If xloc2.column != 0 and it fits within the same + line as xloc1 according to diagnostic_same_line (), then caret2 is + printed at xloc2.colum. Otherwise, the caller has to set up things + to print a second caret line for xloc2. */ +void +diagnostic_print_caret_line (diagnostic_context * context, + expanded_location xloc1, + expanded_location xloc2, + char caret1, char caret2) +{ + if (!diagnostic_same_line (context, xloc1, xloc2)) + /* This will mean ignore xloc2. */ + xloc2.column = 0; + else if (xloc1.column == xloc2.column) + xloc2.column++; + + int cmax = MAX (xloc1.column, xloc2.column); + int line_width; + const char *line = location_get_source_line (xloc1.file, xloc1.line, + &line_width); + if (line == NULL || cmax > line_width) + return; + + /* Center the interesting part of the source line to fit in + max_width, and adjust all columns accordingly. */ + int max_width = context->caret_max_width; + int offset = (int) cmax; + line = adjust_line (line, line_width, max_width, &offset); + offset -= cmax; + cmax += offset; + xloc1.column += offset; + if (xloc2.column) + xloc2.column += offset; + + /* Print the source line. */ + pp_newline (context->printer); + const char *saved_prefix = pp_get_prefix (context->printer); + pp_set_prefix (context->printer, NULL); + pp_space (context->printer); + while (max_width > 0 && line_width > 0) + { + char c = *line == '\t' ? ' ' : *line; + if (c == '\0') + c = ' '; + pp_character (context->printer, c); + max_width--; + line_width--; + line++; + } + pp_newline (context->printer); + + /* Print the caret under the line. */ + const char *caret_cs, *caret_ce; + caret_cs = colorize_start (pp_show_color (context->printer), "caret"); + caret_ce = colorize_stop (pp_show_color (context->printer)); + int cmin = xloc2.column + ? MIN (xloc1.column, xloc2.column) : xloc1.column; + int caret_min = cmin == xloc1.column ? caret1 : caret2; + int caret_max = cmin == xloc1.column ? caret2 : caret1; + + /* cmin is >= 1, but we indent with an extra space at the start like + we did above. */ + int i; + for (i = 0; i < cmin; i++) + pp_space (context->printer); + pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce); + + if (xloc2.column) + { + for (i++; i < cmax; i++) + pp_space (context->printer); + pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce); + } + pp_set_prefix (context->printer, saved_prefix); + pp_needs_newline (context->printer) = true; +} diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 74a40bb..f40e469 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -308,135 +308,6 @@ diagnostic_build_prefix (diagnostic_context *context, locus_ce, text_cs, text, text_ce)); } -/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than - MAX_WIDTH by some margin, then adjust the start of the line such - that the COLUMN is smaller than MAX_WIDTH minus the margin. The - margin is either CARET_LINE_MARGIN characters or the difference - between the column and the length of the line, whatever is smaller. - The length of LINE is given by LINE_WIDTH. */ -static const char * -adjust_line (const char *line, int line_width, - int max_width, int *column_p) -{ - int right_margin = CARET_LINE_MARGIN; - int column = *column_p; - - gcc_checking_assert (line_width >= column); - right_margin = MIN (line_width - column, right_margin); - right_margin = max_width - right_margin; - if (line_width >= max_width && column > right_margin) - { - line += column - right_margin; - *column_p = right_margin; - } - return line; -} - -/* Print the physical source line corresponding to the location of - this diagnostic, and a caret indicating the precise column. This - function only prints two caret characters if the two locations - given by DIAGNOSTIC are on the same line according to - diagnostic_same_line(). */ -void -diagnostic_show_locus (diagnostic_context * context, - const diagnostic_info *diagnostic) -{ - if (!context->show_caret - || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION - || diagnostic_location (diagnostic, 0) == context->last_location) - return; - - context->last_location = diagnostic_location (diagnostic, 0); - expanded_location s0 = diagnostic_expand_location (diagnostic, 0); - expanded_location s1 = { }; - /* Zero-initialized. This is checked later by diagnostic_print_caret_line. */ - - if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION) - s1 = diagnostic_expand_location (diagnostic, 1); - - diagnostic_print_caret_line (context, s0, s1, - context->caret_chars[0], - context->caret_chars[1]); -} - -/* Print (part) of the source line given by xloc1 with caret1 pointing - at the column. If xloc2.column != 0 and it fits within the same - line as xloc1 according to diagnostic_same_line (), then caret2 is - printed at xloc2.colum. Otherwise, the caller has to set up things - to print a second caret line for xloc2. */ -void -diagnostic_print_caret_line (diagnostic_context * context, - expanded_location xloc1, - expanded_location xloc2, - char caret1, char caret2) -{ - if (!diagnostic_same_line (context, xloc1, xloc2)) - /* This will mean ignore xloc2. */ - xloc2.column = 0; - else if (xloc1.column == xloc2.column) - xloc2.column++; - - int cmax = MAX (xloc1.column, xloc2.column); - int line_width; - const char *line = location_get_source_line (xloc1.file, xloc1.line, - &line_width); - if (line == NULL || cmax > line_width) - return; - - /* Center the interesting part of the source line to fit in - max_width, and adjust all columns accordingly. */ - int max_width = context->caret_max_width; - int offset = (int) cmax; - line = adjust_line (line, line_width, max_width, &offset); - offset -= cmax; - cmax += offset; - xloc1.column += offset; - if (xloc2.column) - xloc2.column += offset; - - /* Print the source line. */ - pp_newline (context->printer); - const char *saved_prefix = pp_get_prefix (context->printer); - pp_set_prefix (context->printer, NULL); - pp_space (context->printer); - while (max_width > 0 && line_width > 0) - { - char c = *line == '\t' ? ' ' : *line; - if (c == '\0') - c = ' '; - pp_character (context->printer, c); - max_width--; - line_width--; - line++; - } - pp_newline (context->printer); - - /* Print the caret under the line. */ - const char *caret_cs, *caret_ce; - caret_cs = colorize_start (pp_show_color (context->printer), "caret"); - caret_ce = colorize_stop (pp_show_color (context->printer)); - int cmin = xloc2.column - ? MIN (xloc1.column, xloc2.column) : xloc1.column; - int caret_min = cmin == xloc1.column ? caret1 : caret2; - int caret_max = cmin == xloc1.column ? caret2 : caret1; - - /* cmin is >= 1, but we indent with an extra space at the start like - we did above. */ - int i; - for (i = 0; i < cmin; i++) - pp_space (context->printer); - pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce); - - if (xloc2.column) - { - for (i++; i < cmax; i++) - pp_space (context->printer); - pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce); - } - pp_set_prefix (context->printer, saved_prefix); - pp_needs_newline (context->printer) = true; -} - /* Functions at which to stop the backtrace print. It's not particularly helpful to print the callers of these functions. */