xref: /aosp_15_r20/external/angle/tools/flex-bison/third_party/skeletons/location.cc (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 #C++ skeleton for Bison
2 
3 #Copyright(C) 2002 - 2015, 2018 - 2021 Free Software Foundation, Inc.
4 
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.
9 #
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.
14 #
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/>.
17 
18 m4_pushdef([b4_copyright_years],
19            [2002-2015, 2018-2021])
20 
21 #b4_location_file
22 #-- -- -- -- -- -- -- --
23 #Name of the file containing the position / location class,
24 #if we want this file.
25 b4_percent_define_check_file([b4_location_file],
26                              [[api.location.file]],
27                              b4_header_if([[location.hh]]))
28 
29 #    b4_location_include
30 #    -- -- -- -- -- -- -- -- -- -
31 #    If location.hh is to be generated, the name under which should it be
32 #    included.
33 #
34 #    b4_location_path
35 #    -- -- -- -- -- -- -- --
36 #    The path to use for the CPP guard.
37 m4_ifdef([b4_location_file],
38 [m4_define([b4_location_include],
39            [b4_percent_define_get([[api.location.include]],
40                                   ["b4_location_file"])])
41  m4_define([b4_location_path],
42            b4_percent_define_get([[api.location.include]],
43                                  ["b4_mapped_dir_prefix[]b4_location_file"]))
44  m4_define([b4_location_path],
45            m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
46  ])
47 
48 #    b4_position_file
49 #    -- -- -- -- -- -- -- --
50 #    Name of the file containing the position class, if we want this file.
51 b4_header_if(
52   [b4_required_version_if(
53     [30200], [],
54     [m4_ifdef([b4_location_file],
55               [m4_define([b4_position_file], [position.hh])])])])
56 
57 #    b4_location_define
58 #    -- -- -- -- -- -- -- -- --
59 #    Define the position and location classes.
60 m4_define([b4_location_define],
61 [[  /// A point in a source file.
62   class position
63   {
64   public:
65     /// Type for file name.
66     typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
67     /// Type for line and column numbers.
68     typedef int counter_type;
69 ]m4_ifdef([b4_location_constructors], [[
70     /// Construct a position.
71     explicit position (filename_type* f = YY_NULLPTR,
72                        counter_type l = ]b4_location_initial_line[,
73                        counter_type c = ]b4_location_initial_column[)
74       : filename (f)
75       , line (l)
76       , column (c)
77     {}
78 
79 ]])[
80     /// Initialization.
81     void initialize (filename_type* fn = YY_NULLPTR,
82                      counter_type l = ]b4_location_initial_line[,
83                      counter_type c = ]b4_location_initial_column[)
84     {
85         filename = fn;
86         line     = l;
87         column   = c;
88     }
89 
90     /** \name Line and Column related manipulators
91      ** \{ */
92     /// (line related) Advance to the COUNT next lines.
93     void lines (counter_type count = 1)
94     {
95         if (count)
96         {
97           column = ]b4_location_initial_column[;
98           line = add_ (line, count, ]b4_location_initial_line[);
99         }
100     }
101 
102     /// (column related) Advance to the COUNT next columns.
103     void columns (counter_type count = 1)
104     {
105       column = add_ (column, count, ]b4_location_initial_column[);
106     }
107     /** \} */
108 
109     /// File name to which this position refers.
110     filename_type* filename;
111     /// Current line number.
112     counter_type line;
113     /// Current column number.
114     counter_type column;
115 
116   private:
117     /// Compute max (min, lhs+rhs).
118     static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
119     {
120         return lhs + rhs < min ? min : lhs + rhs;
121     }
122   };
123 
124   /// Add \a width columns, in place.
125   inline position&
126   operator+= (position& res, position::counter_type width)
127   {
128     res.columns(width);
129     return res;
130   }
131 
132   /// Add \a width columns.
133   inline position
134   operator+ (position res, position::counter_type width)
135   {
136     return res += width;
137   }
138 
139   /// Subtract \a width columns, in place.
140   inline position&
141   operator-= (position& res, position::counter_type width)
142   {
143     return res += -width;
144   }
145 
146   /// Subtract \a width columns.
147   inline position
148   operator- (position res, position::counter_type width)
149   {
150     return res -= width;
151   }
152 ]b4_percent_define_flag_if([[define_location_comparison]], [[
153   /// Compare two position objects.
154   inline bool
155   operator== (const position& pos1, const position& pos2)
156   {
157     return (pos1.line == pos2.line && pos1.column == pos2.column &&
158             (pos1.filename == pos2.filename ||
159              (pos1.filename && pos2.filename && *pos1.filename == *pos2.filename)));
160   }
161 
162   /// Compare two position objects.
163   inline bool
164   operator!= (const position& pos1, const position& pos2)
165   {
166     return !(pos1 == pos2);
167   }
168 ]])[
169   /** \brief Intercept output stream redirection.
170    ** \param ostr the destination output stream
171    ** \param pos a reference to the position to redirect
172    */
173   template <typename YYChar>
174   std::basic_ostream<YYChar>&
175   operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
176   {
177     if (pos.filename)
178         ostr << *pos.filename << ':';
179     return ostr << pos.line << '.' << pos.column;
180   }
181 
182   /// Two points in a source file.
183   class location
184   {
185   public:
186     /// Type for file name.
187     typedef position::filename_type filename_type;
188     /// Type for line and column numbers.
189     typedef position::counter_type counter_type;
190 ]m4_ifdef([b4_location_constructors], [
191     /// Construct a location from \a b to \a e.
192     location (const position& b, const position& e)
193       : begin (b)
194       , end (e)
195     {}
196 
197     /// Construct a 0-width location in \a p.
198     explicit location (const position& p = position ())
199       : begin (p)
200       , end (p)
201     {}
202 
203     /// Construct a 0-width location in \a f, \a l, \a c.
204     explicit location (filename_type* f,
205                        counter_type l = ]b4_location_initial_line[,
206                        counter_type c = ]b4_location_initial_column[)
207       : begin (f, l, c)
208       , end (f, l, c)
209     {}
210 
211 ])[
212     /// Initialization.
213     void initialize (filename_type* f = YY_NULLPTR,
214                      counter_type l = ]b4_location_initial_line[,
215                      counter_type c = ]b4_location_initial_column[)
216     {
217         begin.initialize(f, l, c);
218         end = begin;
219     }
220 
221     /** \name Line and Column related manipulators
222      ** \{ */
223   public:
224     /// Reset initial location to final location.
225     void step ()
226     {
227         begin = end;
228     }
229 
230     /// Extend the current location to the COUNT next columns.
231     void columns (counter_type count = 1)
232     {
233         end += count;
234     }
235 
236     /// Extend the current location to the COUNT next lines.
237     void lines (counter_type count = 1)
238     {
239         end.lines(count);
240     }
241     /** \} */
242 
243 
244   public:
245     /// Beginning of the located region.
246     position begin;
247     /// End of the located region.
248     position end;
249   };
250 
251   /// Join two locations, in place.
252   inline location&
253   operator+= (location& res, const location& end)
254   {
255     res.end = end.end;
256     return res;
257   }
258 
259   /// Join two locations.
260   inline location
261   operator+ (location res, const location& end)
262   {
263     return res += end;
264   }
265 
266   /// Add \a width columns to the end position, in place.
267   inline location&
268   operator+= (location& res, location::counter_type width)
269   {
270     res.columns(width);
271     return res;
272   }
273 
274   /// Add \a width columns to the end position.
275   inline location
276   operator+ (location res, location::counter_type width)
277   {
278     return res += width;
279   }
280 
281   /// Subtract \a width columns to the end position, in place.
282   inline location&
283   operator-= (location& res, location::counter_type width)
284   {
285     return res += -width;
286   }
287 
288   /// Subtract \a width columns to the end position.
289   inline location
290   operator- (location res, location::counter_type width)
291   {
292     return res -= width;
293   }
294 ]b4_percent_define_flag_if([[define_location_comparison]], [[
295   /// Compare two location objects.
296   inline bool
297   operator== (const location& loc1, const location& loc2)
298   {
299     return loc1.begin == loc2.begin && loc1.end == loc2.end;
300   }
301 
302   /// Compare two location objects.
303   inline bool
304   operator!= (const location& loc1, const location& loc2)
305   {
306     return !(loc1 == loc2);
307   }
308 ]])[
309   /** \brief Intercept output stream redirection.
310    ** \param ostr the destination output stream
311    ** \param loc a reference to the location to redirect
312    **
313    ** Avoid duplicate information.
314    */
315   template <typename YYChar>
316   std::basic_ostream<YYChar>&
317   operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
318   {
319     location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
320     ostr << loc.begin;
321     if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
322         ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
323     else if (loc.begin.line < loc.end.line)
324         ostr << '-' << loc.end.line << '.' << end_col;
325     else if (loc.begin.column < end_col)
326         ostr << '-' << end_col;
327     return ostr;
328   }
329 ]])
330 
331 
332 m4_ifdef([b4_position_file], [[
333 ]b4_output_begin([b4_dir_prefix], [b4_position_file])[
334 ]b4_generated_by[
335 // Starting with Bison 3.2, this file is useless: the structure it
336 // used to define is now defined in "]b4_location_file[".
337 //
338 // To get rid of this file:
339 // 1. add '%require "3.2"' (or newer) to your grammar file
340 // 2. remove references to this file from your build system
341 // 3. if you used to include it, include "]b4_location_file[" instead.
342 
343 #    include] b4_location_include[
344 ]b4_output_end[
345 ]])
346 
347 
348 m4_ifdef([b4_location_file], [[
349 ]b4_output_begin([b4_dir_prefix], [b4_location_file])[
350 ]b4_copyright([Locations for Bison parsers in C++])[
351 /**
352  ** \file ]b4_location_path[
353  ** Define the ]b4_namespace_ref[::location class.
354  */
355 
356 ]b4_cpp_guard_open([b4_location_path])[
357 
358 #    include <iostream>
359 #    include <string>
360 
361 ]b4_null_define[
362 
363 ]b4_namespace_open[
364 ]b4_location_define[
365 ]b4_namespace_close[
366 ]b4_cpp_guard_close([b4_location_path])[
367 ]b4_output_end[
368 ]])
369 
370 
371 m4_popdef([b4_copyright_years])
372