]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/source-file.cc
Imported Upstream version 2.14.2
[lilypond.git] / lily / source-file.cc
index fc5b03483d78cc85582d04bf7ad576c9bb681a64..b01676355840a1877bacc3b9439809cb195ce496 100644 (file)
@@ -1,10 +1,21 @@
 /*
-  source-file.cc -- implement Source_file
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
-
-  (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org>
+  Copyright (C) 1997--2011 Jan Nieuwenhuizen <janneke@gnu.org>
   Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #if GCC_MAJOR < 4
 
 #include "config.hh"
 
-#if HAVE_UTF8_WCHAR_H
-#include <utf8/wchar.h>  /* mbrtowc */
-#else /* !HAVE_UTF8_WCHAR_H */
-#include <cwchar> /* mbrtowc */
-#endif /* HAVE_UTF8_WCHAR_H */
-
 #include <cstdio>
 
 #if HAVE_SSTREAM
@@ -34,6 +39,7 @@ using namespace std;
 
 #include "file-name-map.hh"
 #include "international.hh"
+#include "misc.hh"
 #include "warn.hh"
 
 void
@@ -42,7 +48,7 @@ Source_file::load_stdin ()
   characters_.clear ();
   int c;
   while ((c = fgetc (stdin)) != EOF)
-    characters_.push_back (c);
+    characters_.push_back ((char)c);
 }
 
 /*
@@ -173,8 +179,8 @@ Source_file::file_line_column_string (char const *context_str0) const
     return " (" + _ ("position unknown") + ")";
   else
     {
-      int l, ch, col;
-      get_counts (context_str0, &l, &ch, &col);
+      int l, ch, col, offset;
+      get_counts (context_str0, &l, &ch, &col, &offset);
 
       return name_string () + ":" + to_string (l)
        + ":" + to_string (col);
@@ -187,13 +193,13 @@ Source_file::quote_input (char const *pos_str0) const
   if (!contains (pos_str0))
     return " (" + _ ("position unknown") + ")";
 
-  int l, ch, col;
-  get_counts (pos_str0, &l, &ch, &col);
+  int l, ch, col, offset;
+  get_counts (pos_str0, &l, &ch, &col, &offset);
   string line = line_string (pos_str0);
-  string context = line.substr (0, ch)
+  string context = line.substr (0, offset)
     + to_string ('\n')
     + to_string (' ', col)
-    + line.substr (ch, line.length ()-ch);
+    + line.substr (offset, line.length () - offset);
   return context;
 }
 
@@ -253,11 +259,10 @@ void
 Source_file::get_counts (char const *pos_str0,
                         int *line_number,
                         int *line_char,
-                        int *column) const
+                        int *column,
+                        int *byte_offset) const
 {
   *line_number = 0;
-  *line_char = 0;
-  *column = 0;
     
   if (!contains (pos_str0))
     return;
@@ -272,36 +277,13 @@ Source_file::get_counts (char const *pos_str0,
   string line_begin (line_start, left);
   char const *line_chars = line_begin.c_str ();
 
-  *column = 0;
   *line_char = 0;
-
-  mbstate_t state;
-
-  /* Initialize the state.  */
-  memset (&state, '\0', sizeof (state));
+  *column = 0;
+  *byte_offset = 0;
 
   while (left > 0)
     {
-      /*
-       FIXME, this is apparently locale dependent.
-      */
-#if HAVE_MBRTOWC
-      wchar_t multibyte[2];
-      size_t thislen = mbrtowc (multibyte, line_chars, left, &state);
-#else
-      size_t thislen = 1;
-#endif /* !HAVE_MBRTOWC */
-
-      /* Stop converting at invalid character;
-        this can mean we have read just the first part
-        of a valid character.  */
-      if (thislen == (size_t) -1)
-       break;
-
-      /* We want to handle embedded NUL bytes
-        but the return value is 0.  Correct this.  */
-      if (thislen == 0)
-       thislen = 1;
+      size_t thislen = utf8_char_len (*line_chars);
 
       if (thislen == 1 && line_chars[0] == '\t')
        (*column) = (*column / 8 + 1) * 8;
@@ -309,6 +291,14 @@ Source_file::get_counts (char const *pos_str0,
        (*column)++;
 
       (*line_char)++;
+
+      /*
+       To have decent output in UTF-8 aware terminals,
+       we must keep track of the number of bytes from
+       the left edge of the terminal.
+      */
+      *byte_offset += thislen;
+
       /* Advance past this character. */
       line_chars += thislen;
       left -= thislen;