maint: remove unnecessary casts before using gnulib functions
[bison.git] / data / skeletons / location.cc
blob091a95b1a0e9dedc3f4d9c07aa327edcb296f9cb
1 # C++ skeleton for Bison
3 # Copyright (C) 2002-2015, 2018-2022 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
18 m4_pushdef([b4_copyright_years],
19 [2002-2015, 2018-2022])
22 # b4_location_file
23 # ----------------
24 # Name of the file containing the position/location class,
25 # if we want this file.
26 b4_percent_define_check_file([b4_location_file],
27 [[api.location.file]],
28 b4_header_if([[location.hh]]))
30 # b4_location_include
31 # -------------------
32 # If location.hh is to be generated, the name under which should it be
33 # included.
35 # b4_location_path
36 # ----------------
37 # The path to use for the CPP guard.
38 m4_ifdef([b4_location_file],
39 [m4_define([b4_location_include],
40 [b4_percent_define_get([[api.location.include]],
41 ["b4_location_file"])])
42 m4_define([b4_location_path],
43 b4_percent_define_get([[api.location.include]],
44 ["b4_mapped_dir_prefix[]b4_location_file"]))
45 m4_define([b4_location_path],
46 m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
50 # b4_position_file
51 # ----------------
52 # Name of the file containing the position class, if we want this file.
53 b4_header_if(
54 [b4_required_version_if(
55 [30200], [],
56 [m4_ifdef([b4_location_file],
57 [m4_define([b4_position_file], [position.hh])])])])
61 # b4_location_define
62 # ------------------
63 # Define the position and location classes.
64 m4_define([b4_location_define],
65 [[ /// A point in a source file.
66 class position
68 public:
69 /// Type for file name.
70 typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
71 /// Type for line and column numbers.
72 typedef int counter_type;
73 ]m4_ifdef([b4_location_constructors], [[
74 /// Construct a position.
75 explicit position (filename_type* f = YY_NULLPTR,
76 counter_type l = ]b4_location_initial_line[,
77 counter_type c = ]b4_location_initial_column[)
78 : filename (f)
79 , line (l)
80 , column (c)
83 ]])[
84 /// Initialization.
85 void initialize (filename_type* fn = YY_NULLPTR,
86 counter_type l = ]b4_location_initial_line[,
87 counter_type c = ]b4_location_initial_column[)
89 filename = fn;
90 line = l;
91 column = c;
94 /** \name Line and Column related manipulators
95 ** \{ */
96 /// (line related) Advance to the COUNT next lines.
97 void lines (counter_type count = 1)
99 if (count)
101 column = ]b4_location_initial_column[;
102 line = add_ (line, count, ]b4_location_initial_line[);
106 /// (column related) Advance to the COUNT next columns.
107 void columns (counter_type count = 1)
109 column = add_ (column, count, ]b4_location_initial_column[);
111 /** \} */
113 /// File name to which this position refers.
114 filename_type* filename;
115 /// Current line number.
116 counter_type line;
117 /// Current column number.
118 counter_type column;
120 private:
121 /// Compute max (min, lhs+rhs).
122 static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
124 return lhs + rhs < min ? min : lhs + rhs;
128 /// Add \a width columns, in place.
129 inline position&
130 operator+= (position& res, position::counter_type width)
132 res.columns (width);
133 return res;
136 /// Add \a width columns.
137 inline position
138 operator+ (position res, position::counter_type width)
140 return res += width;
143 /// Subtract \a width columns, in place.
144 inline position&
145 operator-= (position& res, position::counter_type width)
147 return res += -width;
150 /// Subtract \a width columns.
151 inline position
152 operator- (position res, position::counter_type width)
154 return res -= width;
156 ]b4_percent_define_flag_if([[define_location_comparison]], [[
157 /// Compare two position objects.
158 inline bool
159 operator== (const position& pos1, const position& pos2)
161 return (pos1.line == pos2.line
162 && pos1.column == pos2.column
163 && (pos1.filename == pos2.filename
164 || (pos1.filename && pos2.filename
165 && *pos1.filename == *pos2.filename)));
168 /// Compare two position objects.
169 inline bool
170 operator!= (const position& pos1, const position& pos2)
172 return !(pos1 == pos2);
174 ]])[
175 /** \brief Intercept output stream redirection.
176 ** \param ostr the destination output stream
177 ** \param pos a reference to the position to redirect
179 template <typename YYChar>
180 std::basic_ostream<YYChar>&
181 operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
183 if (pos.filename)
184 ostr << *pos.filename << ':';
185 return ostr << pos.line << '.' << pos.column;
188 /// Two points in a source file.
189 class location
191 public:
192 /// Type for file name.
193 typedef position::filename_type filename_type;
194 /// Type for line and column numbers.
195 typedef position::counter_type counter_type;
196 ]m4_ifdef([b4_location_constructors], [
197 /// Construct a location from \a b to \a e.
198 location (const position& b, const position& e)
199 : begin (b)
200 , end (e)
203 /// Construct a 0-width location in \a p.
204 explicit location (const position& p = position ())
205 : begin (p)
206 , end (p)
209 /// Construct a 0-width location in \a f, \a l, \a c.
210 explicit location (filename_type* f,
211 counter_type l = ]b4_location_initial_line[,
212 counter_type c = ]b4_location_initial_column[)
213 : begin (f, l, c)
214 , end (f, l, c)
218 /// Initialization.
219 void initialize (filename_type* f = YY_NULLPTR,
220 counter_type l = ]b4_location_initial_line[,
221 counter_type c = ]b4_location_initial_column[)
223 begin.initialize (f, l, c);
224 end = begin;
227 /** \name Line and Column related manipulators
228 ** \{ */
229 public:
230 /// Reset initial location to final location.
231 void step ()
233 begin = end;
236 /// Extend the current location to the COUNT next columns.
237 void columns (counter_type count = 1)
239 end += count;
242 /// Extend the current location to the COUNT next lines.
243 void lines (counter_type count = 1)
245 end.lines (count);
247 /** \} */
250 public:
251 /// Beginning of the located region.
252 position begin;
253 /// End of the located region.
254 position end;
257 /// Join two locations, in place.
258 inline location&
259 operator+= (location& res, const location& end)
261 res.end = end.end;
262 return res;
265 /// Join two locations.
266 inline location
267 operator+ (location res, const location& end)
269 return res += end;
272 /// Add \a width columns to the end position, in place.
273 inline location&
274 operator+= (location& res, location::counter_type width)
276 res.columns (width);
277 return res;
280 /// Add \a width columns to the end position.
281 inline location
282 operator+ (location res, location::counter_type width)
284 return res += width;
287 /// Subtract \a width columns to the end position, in place.
288 inline location&
289 operator-= (location& res, location::counter_type width)
291 return res += -width;
294 /// Subtract \a width columns to the end position.
295 inline location
296 operator- (location res, location::counter_type width)
298 return res -= width;
300 ]b4_percent_define_flag_if([[define_location_comparison]], [[
301 /// Compare two location objects.
302 inline bool
303 operator== (const location& loc1, const location& loc2)
305 return loc1.begin == loc2.begin && loc1.end == loc2.end;
308 /// Compare two location objects.
309 inline bool
310 operator!= (const location& loc1, const location& loc2)
312 return !(loc1 == loc2);
314 ]])[
315 /** \brief Intercept output stream redirection.
316 ** \param ostr the destination output stream
317 ** \param loc a reference to the location to redirect
319 ** Avoid duplicate information.
321 template <typename YYChar>
322 std::basic_ostream<YYChar>&
323 operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
325 location::counter_type end_col
326 = 0 < loc.end.column ? loc.end.column - 1 : 0;
327 ostr << loc.begin;
328 if (loc.end.filename
329 && (!loc.begin.filename
330 || *loc.begin.filename != *loc.end.filename))
331 ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
332 else if (loc.begin.line < loc.end.line)
333 ostr << '-' << loc.end.line << '.' << end_col;
334 else if (loc.begin.column < end_col)
335 ostr << '-' << end_col;
336 return ostr;
341 m4_ifdef([b4_position_file], [[
342 ]b4_output_begin([b4_dir_prefix], [b4_position_file])[
343 ]b4_generated_by[
344 // Starting with Bison 3.2, this file is useless: the structure it
345 // used to define is now defined in "]b4_location_file[".
347 // To get rid of this file:
348 // 1. add '%require "3.2"' (or newer) to your grammar file
349 // 2. remove references to this file from your build system
350 // 3. if you used to include it, include "]b4_location_file[" instead.
352 #include ]b4_location_include[
353 ]b4_output_end[
357 m4_ifdef([b4_location_file], [[
358 ]b4_output_begin([b4_dir_prefix], [b4_location_file])[
359 ]b4_copyright([Locations for Bison parsers in C++])[
361 ** \file ]b4_location_path[
362 ** Define the ]b4_namespace_ref[::location class.
365 ]b4_cpp_guard_open([b4_location_path])[
367 # include <iostream>
368 # include <string>
370 ]b4_null_define[
372 ]b4_namespace_open[
373 ]b4_location_define[
374 ]b4_namespace_close[
375 ]b4_cpp_guard_close([b4_location_path])[
376 ]b4_output_end[
380 m4_popdef([b4_copyright_years])