xref: /aosp_15_r20/prebuilts/build-tools/common/bison/skeletons/location.cc (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
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 
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]]))
29 
30 # b4_location_include
31 # -------------------
32 # If location.hh is to be generated, the name under which should it be
33 # included.
34 #
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)))
47  ])
48 
49 
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])])])])
58 
59 
60 
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
67   {
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)
81     {}
82 
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[)
88     {
89       filename = fn;
90       line = l;
91       column = c;
92     }
93 
94     /** \name Line and Column related manipulators
95      ** \{ */
96     /// (line related) Advance to the COUNT next lines.
97     void lines (counter_type count = 1)
98     {
99       if (count)
100         {
101           column = ]b4_location_initial_column[;
102           line = add_ (line, count, ]b4_location_initial_line[);
103         }
104     }
105 
106     /// (column related) Advance to the COUNT next columns.
107     void columns (counter_type count = 1)
108     {
109       column = add_ (column, count, ]b4_location_initial_column[);
110     }
111     /** \} */
112 
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;
119 
120   private:
121     /// Compute max (min, lhs+rhs).
122     static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
123     {
124       return lhs + rhs < min ? min : lhs + rhs;
125     }
126   };
127 
128   /// Add \a width columns, in place.
129   inline position&
130   operator+= (position& res, position::counter_type width)
131   {
132     res.columns (width);
133     return res;
134   }
135 
136   /// Add \a width columns.
137   inline position
138   operator+ (position res, position::counter_type width)
139   {
140     return res += width;
141   }
142 
143   /// Subtract \a width columns, in place.
144   inline position&
145   operator-= (position& res, position::counter_type width)
146   {
147     return res += -width;
148   }
149 
150   /// Subtract \a width columns.
151   inline position
152   operator- (position res, position::counter_type width)
153   {
154     return res -= width;
155   }
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)
160   {
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)));
166   }
167 
168   /// Compare two position objects.
169   inline bool
170   operator!= (const position& pos1, const position& pos2)
171   {
172     return !(pos1 == pos2);
173   }
174 ]])[
175   /** \brief Intercept output stream redirection.
176    ** \param ostr the destination output stream
177    ** \param pos a reference to the position to redirect
178    */
179   template <typename YYChar>
180   std::basic_ostream<YYChar>&
181   operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
182   {
183     if (pos.filename)
184       ostr << *pos.filename << ':';
185     return ostr << pos.line << '.' << pos.column;
186   }
187 
188   /// Two points in a source file.
189   class location
190   {
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)
201     {}
202 
203     /// Construct a 0-width location in \a p.
204     explicit location (const position& p = position ())
205       : begin (p)
206       , end (p)
207     {}
208 
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)
215     {}
216 
217 ])[
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[)
222     {
223       begin.initialize (f, l, c);
224       end = begin;
225     }
226 
227     /** \name Line and Column related manipulators
228      ** \{ */
229   public:
230     /// Reset initial location to final location.
231     void step ()
232     {
233       begin = end;
234     }
235 
236     /// Extend the current location to the COUNT next columns.
237     void columns (counter_type count = 1)
238     {
239       end += count;
240     }
241 
242     /// Extend the current location to the COUNT next lines.
243     void lines (counter_type count = 1)
244     {
245       end.lines (count);
246     }
247     /** \} */
248 
249 
250   public:
251     /// Beginning of the located region.
252     position begin;
253     /// End of the located region.
254     position end;
255   };
256 
257   /// Join two locations, in place.
258   inline location&
259   operator+= (location& res, const location& end)
260   {
261     res.end = end.end;
262     return res;
263   }
264 
265   /// Join two locations.
266   inline location
267   operator+ (location res, const location& end)
268   {
269     return res += end;
270   }
271 
272   /// Add \a width columns to the end position, in place.
273   inline location&
274   operator+= (location& res, location::counter_type width)
275   {
276     res.columns (width);
277     return res;
278   }
279 
280   /// Add \a width columns to the end position.
281   inline location
282   operator+ (location res, location::counter_type width)
283   {
284     return res += width;
285   }
286 
287   /// Subtract \a width columns to the end position, in place.
288   inline location&
289   operator-= (location& res, location::counter_type width)
290   {
291     return res += -width;
292   }
293 
294   /// Subtract \a width columns to the end position.
295   inline location
296   operator- (location res, location::counter_type width)
297   {
298     return res -= width;
299   }
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)
304   {
305     return loc1.begin == loc2.begin && loc1.end == loc2.end;
306   }
307 
308   /// Compare two location objects.
309   inline bool
310   operator!= (const location& loc1, const location& loc2)
311   {
312     return !(loc1 == loc2);
313   }
314 ]])[
315   /** \brief Intercept output stream redirection.
316    ** \param ostr the destination output stream
317    ** \param loc a reference to the location to redirect
318    **
319    ** Avoid duplicate information.
320    */
321   template <typename YYChar>
322   std::basic_ostream<YYChar>&
323   operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
324   {
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;
337   }
338 ]])
339 
340 
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[".
346 //
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.
351 
352 #include ]b4_location_include[
353 ]b4_output_end[
354 ]])
355 
356 
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++])[
360 /**
361  ** \file ]b4_location_path[
362  ** Define the ]b4_namespace_ref[::location class.
363  */
364 
365 ]b4_cpp_guard_open([b4_location_path])[
366 
367 # include <iostream>
368 # include <string>
369 
370 ]b4_null_define[
371 
372 ]b4_namespace_open[
373 ]b4_location_define[
374 ]b4_namespace_close[
375 ]b4_cpp_guard_close([b4_location_path])[
376 ]b4_output_end[
377 ]])
378 
379 
380 m4_popdef([b4_copyright_years])
381