Update URLs to prefer https: to http:
[bison.git] / data / skeletons / location.cc
blob1ec48de7498bef19d7e71fcec2e2ba2f07cb5336
1 # C++ skeleton for Bison
3 # Copyright (C) 2002-2015, 2018-2021 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-2021])
22 # b4_position_file
23 # ----------------
24 # Name of the file containing the position class, if we want this file.
25 b4_defines_if([b4_required_version_if([30200], [],
26 [m4_define([b4_position_file], [position.hh])])])])
29 # b4_location_file
30 # ----------------
31 # Name of the file containing the position/location class,
32 # if we want this file.
33 b4_percent_define_check_file([b4_location_file],
34 [[api.location.file]],
35 b4_defines_if([[location.hh]]))
37 # b4_location_include
38 # -------------------
39 # If location.hh is to be generated, the name under which should it be
40 # included.
42 # b4_location_path
43 # ----------------
44 # The path to use for the CPP guard.
45 m4_ifdef([b4_location_file],
46 [m4_define([b4_location_include],
47 [b4_percent_define_get([[api.location.include]],
48 ["b4_location_file"])])
49 m4_define([b4_location_path],
50 b4_percent_define_get([[api.location.include]],
51 ["b4_mapped_dir_prefix[]b4_location_file"]))
52 m4_define([b4_location_path],
53 m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
58 # b4_location_define
59 # ------------------
60 # Define the position and location classes.
61 m4_define([b4_location_define],
62 [[ /// A point in a source file.
63 class position
65 public:
66 /// Type for file name.
67 typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
68 /// Type for line and column numbers.
69 typedef int counter_type;
70 ]m4_ifdef([b4_location_constructors], [[
71 /// Construct a position.
72 explicit position (filename_type* f = YY_NULLPTR,
73 counter_type l = ]b4_location_initial_line[,
74 counter_type c = ]b4_location_initial_column[)
75 : filename (f)
76 , line (l)
77 , column (c)
80 ]])[
81 /// Initialization.
82 void initialize (filename_type* fn = YY_NULLPTR,
83 counter_type l = ]b4_location_initial_line[,
84 counter_type c = ]b4_location_initial_column[)
86 filename = fn;
87 line = l;
88 column = c;
91 /** \name Line and Column related manipulators
92 ** \{ */
93 /// (line related) Advance to the COUNT next lines.
94 void lines (counter_type count = 1)
96 if (count)
98 column = ]b4_location_initial_column[;
99 line = add_ (line, count, ]b4_location_initial_line[);
103 /// (column related) Advance to the COUNT next columns.
104 void columns (counter_type count = 1)
106 column = add_ (column, count, ]b4_location_initial_column[);
108 /** \} */
110 /// File name to which this position refers.
111 filename_type* filename;
112 /// Current line number.
113 counter_type line;
114 /// Current column number.
115 counter_type column;
117 private:
118 /// Compute max (min, lhs+rhs).
119 static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
121 return lhs + rhs < min ? min : lhs + rhs;
125 /// Add \a width columns, in place.
126 inline position&
127 operator+= (position& res, position::counter_type width)
129 res.columns (width);
130 return res;
133 /// Add \a width columns.
134 inline position
135 operator+ (position res, position::counter_type width)
137 return res += width;
140 /// Subtract \a width columns, in place.
141 inline position&
142 operator-= (position& res, position::counter_type width)
144 return res += -width;
147 /// Subtract \a width columns.
148 inline position
149 operator- (position res, position::counter_type width)
151 return res -= width;
153 ]b4_percent_define_flag_if([[define_location_comparison]], [[
154 /// Compare two position objects.
155 inline bool
156 operator== (const position& pos1, const position& pos2)
158 return (pos1.line == pos2.line
159 && pos1.column == pos2.column
160 && (pos1.filename == pos2.filename
161 || (pos1.filename && pos2.filename
162 && *pos1.filename == *pos2.filename)));
165 /// Compare two position objects.
166 inline bool
167 operator!= (const position& pos1, const position& pos2)
169 return !(pos1 == pos2);
171 ]])[
172 /** \brief Intercept output stream redirection.
173 ** \param ostr the destination output stream
174 ** \param pos a reference to the position to redirect
176 template <typename YYChar>
177 std::basic_ostream<YYChar>&
178 operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
180 if (pos.filename)
181 ostr << *pos.filename << ':';
182 return ostr << pos.line << '.' << pos.column;
185 /// Two points in a source file.
186 class location
188 public:
189 /// Type for file name.
190 typedef position::filename_type filename_type;
191 /// Type for line and column numbers.
192 typedef position::counter_type counter_type;
193 ]m4_ifdef([b4_location_constructors], [
194 /// Construct a location from \a b to \a e.
195 location (const position& b, const position& e)
196 : begin (b)
197 , end (e)
200 /// Construct a 0-width location in \a p.
201 explicit location (const position& p = position ())
202 : begin (p)
203 , end (p)
206 /// Construct a 0-width location in \a f, \a l, \a c.
207 explicit location (filename_type* f,
208 counter_type l = ]b4_location_initial_line[,
209 counter_type c = ]b4_location_initial_column[)
210 : begin (f, l, c)
211 , end (f, l, c)
215 /// Initialization.
216 void initialize (filename_type* f = YY_NULLPTR,
217 counter_type l = ]b4_location_initial_line[,
218 counter_type c = ]b4_location_initial_column[)
220 begin.initialize (f, l, c);
221 end = begin;
224 /** \name Line and Column related manipulators
225 ** \{ */
226 public:
227 /// Reset initial location to final location.
228 void step ()
230 begin = end;
233 /// Extend the current location to the COUNT next columns.
234 void columns (counter_type count = 1)
236 end += count;
239 /// Extend the current location to the COUNT next lines.
240 void lines (counter_type count = 1)
242 end.lines (count);
244 /** \} */
247 public:
248 /// Beginning of the located region.
249 position begin;
250 /// End of the located region.
251 position end;
254 /// Join two locations, in place.
255 inline location&
256 operator+= (location& res, const location& end)
258 res.end = end.end;
259 return res;
262 /// Join two locations.
263 inline location
264 operator+ (location res, const location& end)
266 return res += end;
269 /// Add \a width columns to the end position, in place.
270 inline location&
271 operator+= (location& res, location::counter_type width)
273 res.columns (width);
274 return res;
277 /// Add \a width columns to the end position.
278 inline location
279 operator+ (location res, location::counter_type width)
281 return res += width;
284 /// Subtract \a width columns to the end position, in place.
285 inline location&
286 operator-= (location& res, location::counter_type width)
288 return res += -width;
291 /// Subtract \a width columns to the end position.
292 inline location
293 operator- (location res, location::counter_type width)
295 return res -= width;
297 ]b4_percent_define_flag_if([[define_location_comparison]], [[
298 /// Compare two location objects.
299 inline bool
300 operator== (const location& loc1, const location& loc2)
302 return loc1.begin == loc2.begin && loc1.end == loc2.end;
305 /// Compare two location objects.
306 inline bool
307 operator!= (const location& loc1, const location& loc2)
309 return !(loc1 == loc2);
311 ]])[
312 /** \brief Intercept output stream redirection.
313 ** \param ostr the destination output stream
314 ** \param loc a reference to the location to redirect
316 ** Avoid duplicate information.
318 template <typename YYChar>
319 std::basic_ostream<YYChar>&
320 operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
322 location::counter_type end_col
323 = 0 < loc.end.column ? loc.end.column - 1 : 0;
324 ostr << loc.begin;
325 if (loc.end.filename
326 && (!loc.begin.filename
327 || *loc.begin.filename != *loc.end.filename))
328 ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
329 else if (loc.begin.line < loc.end.line)
330 ostr << '-' << loc.end.line << '.' << end_col;
331 else if (loc.begin.column < end_col)
332 ostr << '-' << end_col;
333 return ostr;
338 m4_ifdef([b4_position_file], [[
339 ]b4_output_begin([b4_dir_prefix], [b4_position_file])[
340 ]b4_generated_by[
341 // Starting with Bison 3.2, this file is useless: the structure it
342 // used to define is now defined in "]b4_location_file[".
344 // To get rid of this file:
345 // 1. add '%require "3.2"' (or newer) to your grammar file
346 // 2. remove references to this file from your build system
347 // 3. if you used to include it, include "]b4_location_file[" instead.
349 #include ]b4_location_include[
350 ]b4_output_end[
354 m4_ifdef([b4_location_file], [[
355 ]b4_output_begin([b4_dir_prefix], [b4_location_file])[
356 ]b4_copyright([Locations for Bison parsers in C++])[
358 ** \file ]b4_location_path[
359 ** Define the ]b4_namespace_ref[::location class.
362 ]b4_cpp_guard_open([b4_location_path])[
364 # include <iostream>
365 # include <string>
367 ]b4_null_define[
369 ]b4_namespace_open[
370 ]b4_location_define[
371 ]b4_namespace_close[
372 ]b4_cpp_guard_close([b4_location_path])[
373 ]b4_output_end[
377 m4_popdef([b4_copyright_years])