* src/sanity/style.test: Test for the missing header. * iface/ltsmin/check.test, src/kripketest/kripke.test, src/kripketest/parse_print_test.cc, src/ltlparse/fmterror.cc, src/ltltest/consterm.test, src/ltltest/kind.test, src/ltltest/length.test, src/ltltest/ltlfilt.test, src/ltltest/reduc.cc, src/ltltest/reduc.test, src/ltltest/reduc0.test, src/ltltest/reducpsl.test, src/ltltest/remove_x.test, src/ltltest/unabbrevwm.test, src/ltltest/utf8.test, src/ltltest/uwrm.test, src/ltlvisit/dump.cc, src/ltlvisit/remove_x.cc, src/misc/casts.hh, src/misc/fixpool.hh, src/misc/hashfunc.hh, src/misc/ltstr.hh, src/sanity/readme.test, src/taalgos/tgba2ta.cc, src/tgbaalgos/bfssteps.cc, src/tgbaalgos/stats.cc, src/tgbatest/acc.test, src/tgbatest/bitvect.test, src/tgbatest/complementation.test, src/tgbatest/cycles.test, src/tgbatest/degendet.test, src/tgbatest/dfs.test, src/tgbatest/dupexp.test, src/tgbatest/emptchkr.test, src/tgbatest/intvcomp.test, src/tgbatest/ltl2ta.test, src/tgbatest/ltl2ta2.test, src/tgbatest/ltlprod.test, src/tgbatest/maskacc.test, src/tgbatest/obligation.test, src/tgbatest/randpsl.test, src/tgbatest/readsat.cc, src/tgbatest/readsat.test, src/tgbatest/scc.test, src/tgbatest/sccsimpl.test, src/tgbatest/taatgba.test, src/tgbatest/tgbaread.test, src/tgbatest/tripprod.test, src/tgbatest/uniq.test, src/tgbatest/wdba.test: Add it.
117 lines
3.3 KiB
C++
117 lines
3.3 KiB
C++
// -*- coding: utf-8 -*-
|
|
// Copyright (C) 2010, 2012, 2013, 2015 Laboratoire de Recherche et
|
|
// Développement de l'Epita (LRDE).
|
|
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris
|
|
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
|
// Université Pierre et Marie Curie.
|
|
//
|
|
// This file is part of Spot, a model checking library.
|
|
//
|
|
// Spot 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.
|
|
//
|
|
// Spot 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include "public.hh"
|
|
#include <ostream>
|
|
#include <iterator>
|
|
#include <vector>
|
|
#include "utf8/utf8.h"
|
|
|
|
namespace spot
|
|
{
|
|
namespace ltl
|
|
{
|
|
|
|
void
|
|
fix_utf8_locations(const std::string& ltl_string,
|
|
parse_error_list& error_list)
|
|
{
|
|
// LUT to convert byte positions to utf8 positions.
|
|
// (The +2 is to account for position 0, not used,
|
|
// and position ltl_string.size()+1 denoting EOS.)
|
|
std::vector<unsigned> b2u(ltl_string.size() + 2);
|
|
|
|
// i will iterate over all utf8 characters between b and e
|
|
std::string::const_iterator b = ltl_string.begin();
|
|
std::string::const_iterator i = b;
|
|
std::string::const_iterator e = ltl_string.end();
|
|
|
|
unsigned n = 0; // number of current utf8 character
|
|
unsigned prev = 0; // last byte of previous utf8 character
|
|
while (i != e)
|
|
{
|
|
utf8::next(i, e);
|
|
++n;
|
|
unsigned d = std::distance(b, i);
|
|
while (prev < d)
|
|
b2u[++prev] = n;
|
|
}
|
|
b2u[++prev] = ++n;
|
|
|
|
// use b2u to update error_list
|
|
parse_error_list::iterator it;
|
|
for (it = error_list.begin(); it != error_list.end(); ++it)
|
|
{
|
|
location& l = it->first;
|
|
l.begin.column = b2u[l.begin.column];
|
|
l.end.column = b2u[l.end.column];
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
bool
|
|
format_parse_errors_aux(std::ostream& os,
|
|
const std::string& ltl_string,
|
|
const parse_error_list& error_list)
|
|
{
|
|
bool printed = false;
|
|
parse_error_list::const_iterator it;
|
|
for (it = error_list.begin(); it != error_list.end(); ++it)
|
|
{
|
|
os << ">>> " << ltl_string << std::endl;
|
|
const location& l = it->first;
|
|
|
|
unsigned n = 1;
|
|
for (; n < 4 + l.begin.column; ++n)
|
|
os << ' ';
|
|
// Write at least one '^', even if begin==end.
|
|
os << '^';
|
|
++n;
|
|
for (; n < 4 + l.end.column; ++n)
|
|
os << '^';
|
|
os << std::endl << it->second << std::endl << std::endl;
|
|
printed = true;
|
|
}
|
|
return printed;
|
|
}
|
|
}
|
|
|
|
bool
|
|
format_parse_errors(std::ostream& os,
|
|
const std::string& ltl_string,
|
|
const parse_error_list& error_list)
|
|
{
|
|
if (utf8::is_valid(ltl_string.begin(), ltl_string.end()))
|
|
{
|
|
parse_error_list fixed = error_list;
|
|
fix_utf8_locations(ltl_string, fixed);
|
|
return format_parse_errors_aux(os, ltl_string, fixed);
|
|
}
|
|
else
|
|
{
|
|
return format_parse_errors_aux(os, ltl_string, error_list);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|