Skip to content
Snippets Groups Projects
Commit f501c31a authored by casse's avatar casse
Browse files

Added missing files.

parent 2439c122
No related branches found
No related tags found
No related merge requests found
......@@ -46,6 +46,7 @@ public:
virtual void write(const char *s) = 0;
virtual void write(cstring x) = 0;
virtual void write(const string& x) = 0;
inline void key(const char *x) { key(cstring(x)); }
virtual void key(cstring x) = 0;
virtual void key(const string& x) = 0;
virtual void beginMap() = 0;
......
......@@ -22,11 +22,13 @@ public:
: io::Output(_stream), _stream(capacity, increment)
{ init(); }
inline String toString(void)
inline String toString()
{ int len = length(); _stream.write('\0');
return String((String::buffer_t *)_stream.detach(), sizeof(short), len); }
inline CString toCString()
{ _stream.write('\0'); return _stream.block() + sizeof(short); }
inline String copyString(void)
inline String copyString()
{ return String( _stream.block() + sizeof(short), _stream.size() - sizeof(short)); }
inline int length(void) const { return _stream.size() - sizeof(short); }
inline void reset(void) { _stream.clear(); init(); }
......
......@@ -106,7 +106,6 @@ void Saver::nextByValue() {
* Close the JSON output.
*/
void Saver::close(void) {
ASSERTP(state == END, "json: unended output!");
_out.flush();
}
......
......@@ -30,6 +30,14 @@ namespace elm { namespace utf8 {
* @ingroup string
*/
///
inline void bad_encoding(char c) {
throw Exception(_ <<
"utf8: bad encoding: " << c
<< " (" << t::uint8(c) << ")");
}
/**
*/
void Iter::parse(void) {
......@@ -42,7 +50,8 @@ void Iter::parse(void) {
c = 0;
// read first character
char cc = *p++;
auto ic = *p++;
char cc = ic;
if(!(cc & 0b10000000)) {
c = cc;
return;
......@@ -50,12 +59,12 @@ void Iter::parse(void) {
// determine length
if(!(cc & 0b01000000))
throw Exception("utf8: bad encoding");
bad_encoding(ic);
int l = 1;
while(l <= 3 && (cc & (1 << (6 - l))))
l++;
if(l == 4)
throw Exception("utf8: bad encoding");
bad_encoding(ic);
c = cc & (((1 << (6 - l)) - 1));
// read other characers
......@@ -64,7 +73,7 @@ void Iter::parse(void) {
throw Exception("utf8: character sequence too short");
cc = *p++;
if((cc & 0b11000000) != 0b10000000)
throw Exception("utf8: bad encoding");
bad_encoding(ic);
c = (c << 6) | (cc & 0b00111111);
}
}
......
/*
* Test for dtd module.
*
* This file is part of OTAWA
* Copyright (c) 2016, IRIT UPS.
*
* OTAWA 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 2 of the License, or
* (at your option) any later version.
*
* OTAWA 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 OTAWA; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <elm/xom/dtd.h>
#include <elm/test.h>
using namespace elm;
using namespace dtd;
/// test 1
Element name("name", PCDATA);
Element session("session", EMPTY);
Attribute<CDATA> date(session, "date", "", REQUIRED);
Element training("training", (name, *session));
IDAttribute id(training, "id");
Attribute<CDATA> start(training, "start", "");
cstring test1 =
"<?xml version=\"1.0\"?>\n"
"<training id=\"ok\">\n"
"<name>ok</name>\n"
"<session date=\"0\"/>\n"
"<session date=\"1\"/>\n"
"</training>\n";
class MyFactory: public Factory {
public:
void begin(Element& e) override {
//cerr << "DEBUG: <" << e.name() << ">" << io::endl;
if(e == training)
_id = *id;
else if(e == session)
sessions.add(*date);
}
void end(Element& e) override {
//cerr << "DEBUG: </" << e.name() << ">" << io::endl;
}
void getPCDATA(xom::String data) override {
//cerr << "DEBUG: PCDATA = [" << data << "]" << io::endl;
_name = data;
}
string _id;
string _name;
Vector<string> sessions;
};
/// Test 2
class Node {
public:
Node(string i): id(i), ref(nullptr) { }
string id;
Node *ref;
};
Element node("node", EMPTY);
IDAttribute id1(node, "id", REQUIRED);
RefAttribute<Node> ref(node, "ref", FORWARD);
Element all("all", *node);
cstring test2 =
"<?xml version=\"1.0\"?>\n"
"<all>\n"
"<node id=\"0\" ref=\"1\"/>\n"
"<node id=\"1\" ref=\"0\"/>\n"
"</all>\n";
class Factory2: public Factory {
public:
void begin(Element& e) override {
if(e == node) {
nodes.add(new Node(*id1));
if(*ref != nullptr)
nodes.top()->ref = *ref;
}
}
void *getRef(Element& e) override {
//cerr << "DEBUG: getRef(" << e.name() << ")" << io::endl;
if(e == node)
return nodes.top();
else
return nullptr;
}
void *getPatchRef(/*Element& e,*/ AbstractAttribute& a) override {
if(/*e == node &&*/ a == ref)
return &nodes.top()->ref;
else
return nullptr;
}
void patch(AbstractAttribute& a, void *o, void *r) override {
if(a == ref)
*static_cast<Node **>(o) = static_cast<Node *>(r);
}
Vector<Node *> nodes;
};
// Test 3
cstring test3 =
"<?xml version=\"1.0\"?>\n"
"<T3>\n"
"<A num=\"0\"/>\n"
"<A num=\"1\"/>\n"
"<B num=\"2\"/>\n"
"<A num=\"3\"/>\n"
"</T3>\n";
Element A("A", EMPTY);
Attribute<CDATA> A_num(A, "num", "");
Element B("B", EMPTY);
Attribute<CDATA> B_num(B, "num", "");
Element T3("T3", *(A | B));
class Item {
public:
inline Item() { }
inline Item(string n): num(n) { }
string num;
};
class Factory3: public Factory {
public:
void begin(Element& element) {
//cerr << "DEBUG: <" << element.name() << ">" << io::endl;
if(element == A)
As.add(Item(*A_num));
else if(element == B)
Bs.add(Item(*B_num));
}
Vector<Item> As;
Vector<Item> Bs;
};
TEST_BEGIN(dtd)
{
MyFactory factory;
io::BlockInStream in(test1);
training.parse(factory, in);
CHECK_EQUAL(factory._id, string("ok"));
CHECK_EQUAL(factory._name, string("ok"));
CHECK_EQUAL(factory.sessions.length(), 2);
if(factory.sessions.length() >= 1)
CHECK_EQUAL(factory.sessions[0], string("0"));
if(factory.sessions.length() >= 2)
CHECK_EQUAL(factory.sessions[1], string("1"));
}
{
Factory2 f;
io::BlockInStream in(test2);
all.parse(f, in);
CHECK_EQUAL(f.nodes.length(), 2);
if(f.nodes.length() == 2) {
CHECK_EQUAL(f.nodes[0]->id, string("0"));
CHECK_EQUAL(f.nodes[1]->id, string("1"));
CHECK_EQUAL(f.nodes[1]->ref, f.nodes[0]);
CHECK_EQUAL(f.nodes[0]->ref, f.nodes[1]);
}
}
{
Factory3 f;
io::BlockInStream in(test3);
T3.parse(f, in);
CHECK_EQUAL(f.As.length(), 3);
CHECK_EQUAL(f.Bs.length(), 1);
if(f.As.length() == 3) {
CHECK_EQUAL(f.As[0].num, string("0"));
CHECK_EQUAL(f.As[1].num, string("1"));
CHECK_EQUAL(f.As[2].num, string("3"));
}
if(f.Bs.length() == 1)
CHECK_EQUAL(f.Bs[0].num, string("2"));
}
TEST_END
/*
* test_listgc.cpp
*
* Created on: 18 juin 2020
* Author: casse
*/
#include <elm/alloc/ListGC.h>
#include <elm/data/List.h>
#include <elm/sys/System.h>
#include <elm/test.h>
using namespace elm;
class Int {
public:
inline Int(int x): i(x) { }
int i;
};
class Provider: public GCManager {
public:
Provider(): used_err(false), unk_err(false), cnt(0), gc(*this, 16), ending(false) {}
~Provider() {
}
void add(Int *i) {
used.add(i);
//cerr << "DEBUG: add " << i->i << " (" << i << ")" << io::endl;
}
void remove(Int *i) {
used.remove(i);
removed.add(i);
//cerr << "DEBUG: remove " << i->i << " (" << i << ")" << io::endl;
}
void collect(AbstractGC& gc) override {
cnt++;
for(auto p: used)
gc.mark(p, sizeof(Int));
}
void clean(void *p) override {
//cerr << "DEBUG: clean " << reinterpret_cast<Int *>(p)->i << " (" << p << ")" << io::endl;
if(ending)
return;
Int *i = static_cast<Int *>(p);
if(removed.contains(i))
removed.remove(i);
else if(used.contains(i)) {
used_err = true;
//cerr << "DEBUG: still in use!\n";
}
else {
unk_err = true;
//cerr << "DEBUG: don't know this block.\n";
}
}
void run(int ss, bool only_alloc = false) {
for(int i = 0; i < ss; i++) {
auto c = sys::System::random(100);
if(!used || c < 50 || only_alloc)
add(new(gc.alloc<Int>()) Int(i));
else
remove(used[sys::System::random(used.length())]);
if(used_err || unk_err)
return;
}
}
Vector<Int *> used;
Vector<Int *> removed;
bool used_err, unk_err;
int cnt;
ListGC gc;
bool ending;
};
TEST_BEGIN(listgc)
{
Provider prov;
prov.run(10);
CHECK(!prov.used_err);
CHECK(!prov.unk_err);
CHECK(prov.cnt == 0);
}
{
Provider prov;
prov.run(15);
prov.gc.runGC();
CHECK(!prov.used_err);
CHECK(!prov.unk_err);
CHECK(prov.cnt == 1);
CHECK(!prov.removed);
}
{
Provider prov;
prov.run(17, true);
CHECK(!prov.used_err);
CHECK(!prov.unk_err);
CHECK(prov.cnt == 1);
}
{
Provider prov;
prov.run(10000);
CHECK(!prov.used_err);
CHECK(!prov.unk_err);
prov.gc.runGC();
CHECK(!prov.removed);
cerr << "GC: " << prov.cnt << io::endl;
}
TEST_END
/*
* test-preiter.cpp
*
* Created on: 15 juin 2020
* Author: casse
*/
#include <elm/iter.h>
#include <elm/test.h>
using namespace elm;
template <class T>
class MyArray {
public:
MyArray() {
for(int i = 0; i < 10; i++)
t[i] = i;
}
~MyArray() {
}
class BaseIter: public PreIter<BaseIter, T> {
public:
inline BaseIter(const MyArray& array, int idx = 0): a(array), i(idx) { }
inline bool ended() const { return i >= 10; }
inline void next() { i++; }
inline bool equals(const BaseIter& it) const { return i == it.i; }
protected:
const MyArray& a;
int i;
};
class Iter: public BaseIter, public ConstPreIter<Iter, T> {
public:
using BaseIter::BaseIter;
inline const T& item() const { return BaseIter::a.t[BaseIter::i]; }
};
class MutIter: public BaseIter, public MutPreIter<MutIter, T> {
public:
MutIter(MyArray<T>& a, int i = 0): BaseIter(a, i) { }
inline T& item() { return const_cast<MyArray&>(BaseIter::a).t[BaseIter::i]; }
};
inline Iter begin() const { return Iter(*this); }
inline Iter end() const { return Iter(*this, 10); }
inline MutIter begin() { return MutIter(*this); }
inline MutIter end() { return MutIter(*this, 10); }
inline Iter cend() { return Iter(*this, 10); }
private:
T t[10];
};
TEST_BEGIN(preiter)
{
MyArray<int> a;
int s = 0;
for(auto x: a)
s += x;
CHECK_EQUAL(s, 45);
}
{
const MyArray<int> a;
int s = 0;
for(auto x: a)
s += x;
CHECK_EQUAL(s, 45);
}
{
MyArray<int> a;
for(auto& x: a)
x = 0;
int s = 0;
for(auto x: a)
s += x;
CHECK_EQUAL(s, 0);
}
{
MyArray<int> a;
CHECK(a.cend() == a.end());
CHECK(a.end() == a.cend());
}
TEST_END
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment