]> git.saurik.com Git - bison.git/commitdiff
c++: fix several issues with locations
authorAkim Demaille <akim@lrde.epita.fr>
Thu, 11 Apr 2013 07:53:18 +0000 (09:53 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Thu, 11 Apr 2013 10:50:59 +0000 (12:50 +0200)
Reported by Daniel Frużyński.
http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html

* data/location.cc (position::columns, position::lines): Check for
underflow.
Fix some weird function signatures.
(location): Accept signed integers as arguments where appropriate.
Add operator- and operator+=.
* doc/bison.texi (C++ position, C++ location): Various fixes
and completion.
* tests/c++.at (C++ Locations): New tests.

NEWS
THANKS
data/location.cc
doc/bison.texi
tests/c++.at

diff --git a/NEWS b/NEWS
index d7d89d2a86589bb9dcb73364dcd55da9ce306a25..cf118c15ee83f632b677a7c23491c4fe9560c70f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -569,6 +569,11 @@ GNU Bison NEWS
       ...
     }
 
+*** C++ locations
+
+  There are operator- and operator-= for 'location'.  Negative line/column
+  increments can no longer underflow the resulting value.
+
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
 ** Bug fixes
diff --git a/THANKS b/THANKS
index a7d1d47ec9c244f9d4dd74dafd2c3e0134a75106..320e26f1743eef391600b9023020f78f1d0e886c 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -29,6 +29,7 @@ Cris Bailiff              c.bailiff+bison@awayweb.com
 Cris van Pelt             cris@amf03054.office.wxs.nl
 Csaba Raduly              csaba_22@yahoo.co.uk
 Dagobert Michelsen        dam@baltic-online.de
+Daniel Frużyński          daniel@poradnik-webmastera.com
 Daniel Hagerty            hag@gnu.org
 David J. MacKenzie        djm@gnu.org
 David Kastrup             dak@gnu.org
index 987843b26cd55e9a7a51850dbedc6d1a185d8597..309b9c0f7432098d2624393908e756adf189aa34 100644 (file)
@@ -25,8 +25,7 @@ m4_define([b4_position_define],
 [[  /// Abstract a position.
   class position
   {
-  public:
-]m4_ifdef([b4_location_constructors], [[
+  public:]m4_ifdef([b4_location_constructors], [[
     /// Construct a position.
     explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
                        unsigned int l = ]b4_location_initial_line[u,
@@ -53,14 +52,23 @@ m4_define([b4_position_define],
     /// (line related) Advance to the COUNT next lines.
     void lines (int count = 1)
     {
-      column = ]b4_location_initial_column[u;
-      line += count;
+      if (count)
+        {
+          column = ]b4_location_initial_column[u;
+          line =
+            0 < count || -count < line
+            ? line + count
+            : ]b4_location_initial_line[;
+        }
     }
 
     /// (column related) Advance to the COUNT next columns.
     void columns (int count = 1)
     {
-      column = std::max (]b4_location_initial_column[u, column + count);
+      column =
+        0 < count || -count < column
+        ? column + count
+        : ]b4_location_initial_column[;
     }
     /** \} */
 
@@ -74,32 +82,31 @@ m4_define([b4_position_define],
 
   /// Add and assign a position.
   inline position&
-  operator+= (position& res, const int width)
+  operator+= (position& res, int width)
   {
     res.columns (width);
     return res;
   }
 
   /// Add two position objects.
-  inline const position
-  operator+ (const position& begin, const int width)
+  inline position
+  operator+ (position res, int width)
   {
-    position res = begin;
     return res += width;
   }
 
   /// Add and assign a position.
   inline position&
-  operator-= (position& res, const int width)
+  operator-= (position& res, int width)
   {
     return res += -width;
   }
 
   /// Add two position objects.
-  inline const position
-  operator- (const position& begin, const int width)
+  inline position
+  operator- (position res, int width)
   {
-    return begin + -width;
+    return res -= width;
   }
 ]b4_percent_define_flag_if([[define_location_comparison]], [[
   /// Compare two position objects.
@@ -186,13 +193,13 @@ m4_define([b4_location_define],
     }
 
     /// Extend the current location to the COUNT next columns.
-    void columns (unsigned int count = 1)
+    void columns (int count = 1)
     {
       end += count;
     }
 
     /// Extend the current location to the COUNT next lines.
-    void lines (unsigned int count = 1)
+    void lines (int count = 1)
     {
       end.lines (count);
     }
@@ -207,26 +214,35 @@ m4_define([b4_location_define],
   };
 
   /// Join two location objects to create a location.
-  inline const location operator+ (const location& begin, const location& end)
+  inline location operator+ (location res, const location& end)
   {
-    location res = begin;
     res.end = end.end;
     return res;
   }
 
-  /// Add two location objects.
-  inline const location operator+ (const location& begin, unsigned int width)
+  /// Change end position in place.
+  inline location& operator+= (location& res, int width)
   {
-    location res = begin;
     res.columns (width);
     return res;
   }
 
-  /// Add and assign a location.
-  inline location& operator+= (location& res, unsigned int width)
+  /// Change end position.
+  inline location operator+ (location res, int width)
   {
-    res.columns (width);
-    return res;
+    return res += width;
+  }
+
+  /// Change end position in place.
+  inline location& operator-= (location& res, int width)
+  {
+    return res += -width;
+  }
+
+  /// Change end position.
+  inline location operator- (const location& begin, int width)
+  {
+    return begin + -width;
   }
 ]b4_percent_define_flag_if([[define_location_comparison]], [[
   /// Compare two location objects.
index 250e94d8c74699655f5246b84c99d97cf718cef0..72847a1e0a9180fadcf9c8f056284819338f590a 100644 (file)
@@ -10591,16 +10591,18 @@ filename_type "@var{type}"}.
 The line, starting at 1.
 @end deftypeivar
 
-@deftypemethod {position} {uint} lines (int @var{height} = 1)
-Advance by @var{height} lines, resetting the column number.
+@deftypemethod {position} {void} lines (int @var{height} = 1)
+If @var{height} is not null, advance by @var{height} lines, resetting the
+column number.  The resulting line number cannot be less than 1.
 @end deftypemethod
 
 @deftypeivar {position} {uint} column
 The column, starting at 1.
 @end deftypeivar
 
-@deftypemethod {position} {uint} columns (int @var{width} = 1)
-Advance by @var{width} columns, without changing the line number.
+@deftypemethod {position} {void} columns (int @var{width} = 1)
+Advance by @var{width} columns, without changing the line number. The
+resulting column number cannot be less than 1.
 @end deftypemethod
 
 @deftypemethod {position} {position&} operator+= (int @var{width})
@@ -10642,14 +10644,16 @@ Reset the location to an empty range at the given values.
 The first, inclusive, position of the range, and the first beyond.
 @end deftypeivar
 
-@deftypemethod {location} {uint} columns (int @var{width} = 1)
-@deftypemethodx {location} {uint} lines (int @var{height} = 1)
-Advance the @code{end} position.
+@deftypemethod {location} {void} columns (int @var{width} = 1)
+@deftypemethodx {location} {void} lines (int @var{height} = 1)
+Forwarded to the @code{end} position.
 @end deftypemethod
 
 @deftypemethod {location} {location} operator+ (const location& @var{end})
 @deftypemethodx {location} {location} operator+ (int @var{width})
 @deftypemethodx {location} {location} operator+= (int @var{width})
+@deftypemethodx {location} {location} operator- (int @var{width})
+@deftypemethodx {location} {location} operator-= (int @var{width})
 Various forms of syntactic sugar.
 @end deftypemethod
 
index 3300352d8cfcaf326f3e46eb94f7b69d8045efd0..387d48780b98d3fc7c0ddc3854b3ac58b8089834 100644 (file)
 AT_BANNER([[C++ Features.]])
 
 
+## --------------- ##
+## C++ Locations.  ##
+## --------------- ##
+
+AT_SETUP([C++ Locations])
+
+AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "lalr1.cc"])
+AT_DATA_GRAMMAR([[input.y]],
+[[%code {#include <sstream>}
+%locations
+%debug
+%skeleton "lalr1.cc"
+%code
+{
+]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
+}
+%%
+exp: %empty;
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE[
+
+template <typename T>
+bool
+check (const T& in, const std::string& s)
+{
+  std::stringstream os;
+  os << in;
+  if (os.str () != s)
+    {
+      std::cerr << "fail: " << os.str () << ", expected: " << s << std::endl;
+      return false;
+    }
+  return true;
+}
+
+int
+main (void)
+{
+  int fail = 0;
+  ]AT_YYLTYPE[ loc;  fail += check (loc, "1.1");
+  loc += 10;         fail += check (loc, "1.1-10");
+  loc += -5;         fail += check (loc, "1.1-5");
+  loc -= 5;          fail += check (loc, "1.1");
+  // Check that we don't go below.
+  // http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
+  loc -= 10;         fail += check (loc, "1.1");
+
+  loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0");
+  loc.lines (-2);                   fail += check (loc, "1.1-9.0");
+  loc.lines (-10);                  fail += check (loc, "1.1");
+  return !fail;
+}
+]])
+
+AT_FULL_COMPILE([input])
+AT_PARSER_CHECK([./input], 0)
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
+
 ## --------------------------- ##
 ## C++ Variant-based Symbols.  ##
 ## --------------------------- ##