This helps working around missing C functions like strcasecmp that do not exist everywhere (e.g. on Cygwin), and for which lib/ supplies a replacement. Unfortunately we do not have such build in our current continuous integration suite, so we cannot easily detect files where such config.h inclusion would be useful. Therefore this patch simply makes it mandatory to include config.h in *.cc files. Including this in public *.hh file is currently forbidden. * spot/gen/automata.cc, spot/gen/formulas.cc, spot/kripke/fairkripke.cc, spot/kripke/kripke.cc, spot/ltsmin/ltsmin.cc, spot/misc/game.cc, spot/parseaut/fmterror.cc, spot/parsetl/fmterror.cc, spot/parsetl/parsetl.yy, spot/priv/bddalloc.cc, spot/priv/freelist.cc, spot/priv/satcommon.cc, spot/priv/trim.cc, spot/priv/weight.cc, spot/ta/ta.cc, spot/ta/taexplicit.cc, spot/ta/taproduct.cc, spot/ta/tgtaexplicit.cc, spot/ta/tgtaproduct.cc, spot/taalgos/dot.cc, spot/taalgos/emptinessta.cc, spot/taalgos/minimize.cc, spot/taalgos/reachiter.cc, spot/taalgos/statessetbuilder.cc, spot/taalgos/stats.cc, spot/taalgos/tgba2ta.cc, spot/tl/apcollect.cc, spot/tl/contain.cc, spot/tl/declenv.cc, spot/tl/defaultenv.cc, spot/tl/dot.cc, spot/tl/exclusive.cc, spot/tl/hierarchy.cc, spot/tl/length.cc, spot/tl/ltlf.cc, spot/tl/mark.cc, spot/tl/mutation.cc, spot/tl/nenoform.cc, spot/tl/print.cc, spot/tl/randomltl.cc, spot/tl/relabel.cc, spot/tl/remove_x.cc, spot/tl/simplify.cc, spot/tl/snf.cc, spot/tl/unabbrev.cc, spot/twa/acc.cc, spot/twa/bdddict.cc, spot/twa/bddprint.cc, spot/twa/formula2bdd.cc, spot/twa/taatgba.cc, spot/twa/twa.cc, spot/twa/twagraph.cc, spot/twa/twaproduct.cc, spot/twaalgos/aiger.cc, spot/twaalgos/alternation.cc, spot/twaalgos/are_isomorphic.cc, spot/twaalgos/bfssteps.cc, spot/twaalgos/canonicalize.cc, spot/twaalgos/cleanacc.cc, spot/twaalgos/cobuchi.cc, spot/twaalgos/complement.cc, spot/twaalgos/complete.cc, spot/twaalgos/compsusp.cc, spot/twaalgos/couvreurnew.cc, spot/twaalgos/cycles.cc, spot/twaalgos/degen.cc, spot/twaalgos/determinize.cc, spot/twaalgos/dot.cc, spot/twaalgos/dtbasat.cc, spot/twaalgos/dtwasat.cc, spot/twaalgos/dualize.cc, spot/twaalgos/emptiness.cc, spot/twaalgos/gtec/ce.cc, spot/twaalgos/gtec/gtec.cc, spot/twaalgos/gtec/sccstack.cc, spot/twaalgos/gtec/status.cc, spot/twaalgos/gv04.cc, spot/twaalgos/hoa.cc, spot/twaalgos/iscolored.cc, spot/twaalgos/isdet.cc, spot/twaalgos/isunamb.cc, spot/twaalgos/isweakscc.cc, spot/twaalgos/langmap.cc, spot/twaalgos/lbtt.cc, spot/twaalgos/ltl2taa.cc, spot/twaalgos/ltl2tgba_fm.cc, spot/twaalgos/magic.cc, spot/twaalgos/mask.cc, spot/twaalgos/minimize.cc, spot/twaalgos/neverclaim.cc, spot/twaalgos/parity.cc, spot/twaalgos/postproc.cc, spot/twaalgos/powerset.cc, spot/twaalgos/product.cc, spot/twaalgos/rabin2parity.cc, spot/twaalgos/randomgraph.cc, spot/twaalgos/randomize.cc, spot/twaalgos/reachiter.cc, spot/twaalgos/relabel.cc, spot/twaalgos/remfin.cc, spot/twaalgos/remprop.cc, spot/twaalgos/sbacc.cc, spot/twaalgos/sccfilter.cc, spot/twaalgos/sccinfo.cc, spot/twaalgos/se05.cc, spot/twaalgos/sepsets.cc, spot/twaalgos/simulation.cc, spot/twaalgos/split.cc, spot/twaalgos/stats.cc, spot/twaalgos/strength.cc, spot/twaalgos/stripacc.cc, spot/twaalgos/stutter.cc, spot/twaalgos/sum.cc, spot/twaalgos/tau03.cc, spot/twaalgos/tau03opt.cc, spot/twaalgos/totgba.cc, spot/twaalgos/toweak.cc, spot/twaalgos/translate.cc, spot/twaalgos/word.cc, tests/core/acc.cc, tests/core/bitvect.cc, tests/core/checkpsl.cc, tests/core/checkta.cc, tests/core/consterm.cc, tests/core/emptchk.cc, tests/core/equalsf.cc, tests/core/graph.cc, tests/core/ikwiad.cc, tests/core/intvcmp2.cc, tests/core/intvcomp.cc, tests/core/kind.cc, tests/core/kripkecat.cc, tests/core/length.cc, tests/core/ltlrel.cc, tests/core/ngraph.cc, tests/core/parity.cc, tests/core/randtgba.cc, tests/core/readltl.cc, tests/core/reduc.cc, tests/core/safra.cc, tests/core/sccif.cc, tests/core/syntimpl.cc, tests/core/taatgba.cc, tests/core/tostring.cc, tests/core/trival.cc, tests/core/twagraph.cc, tests/ltsmin/modelcheck.cc, spot/parseaut/scanaut.ll, spot/parsetl/scantl.ll: Include config.h. * spot/gen/Makefile.am, spot/graph/Makefile.am, spot/kripke/Makefile.am, spot/ltsmin/Makefile.am, spot/parseaut/Makefile.am, spot/parsetl/Makefile.am, spot/priv/Makefile.am, spot/ta/Makefile.am, spot/taalgos/Makefile.am, spot/tl/Makefile.am, spot/twa/Makefile.am, spot/twaalgos/Makefile.am, spot/twaalgos/gtec/Makefile.am, tests/Makefile.am: Add the -I lib/ flags. * tests/sanity/includes.test: Catch missing config.h in *.cc, and diagnose config.h in *.hh. * tests/sanity/style.test: Better diagnostics.
222 lines
6.3 KiB
C++
222 lines
6.3 KiB
C++
// -*- coding: utf-8 -*-
|
|
// Copyright (C) 2014, 2018 Laboratoire de Recherche et Développement de
|
|
// l'Epita.
|
|
// Copyright (C) 2004, 2006 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 "config.h"
|
|
#include "spot/priv/freelist.hh"
|
|
#include <cassert>
|
|
#include <iostream>
|
|
|
|
namespace spot
|
|
{
|
|
|
|
free_list::~free_list()
|
|
{
|
|
}
|
|
|
|
int
|
|
free_list::register_n(int n)
|
|
{
|
|
// Browse the free list until we find N consecutive variables. We
|
|
// try not to fragment the list my allocating the variables in the
|
|
// smallest free range we find.
|
|
free_list_type::iterator best = fl.end();
|
|
free_list_type::iterator cur;
|
|
for (cur = fl.begin(); cur != fl.end(); ++cur)
|
|
{
|
|
if (cur->second < n)
|
|
continue;
|
|
if (n == cur->second)
|
|
{
|
|
best = cur;
|
|
break;
|
|
}
|
|
if (best == fl.end()
|
|
|| cur->second < best->second)
|
|
best = cur;
|
|
}
|
|
|
|
// We have found enough free variables.
|
|
if (best != fl.end())
|
|
{
|
|
int result = best->first;
|
|
remove(best, result, n);
|
|
return result;
|
|
}
|
|
|
|
// We haven't found enough adjacent free variables;
|
|
// ask for some more.
|
|
return extend(n);
|
|
}
|
|
|
|
void
|
|
free_list::insert(int base, int n)
|
|
{
|
|
free_list_type::iterator cur;
|
|
int end = base + n;
|
|
for (cur = fl.begin(); cur != fl.end(); ++cur)
|
|
{
|
|
int cend = cur->first + cur->second;
|
|
// cur [...]
|
|
// to insert [...]
|
|
// -----------------------
|
|
// result [...] [...]
|
|
// (Insert a new range, unconnected.)
|
|
if (cur->first > end)
|
|
{
|
|
break;
|
|
}
|
|
// cur [...]
|
|
// to insert [...]
|
|
// -----------------------
|
|
// result unknown : we should look at the rest of the freelist.
|
|
else if (base > cend)
|
|
{
|
|
continue;
|
|
}
|
|
// cur [....[ [......[
|
|
// to insert [....[ [..[
|
|
// ----------------------------------
|
|
// result [......[ [......[
|
|
else if (cur->first <= base)
|
|
{
|
|
if (cend >= end)
|
|
// second case : nothing to do
|
|
return;
|
|
// cur->second is set below.
|
|
}
|
|
// cur [....[ [..[
|
|
// to insert [....[ [.......[
|
|
// ----------------------------------
|
|
// result [......[ [.......[
|
|
else
|
|
{
|
|
cur->first = base;
|
|
// cur->second is set below.
|
|
}
|
|
|
|
// We get here in one of these three situations:
|
|
//
|
|
// cur [....[ [....[ [..[
|
|
// to insert [....[ [....[ [.......[
|
|
// -------------------------------------------
|
|
// result [......[ [......[ [.......[
|
|
//
|
|
// cur->first is already set, be cur->second has yet to be.
|
|
end = std::max(cend, end);
|
|
cur->second = end - cur->first;
|
|
// Since we have extended the current range, maybe the next
|
|
// items on the list should be merged.
|
|
free_list_type::iterator next = cur;
|
|
++next;
|
|
while (next != fl.end() && next->first <= end)
|
|
{
|
|
end = std::max(next->first + next->second, end);
|
|
cur->second = end - cur->first;
|
|
free_list_type::iterator next2 = next++;
|
|
fl.erase(next2);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// We reach this place either because a new unconnected range
|
|
// should be inserted in the middle of FL, or at the end.
|
|
fl.insert(cur, pos_lenght_pair(base, n));
|
|
}
|
|
|
|
void
|
|
free_list::remove(int base, int n)
|
|
{
|
|
free_list_type::iterator cur = fl.begin();
|
|
int end = base + n;
|
|
while (cur != fl.end() && cur->first < end)
|
|
{
|
|
int cend = cur->first + cur->second;
|
|
// Remove may invalidate the current iterator, so advance it first.
|
|
free_list_type::iterator old = cur++;
|
|
if (cend >= base)
|
|
{
|
|
int newbase = std::max(base, old->first);
|
|
int q = std::min(cend, end) - newbase;
|
|
remove(old, newbase, q);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
free_list::remove(free_list_type::iterator i, int base, int n)
|
|
{
|
|
if (base == i->first)
|
|
{
|
|
// Removing at the beginning of the range
|
|
i->second -= n;
|
|
assert(i->second >= 0);
|
|
// Erase the range if it's now empty.
|
|
if (i->second == 0)
|
|
fl.erase(i);
|
|
else
|
|
i->first += n;
|
|
}
|
|
else if (base + n == i->first + i->second)
|
|
{
|
|
// Removing at the end of the range
|
|
i->second -= n;
|
|
assert(i->second > 0); // cannot be empty because base != i->first
|
|
}
|
|
else
|
|
{
|
|
// Removing in the middle of a range.
|
|
int b1 = i->first;
|
|
int n1 = base - i->first;
|
|
int n2 = i->first + i->second - base - n;
|
|
assert(n1 > 0);
|
|
assert(n2 > 0);
|
|
*i = pos_lenght_pair(base + n, n2);
|
|
fl.insert(i, pos_lenght_pair(b1, n1));
|
|
}
|
|
}
|
|
|
|
void
|
|
free_list::release_n(int base, int n)
|
|
{
|
|
insert(base, n);
|
|
}
|
|
|
|
std::ostream&
|
|
free_list::dump_free_list(std::ostream& os) const
|
|
{
|
|
free_list_type::const_iterator i;
|
|
for (i = fl.begin(); i != fl.end(); ++i)
|
|
os << " (" << i->first << ", " << i->second << ')';
|
|
return os;
|
|
}
|
|
|
|
int
|
|
free_list::free_count() const
|
|
{
|
|
int res = 0;
|
|
free_list_type::const_iterator i;
|
|
for (i = fl.begin(); i != fl.end(); ++i)
|
|
res += i->second;
|
|
return res;
|
|
}
|
|
|
|
}
|