#include "config.hh"
#if HAVE_UTF8_WCHAR_H
-#include <utf8/wchar.h> /* wcrtomb */
+#include <utf8/wchar.h> /* mbrtowc */
#else
-#include <wchar.h> /* wcrtomb */
+#include <wchar.h> /* mbrtowc */
#endif
#include <cstdio>
if (!to_str0 ())
return " (" + _ ("position unknown") + ")";
else
- return name_string () + ":" + to_string (get_line (context_str0))
- + ":" + to_string (get_column (context_str0));
+ {
+ int l, ch, col;
+ get_counts (context_str0, &l, &ch, &col);
+
+ return name_string () + ":" + to_string (l)
+ + ":" + to_string (col);
+ }
+}
+
+
+
+String
+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);
+ String line = line_string (pos_str0);
+ String context = line.left_string (ch)
+ + to_string ('\n')
+ + to_string (' ', col)
+ + line.cut_string (ch, INT_MAX);
+ return context;
}
String
return String ((Byte const *)data_str0 + line[LEFT], line.length ());
}
-int
-Source_file::get_char_of_line (char const *pos_str0) const
-{
- if (!contains (pos_str0))
- return 0;
-
- char const *data_str0 = to_str0 ();
- return pos_str0 - (line_slice (pos_str0)[SMALLER] + data_str0);
-}
-int
-Source_file::get_column (char const *pos_str0) const
+void
+Source_file::get_counts (char const *pos_str0,
+ int *line_number,
+ int *line_char,
+ int *column) const
{
if (!contains (pos_str0))
- return 0;
+ return;
+ *line_number = get_line (pos_str0);
+
Slice line = line_slice (pos_str0);
char const *data = to_str0 ();
Byte const *line_start = (Byte const *)data + line[LEFT];
String line_begin (line_start, left);
char const *line_chars = line_begin.to_str0();
- int column = 0;
+ *column = 0;
+ *line_char = 0;
+
mbstate_t state;
/* Initialize the state. */
while (left > 0)
{
wchar_t multibyte[2];
+
+ /*
+ FIXME, this is apparently locale dependent.
+ */
size_t thislen = mbrtowc (multibyte, line_chars, left, &state);
/* Stop converting at invalid character;
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;
if (thislen == 1 && line_chars[0] == '\t')
- column = (column / 8 + 1) * 8;
+ (*column) = (*column / 8 + 1) * 8;
else
- column ++;
-
+ (*column) ++;
+
+ (*line_char) ++;
/* Advance past this character. */
line_chars += thislen;
left -= thislen;
}
- return column;
-}
-String
-Source_file::error_string (char const* pos_str0) const
-{
- if (!contains (pos_str0))
- return " (" + _ ("position unknown") + ")";
-
- int ch_i = get_char_of_line (pos_str0);
- String line = line_string (pos_str0);
- String context = line.left_string (ch_i)
- + to_string ('\n')
- + to_string (' ', get_column (pos_str0))
- + line.cut_string (ch_i, INT_MAX);
-
- return context;
}
-
bool
Source_file::contains (char const* pos_str0) const
{
if (contains (pos_str0))
pos_str0_ = pos_str0;
else
- error (error_string (pos_str0) + "invalid pos");
+ error (quote_input (pos_str0) + "invalid pos");
}
char const *
if (contains (new_str0))
pos_str0_ = new_str0;
else
- error (error_string (new_str0) + "seek past eof");
+ error (quote_input (new_str0) + "seek past eof");
return pos_str0_;
}
if (contains (new_str0))
pos_str0_ = new_str0;
else
- error (error_string (new_str0) + "forward past eof");
+ error (quote_input (new_str0) + "forward past eof");
return old_pos;
}