Imported Upstream version 0.26.0

This commit is contained in:
Bret Curtis 2013-10-17 16:37:22 +02:00
commit 9a2b6c69b6
1398 changed files with 212217 additions and 0 deletions

View file

@ -0,0 +1,82 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.sourceforge.net/
This file (slice_array.h) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
This program 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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#ifndef MISC_SLICE_ARRAY_H
#define MISC_SLICE_ARRAY_H
// A simple array implementation containing a pointer and a
// length. Used for holding slices into a data buffer.
#include <string.h>
#include <string>
namespace Misc
{
template <class T>
struct SliceArray
{
const T* ptr;
size_t length;
/// Initialize to zero length
SliceArray() : ptr(0), length(0) {}
/// Initialize from pointer + length
SliceArray(const T* _ptr, size_t _length)
: ptr(_ptr), length(_length) {}
/// Initialize from null-terminated string
SliceArray(const char* str)
{
ptr = str;
length = strlen(str);
}
bool operator==(SliceArray &t)
{
return
length == t.length &&
(memcmp(ptr,t.ptr, length*sizeof(T)) == 0);
}
/// Only use this for stings
bool operator==(const char* str)
{
return
str[length] == 0 &&
(strncmp(ptr, str, length) == 0);
}
/** This allocates a copy of the data. Only use this for debugging
and error messages. */
std::string toString()
{ return std::string(ptr,length); }
};
typedef SliceArray<char> SString;
typedef SliceArray<int> IntArray;
typedef SliceArray<float> FloatArray;
}
#endif

View file

@ -0,0 +1,70 @@
#include "stringops.hpp"
#include <cctype>
#include <algorithm>
#include <iterator>
#include <string.h>
#include <libs/platform/strings.h>
namespace Misc
{
bool begins(const char* str1, const char* str2)
{
while(*str2)
{
if(*str1 == 0 || *str1 != *str2) return false;
str1++;
str2++;
}
return true;
}
bool ends(const char* str1, const char* str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
if(len1 < len2) return false;
return strcmp(str2, str1+len1-len2) == 0;
}
// True if the given chars match, case insensitive
static bool icmp(char a, char b)
{
if(a >= 'A' && a <= 'Z')
a += 'a' - 'A';
if(b >= 'A' && b <= 'Z')
b += 'a' - 'A';
return a == b;
}
bool ibegins(const char* str1, const char* str2)
{
while(*str2)
{
if(*str1 == 0 || !icmp(*str1,*str2)) return false;
str1++;
str2++;
}
return true;
}
bool iends(const char* str1, const char* str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
if(len1 < len2) return false;
return strcasecmp(str2, str1+len1-len2) == 0;
}
}

View file

@ -0,0 +1,92 @@
#ifndef MISC_STRINGOPS_H
#define MISC_STRINGOPS_H
#include <cctype>
#include <string>
#include <algorithm>
namespace Misc
{
class StringUtils
{
struct ci
{
bool operator()(int x, int y) const {
return std::tolower(x) < std::tolower(y);
}
};
public:
static bool ciLess(const std::string &x, const std::string &y) {
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
}
static bool ciEqual(const std::string &x, const std::string &y) {
if (x.size() != y.size()) {
return false;
}
std::string::const_iterator xit = x.begin();
std::string::const_iterator yit = y.begin();
for (; xit != x.end(); ++xit, ++yit) {
if (std::tolower(*xit) != std::tolower(*yit)) {
return false;
}
}
return true;
}
static int ciCompareLen(const std::string &x, const std::string &y, size_t len)
{
std::string::const_iterator xit = x.begin();
std::string::const_iterator yit = y.begin();
for(;xit != x.end() && yit != y.end() && len > 0;++xit,++yit,--len)
{
int res = *xit - *yit;
if(res != 0 && std::tolower(*xit) != std::tolower(*yit))
return (res > 0) ? 1 : -1;
}
if(len > 0)
{
if(xit != x.end())
return 1;
if(yit != y.end())
return -1;
}
return 0;
}
/// Transforms input string to lower case w/o copy
static std::string &toLower(std::string &inout) {
std::transform(
inout.begin(),
inout.end(),
inout.begin(),
(int (*)(int)) std::tolower
);
return inout;
}
/// Returns lower case copy of input string
static std::string lowerCase(const std::string &in)
{
std::string out = in;
return toLower(out);
}
};
/// Returns true if str1 begins with substring str2
bool begins(const char* str1, const char* str2);
/// Returns true if str1 ends with substring str2
bool ends(const char* str1, const char* str2);
/// Case insensitive, returns true if str1 begins with substring str2
bool ibegins(const char* str1, const char* str2);
/// Case insensitive, returns true if str1 ends with substring str2
bool iends(const char* str1, const char* str2);
}
#endif

View file

@ -0,0 +1,12 @@
GCC=g++
all: strops_test slice_test
slice_test: slice_test.cpp ../slice_array.hpp
$(GCC) $< -o $@
strops_test: strops_test.cpp ../stringops.hpp ../stringops.cpp
$(GCC) $< -o $@ ../stringops.cpp
clean:
rm *_test

View file

@ -0,0 +1,6 @@
hello, len=5
001
hell, len=4
010
01
4 3

View file

@ -0,0 +1,28 @@
#include <iostream>
using namespace std;
#include "../slice_array.hpp"
int main()
{
Misc::SString s, t;
s = Misc::SString("hello");
cout << s.toString() << ", len=" << s.length << endl;
cout << (s=="hel") << (s=="hell") << (s=="hello") << endl;
t = s;
s = Misc::SString("othello"+2, 4);
cout << s.toString() << ", len=" << s.length << endl;
cout << (s=="hel") << (s=="hell") << (s=="hello") << endl;
cout << (s==t) << (Misc::SString("hello")==t) << endl;
const int arr[4] = {1,2,3,4};
Misc::IntArray ia(arr,4);
cout << ia.length << " " << ia.ptr[2] << endl;
return 0;
}

View file

@ -0,0 +1,48 @@
#include <cassert>
#include "../stringops.hpp"
int main()
{
assert(Misc::begins("abc", "a"));
assert(Misc::begins("abc", "ab"));
assert(Misc::begins("abc", "abc"));
assert(Misc::begins("abcd", "abc"));
assert(!Misc::begins("abc", "b"));
assert(!Misc::begins("abc", "bc"));
assert(!Misc::begins("abc", "bcd"));
assert(!Misc::begins("abc", "abcd"));
assert(Misc::ibegins("Abc", "a"));
assert(Misc::ibegins("aBc", "ab"));
assert(Misc::ibegins("abC", "abc"));
assert(Misc::ibegins("abcD", "abc"));
assert(!Misc::ibegins("abc", "b"));
assert(!Misc::ibegins("abc", "bc"));
assert(!Misc::ibegins("abc", "bcd"));
assert(!Misc::ibegins("abc", "abcd"));
assert(Misc::ends("abc", "c"));
assert(Misc::ends("abc", "bc"));
assert(Misc::ends("abc", "abc"));
assert(Misc::ends("abcd", "abcd"));
assert(!Misc::ends("abc", "b"));
assert(!Misc::ends("abc", "ab"));
assert(!Misc::ends("abc", "bcd"));
assert(!Misc::ends("abc", "abcd"));
assert(Misc::iends("Abc", "c"));
assert(Misc::iends("aBc", "bc"));
assert(Misc::iends("abC", "abc"));
assert(Misc::iends("abcD", "abcd"));
assert(!Misc::iends("abc", "b"));
assert(!Misc::iends("abc", "ab"));
assert(!Misc::iends("abc", "bcd"));
assert(!Misc::iends("abc", "abcd"));
return 0;
}

18
components/misc/tests/test.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
make || exit
mkdir -p output
PROGS=*_test
for a in $PROGS; do
if [ -f "output/$a.out" ]; then
echo "Running $a:"
./$a | diff output/$a.out -
else
echo "Creating $a.out"
./$a > "output/$a.out"
git add "output/$a.out"
fi
done

View file

@ -0,0 +1,116 @@
#ifndef MISC_UTF8ITER_HPP
#define MISC_UTF8ITER_HPP
#include <boost/tuple/tuple.hpp>
class Utf8Stream
{
public:
typedef uint32_t UnicodeChar;
typedef unsigned char const * Point;
//static const unicode_char sBadChar = 0xFFFFFFFF; gcc can't handle this
static UnicodeChar sBadChar () { return UnicodeChar (0xFFFFFFFF); }
Utf8Stream (Point begin, Point end) :
cur (begin), nxt (begin), end (end)
{
}
Utf8Stream (std::pair <Point, Point> range) :
cur (range.first), nxt (range.first), end (range.second)
{
}
bool eof () const
{
return cur == end;
}
Point current () const
{
return cur;
}
UnicodeChar peek ()
{
if (cur == nxt)
next ();
return val;
}
UnicodeChar consume ()
{
if (cur == nxt)
next ();
cur = nxt;
return val;
}
static std::pair <UnicodeChar, Point> decode (Point cur, Point end)
{
if ((*cur & 0x80) == 0)
{
UnicodeChar chr = *cur++;
return std::make_pair (chr, cur);
}
int octets;
UnicodeChar chr;
boost::tie (octets, chr) = octet_count (*cur++);
if (octets > 5)
return std::make_pair (sBadChar(), cur);
Point eoc = cur + octets;
if (eoc > end)
return std::make_pair (sBadChar(), cur);
while (cur != eoc)
{
if ((*cur & 0xC0) != 0x80) // check continuation mark
return std::make_pair (sBadChar(), cur);;
chr = (chr << 6) | UnicodeChar ((*cur++) & 0x3F);
}
return std::make_pair (chr, cur);
}
private:
static std::pair <int, UnicodeChar> octet_count (unsigned char octet)
{
int octets;
unsigned char mark = 0xC0;
unsigned char mask = 0xE0;
for (octets = 1; octets <= 5; ++octets)
{
if ((octet & mask) == mark)
break;
mark = (mark >> 1) | 0x80;
mask = (mask >> 1) | 0x80;
}
return std::make_pair (octets, octet & ~mask);
}
void next ()
{
boost::tie (val, nxt) = decode (nxt, end);
}
Point cur;
Point nxt;
Point end;
UnicodeChar val;
};
#endif