File: sdcpp-diagnostic.c

package info (click to toggle)
sdcc 4.2.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 105,232 kB
  • sloc: ansic: 956,095; cpp: 110,511; makefile: 59,314; sh: 29,875; asm: 17,178; perl: 12,136; yacc: 7,480; lisp: 1,672; python: 907; lex: 805; awk: 498; sed: 89
file content (178 lines) | stat: -rw-r--r-- 5,263 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* diagnostic subroutines for the SDCC
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
   2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 2010 Borut Razem
   Contributed by Gabriel Dos Reis <gdr@codesourcery.com>

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
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "internal.h"
#include "sdcpp.h"

#ifndef _
# define _(msgid) (msgid)
#endif

/* from libcpp/line-map.c */

/* Print the file names and line numbers of the #include commands
   which led to the map MAP, if any, to stderr.  Nothing is output if
   the most recently listed stack is the same as the current one.  */

void
linemap_print_containing_files (struct line_maps *set,
                                const struct line_map *map)
{
  if (MAIN_FILE_P (map) || set->last_listed == map->included_from)
    return;

  set->last_listed = map->included_from;
  map = INCLUDED_FROM (set, map);

  fprintf (stderr,  _("In file included from %s:%u"),
           map->to_file, LAST_SOURCE_LINE (map));

  while (! MAIN_FILE_P (map))
    {
      map = INCLUDED_FROM (set, map);
      /* Translators note: this message is used in conjunction
         with "In file included from %s:%ld" and some other
         tricks.  We want something like this:

         | In file included from sys/select.h:123,
         |                  from sys/types.h:234,
         |                  from userfile.c:31:
         | bits/select.h:45: <error message here>

         with all the "from"s lined up.
         The trailing comma is at the beginning of this message,
         and the trailing colon is not translated.  */
      fprintf (stderr, _(",\n                 from %s:%u"),
               map->to_file, LAST_SOURCE_LINE (map));
    }

  fputs (":\n", stderr);
}

/* from libcpp/errors.c */

/* Print the logical file location (LINE, COL) in preparation for a
   diagnostic.  Outputs the #include chain if it has changed.  A line
   of zero suppresses the include stack, and outputs the program name
   instead.  */
static void
print_location (cpp_reader *pfile, source_location line, unsigned int col)
{
  if (line == 0)
    fprintf (stderr, "%s: ", progname);
  else
    {
      const struct line_map *map;
      unsigned int lin;

      map = linemap_lookup (pfile->line_table, line);
      linemap_print_containing_files (pfile->line_table, map);

      lin = SOURCE_LINE (map, line);
      if (col == 0)
	{
	  col = SOURCE_COLUMN (map, line);
	  if (col == 0)
	    col = 1;
	}

      if (lin == 0)
	fprintf (stderr, "%s:", map->to_file);
      else
	fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);

      fputc (' ', stderr);
    }
}

/* from c-common.c */

/* Callback from cpp_error for PFILE to print diagnostics from the
   preprocessor.  The diagnostic is of type LEVEL, at location
   LOCATION unless this is after lexing and the compiler's location
   should be used instead, with column number possibly overridden by
   COLUMN_OVERRIDE if not zero; MSG is the translated message and AP
   the arguments.  Returns true if a diagnostic was emitted, false
   otherwise.  */

bool
c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason ATTRIBUTE_UNUSED,
	     location_t location, unsigned int column_override,
	     const char *msg, va_list *ap)
{
/* Moved here from cpplib.h */
/* Extracts a diagnostic level from an int.  */
#define CPP_DL_EXTRACT(l)       (l & 0xf)
/* Nonzero if a diagnostic level is one of the warnings.  */
#define CPP_DL_WARNING_P(l)     (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \
                                 && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN)

  switch (level)
    {
    case CPP_DL_WARNING:
    case CPP_DL_PEDWARN:
      if (cpp_in_system_header (pfile)
	  && ! warn_system_headers)
	return false;
      /* Fall through.  */

    case CPP_DL_WARNING_SYSHDR:
      if (warnings_are_errors
	  || (level == CPP_DL_PEDWARN && flag_pedantic_errors))
	{
	  level = CPP_DL_ERROR;
	  ++errorcount;
	}
      else if (inhibit_warnings)
	return false;
      break;

    case CPP_DL_ERROR:
      /* ICEs cannot be inhibited.  */
    case CPP_DL_ICE:
      ++errorcount;
      break;
    }

  print_location (pfile, location, column_override);

  if (CPP_DL_WARNING_P (level))
    fputs (_("warning: "), stderr);
  else if (level == CPP_DL_ICE)
    fputs (_("internal error: "), stderr);
  else if (level == CPP_DL_FATAL)
    fputs (_("fatal error: "), stderr);
  else
    fputs (_("error: "), stderr);

  vfprintf (stderr, _(msg), *ap);
  putc ('\n', stderr);

  if (level == CPP_DL_FATAL) {
    fputs(_("compilation terminated.\n"), stderr);
    exit (FATAL_EXIT_CODE);
  }

  return true;
}