mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-31 17:23:03 +01:00
652 lines
12 KiB
C++
652 lines
12 KiB
C++
char lbl[] = "0123456789";
|
|
|
|
//#define CHECK_FATAL_RANGE_EXCEPTION
|
|
//Don't modify 3 lines upper from this - they are used in file read test
|
|
//If you plan to check range exception, you may uncomment it -
|
|
//anyway file test should not happen
|
|
|
|
/*
|
|
* PROGRAM: Class library integrity tests
|
|
* MODULE: string_test.cpp
|
|
* DESCRIPTION: test class Firebird::string
|
|
*
|
|
* The contents of this file are subject to the Initial
|
|
* Developer's Public License Version 1.0 (the "License");
|
|
* you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
|
*
|
|
* Software distributed under the License is distributed AS IS,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing rights
|
|
* and limitations under the License.
|
|
*
|
|
* The Original Code was created by Alexander Peshkoff
|
|
* for the Firebird Open Source RDBMS project.
|
|
*
|
|
* Copyright (c) 2004 Alexander Peshkoff <peshkoff@mail.ru>
|
|
* and all contributors signed below.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
*/
|
|
|
|
#if defined(FIRESTR) && defined(DEV_BUILD)
|
|
#define FULL_FIRE
|
|
#endif
|
|
|
|
#ifdef FIRESTR
|
|
#define NAME "Firebird::string"
|
|
#include "../common/classes/fb_string.h"
|
|
|
|
using namespace Firebird;
|
|
#else
|
|
#define NAME "std::basic_string"
|
|
#include <string>
|
|
typedef std::basic_string<char> string;
|
|
typedef string AbstractString;
|
|
#endif
|
|
|
|
#include <time.h>
|
|
|
|
#ifdef DEV_BUILD
|
|
void CheckStr(const AbstractString& check, const char* want, int line) {
|
|
if (strlen(check.c_str()) != check.length()) {
|
|
printf("Length error at %d\n\n", line);
|
|
}
|
|
if (strcmp(check.c_str(), want)) {
|
|
printf("Wanted >%s<,\n got >%s< at %d\n\n", want, check.c_str(), line);
|
|
}
|
|
}
|
|
#define validate(a, b) CheckStr(a, b, __LINE__)
|
|
#else
|
|
#define validate(a, b)
|
|
#define check(a, b)
|
|
#endif
|
|
|
|
void test(void) {
|
|
{
|
|
string a;
|
|
validate(a, "");
|
|
a = lbl;
|
|
string b = a;
|
|
validate(b, lbl);
|
|
string f = "0123456789";
|
|
validate(f, lbl);
|
|
string g("0123456789", 5);
|
|
validate(g, "01234");
|
|
string h(5, '7');
|
|
validate(h, "77777");
|
|
#ifdef FULL_FIRE
|
|
string i('7');
|
|
validate(i, "7");
|
|
#endif
|
|
string j(&lbl[3], &lbl[5]);
|
|
validate(j, "34");
|
|
}
|
|
{
|
|
string a = lbl;
|
|
string b;
|
|
b = a;
|
|
validate(b, lbl);
|
|
b = lbl;
|
|
validate(b, lbl);
|
|
a = 'X';
|
|
validate(a, "X");
|
|
|
|
a = b;
|
|
for (string::iterator x = b.begin(); x < b.end(); x++)
|
|
*x = 'u';
|
|
validate(a, lbl);
|
|
validate(b, "uuuuuuuuuu");
|
|
|
|
char y[20], *z = y;
|
|
const string c = a;
|
|
for (string::const_iterator x1 = c.begin(); x1 < c.end(); x1++)
|
|
*z++ = *x1;
|
|
*z = 0;
|
|
b = y;
|
|
validate(b, lbl);
|
|
}
|
|
#ifdef FULL_FIRE
|
|
{
|
|
const string a = lbl;
|
|
string b = a.at(5);
|
|
validate(b, "5");
|
|
}
|
|
{
|
|
string a = lbl;
|
|
string b = a.at(5);
|
|
validate(b, "5");
|
|
}
|
|
#endif
|
|
// conflict with J. requirement to string class - operator const char* {
|
|
// string a = lbl;
|
|
// char c = a[5];
|
|
// a[5] = 'u';
|
|
// validate(a, "01234u6789");
|
|
//}
|
|
{
|
|
string a = lbl;
|
|
char c = a[5]; // via operator const char*
|
|
a.at(5) = 'u';
|
|
a.at(7) = c;
|
|
validate(a, "01234u6589");
|
|
}
|
|
#ifdef CHECK_FATAL_RANGE_EXCEPTION
|
|
{
|
|
const string a = lbl;
|
|
string b = a.at(15);
|
|
}
|
|
#endif
|
|
{
|
|
string a = lbl;
|
|
a.resize(15, 'u');
|
|
validate(a, "0123456789uuuuu");
|
|
}
|
|
{
|
|
string a;
|
|
string x = lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl; //120 bytes
|
|
a = x;
|
|
validate(a, x.c_str());
|
|
|
|
x = lbl;
|
|
x += lbl;
|
|
x += lbl;
|
|
x += lbl; //40 bytes
|
|
a = x;
|
|
validate(a, x.c_str());
|
|
}
|
|
{
|
|
string a = lbl;
|
|
const string b = a;
|
|
a += b;
|
|
validate(a, "01234567890123456789");
|
|
|
|
a = lbl;
|
|
a += lbl;
|
|
validate(a, "01234567890123456789");
|
|
|
|
a = lbl;
|
|
a += 'u';
|
|
validate(a, "0123456789u");
|
|
}
|
|
{
|
|
string a, b, c;
|
|
|
|
a = "uuu";
|
|
b = lbl;
|
|
c = a + b;
|
|
validate(c, "uuu0123456789");
|
|
|
|
c = a + lbl;
|
|
validate(c, "uuu0123456789");
|
|
|
|
c = b + 'u';
|
|
validate(c, "0123456789u");
|
|
|
|
c = lbl + a;
|
|
validate(c, "0123456789uuu");
|
|
|
|
c = 'u' + b;
|
|
validate(c, "u0123456789");
|
|
|
|
validate(a, "uuu");
|
|
validate(b, lbl);
|
|
}
|
|
{
|
|
string a = lbl;
|
|
const string b = a;
|
|
a.append(b);
|
|
validate(a, "01234567890123456789");
|
|
|
|
a = lbl;
|
|
a.append(lbl);
|
|
validate(a, "01234567890123456789");
|
|
|
|
a = lbl;
|
|
a.append(lbl, 6);
|
|
validate(a, "0123456789012345");
|
|
|
|
a = lbl;
|
|
a.append(b, 3, 2);
|
|
validate(a, "012345678934");
|
|
|
|
a = lbl;
|
|
a.append(b, 3, 20);
|
|
validate(a, "01234567893456789");
|
|
|
|
a = lbl;
|
|
a.append(3, 'u');
|
|
validate(a, "0123456789uuu");
|
|
|
|
a = lbl;
|
|
a.append(b.begin(), b.end());
|
|
validate(a, "01234567890123456789");
|
|
|
|
a = lbl;
|
|
a.append("Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
validate(a, "0123456789Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
a = lbl;
|
|
validate(a, lbl);
|
|
|
|
string c = lbl;
|
|
c += lbl;
|
|
c += lbl;
|
|
c += lbl;
|
|
a = lbl;
|
|
a.append("Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
validate(a, "0123456789Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
a = c;
|
|
validate(a, c.c_str());
|
|
}
|
|
{
|
|
string a, b;
|
|
b = lbl;
|
|
|
|
a.assign(3, 'u');
|
|
validate(a, "uuu");
|
|
|
|
a.assign(lbl);
|
|
validate(a, lbl);
|
|
|
|
a.assign(lbl, 2);
|
|
validate(a, "01");
|
|
|
|
a.assign(b, 3, 3);
|
|
validate(a, "345");
|
|
|
|
a.assign(b);
|
|
validate(a, lbl);
|
|
|
|
a = "";
|
|
validate(a, "");
|
|
string::iterator x = b.begin();
|
|
string::iterator y = b.end();
|
|
a.assign(x, y);
|
|
validate(a, lbl);
|
|
}
|
|
{
|
|
string a, b = lbl;
|
|
|
|
a = lbl;
|
|
a.insert(5, 3, 'u');
|
|
validate(a, "01234uuu56789");
|
|
|
|
a = lbl;
|
|
a.insert(3, lbl);
|
|
validate(a, "01201234567893456789");
|
|
|
|
a = lbl;
|
|
a.insert(4, lbl, 2);
|
|
validate(a, "012301456789");
|
|
|
|
a = lbl;
|
|
a.insert(5, b, 3, 3);
|
|
validate(a, "0123434556789");
|
|
|
|
a = lbl;
|
|
a.insert(5, b);
|
|
validate(a, "01234012345678956789");
|
|
|
|
a = lbl;
|
|
a.insert(2, "Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
validate(a, "01Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long23456789");
|
|
|
|
a = lbl;
|
|
string::iterator x = a.begin();
|
|
x++;
|
|
a.insert(x, 5, 'u');
|
|
validate(a, "0uuuuu123456789");
|
|
|
|
a = lbl;
|
|
x = a.begin();
|
|
x += 2;
|
|
string::iterator f = b.begin();
|
|
string::iterator t = b.end();
|
|
f++; t--;
|
|
a.insert(x, f, t);
|
|
validate(a, "011234567823456789");
|
|
|
|
a = lbl;
|
|
a.erase();
|
|
validate(a, "");
|
|
|
|
a = lbl;
|
|
a.erase(3, 6);
|
|
validate(a, "0129");
|
|
|
|
a = lbl;
|
|
a.erase(3, 16);
|
|
validate(a, "012");
|
|
|
|
a = lbl;
|
|
a.erase(3);
|
|
validate(a, "012");
|
|
|
|
a = lbl;
|
|
x = a.begin();
|
|
x += 3;
|
|
a.erase(x);
|
|
validate(a, "012456789");
|
|
|
|
a = lbl;
|
|
x = a.begin();
|
|
x += 3;
|
|
string::iterator y = a.end();
|
|
y -= 2;
|
|
a.erase(x, y);
|
|
validate(a, "01289");
|
|
}
|
|
{
|
|
string a;
|
|
const string b = lbl;
|
|
string::iterator f0, t0;
|
|
string::const_iterator f, t;
|
|
|
|
a = lbl;
|
|
a.replace(5, 2, 3, 'u');
|
|
validate(a, "01234uuu789");
|
|
|
|
a = lbl;
|
|
f0 = a.begin() + 5;
|
|
t0 = f0 + 2;
|
|
a.replace(f0, t0, 3, 'u');
|
|
validate(a, "01234uuu789");
|
|
|
|
a = lbl;
|
|
a.replace(3, 3, lbl);
|
|
validate(a, "01201234567896789");
|
|
|
|
a = lbl;
|
|
f0 = a.begin() + 3;
|
|
t0 = f0 + 3;
|
|
a.replace(f0, t0, lbl);
|
|
validate(a, "01201234567896789");
|
|
|
|
a = lbl;
|
|
a.replace(4, 4, lbl, 2);
|
|
validate(a, "01230189");
|
|
|
|
a = lbl;
|
|
f0 = a.begin() + 4;
|
|
t0 = f0 + 4;
|
|
a.replace(f0, t0, lbl, 2);
|
|
validate(a, "01230189");
|
|
|
|
a = lbl;
|
|
a.replace(5, 10, b, 3, 3);
|
|
validate(a, "01234345");
|
|
|
|
a = lbl;
|
|
f0 = a.begin() + 5;
|
|
t0 = f0 + 10;
|
|
f = b.begin() + 3;
|
|
t = f + 3;
|
|
a.replace(f0, t0, f, t);
|
|
validate(a, "01234345");
|
|
|
|
a = lbl;
|
|
a.replace(5, 0, b);
|
|
validate(a, "01234012345678956789");
|
|
|
|
a = lbl;
|
|
f0 = a.begin() + 5;
|
|
t0 = f0;
|
|
a.replace(f0, t0, b);
|
|
validate(a, "01234012345678956789");
|
|
|
|
a = lbl;
|
|
a.replace(2, 1, "Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long");
|
|
validate(a, "01Something reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally long3456789");
|
|
}
|
|
{
|
|
string a, b = lbl;
|
|
char s[40];
|
|
memset(s, 0, 40);
|
|
|
|
#ifdef FULL_FIRE
|
|
b.copyTo(s, 5);
|
|
a = s;
|
|
validate(a, "0123");
|
|
|
|
b.copyTo(s, 40);
|
|
a = s;
|
|
validate(a, lbl);
|
|
#endif
|
|
|
|
// a.swap(b);
|
|
// validate(b, "3456789");
|
|
// validate(a, lbl);
|
|
}
|
|
|
|
#ifdef DEV_BUILD
|
|
#undef check
|
|
#define check(a, b) if (a != b) printf("Wanted %d got %d at %d\n\n",\
|
|
b, a, __LINE__)
|
|
#endif
|
|
|
|
{
|
|
string a = "012345uuu345678";
|
|
// 9
|
|
string b = "345";
|
|
|
|
check(a.find(b), 3);
|
|
check(a.find("45"), 4);
|
|
check(a.find('5'), 5);
|
|
check(a.find("ZZ"), string::npos);
|
|
|
|
check(a.rfind(b), 9);
|
|
check(a.rfind("45"), 10);
|
|
check(a.rfind('5'), 11);
|
|
check(a.rfind("ZZ"), string::npos);
|
|
|
|
check(a.find("45", 8), 10);
|
|
|
|
check(a.find_first_of("aub"), 6);
|
|
check(a.find_first_of(b), 3);
|
|
check(a.find_first_of("54"), 4);
|
|
check(a.find_first_of('5'), 5);
|
|
check(a.find_first_of("ZZ"), string::npos);
|
|
|
|
check(a.find_last_of("aub"), 8);
|
|
check(a.find_last_of(b), 11);
|
|
check(a.find_last_of("54"), 11);
|
|
check(a.find_last_of('5'), 11);
|
|
check(a.find_last_of("ZZ"), string::npos);
|
|
|
|
check(a.find_first_of("45", 8), 10);
|
|
|
|
b = "010";
|
|
check(a.find_first_not_of("aub"), 0);
|
|
check(a.find_first_not_of(b), 2);
|
|
check(a.find_first_not_of("0102"), 3);
|
|
check(a.find_first_not_of('0'), 1);
|
|
check(a.find_first_not_of(a), string::npos);
|
|
|
|
b = "878";
|
|
check(a.find_last_not_of("aub"), 14);
|
|
check(a.find_last_not_of(b), 12);
|
|
check(a.find_last_not_of("78"), 12);
|
|
check(a.find_last_not_of('8'), 13);
|
|
check(a.find_last_not_of(a), string::npos);
|
|
|
|
check(a.find_first_not_of("u345", 8), 12);
|
|
}
|
|
{
|
|
string a = lbl;
|
|
string b;
|
|
|
|
b = a.substr(3, 4);
|
|
validate(b, "3456");
|
|
|
|
b = a.substr(5, 20);
|
|
validate(b, "56789");
|
|
#ifdef FULL_FIRE
|
|
b = a.substr(50, 20);
|
|
validate(b, "");
|
|
|
|
#endif
|
|
}
|
|
#ifdef FULL_FIRE
|
|
{
|
|
string b;
|
|
FILE *x = fopen("string_test.cpp", "rt");
|
|
b.LoadFromFile(x);
|
|
validate(b, "char lbl[] = \"0123456789\";");
|
|
b.LoadFromFile(x);
|
|
validate(b, "");
|
|
b.LoadFromFile(x);
|
|
validate(b, "//#define CHECK_FATAL_RANGE_EXCEPTION");
|
|
fclose(x);
|
|
}
|
|
#endif
|
|
{
|
|
string a = "Something moderaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaately long";
|
|
string a1 = a;
|
|
string b = a + a1;
|
|
string b1 = b;
|
|
string c = b + b1;
|
|
string d = c;
|
|
string e = c;
|
|
string f = c;
|
|
string g = c;
|
|
string h = c;
|
|
string i = c;
|
|
string j = c;
|
|
string k = c;
|
|
string l = c;
|
|
string m = c;
|
|
string n = c;
|
|
string o = c;
|
|
string p = c;
|
|
}
|
|
|
|
#ifdef DEV_BUILD
|
|
#undef check
|
|
#define check(get, want) if ( (get < 0 ? -1 : get > 0 ? 1 : 0) != want)\
|
|
printf("Wanted %d got %d at %d\n\n", want, get, __LINE__)
|
|
#endif
|
|
|
|
#ifdef FULL_FIRE
|
|
{
|
|
PathName c = "Aa";
|
|
PathName d = "AB";
|
|
|
|
check(c.compare(d), -1);
|
|
}
|
|
#endif
|
|
|
|
{
|
|
string a = lbl;
|
|
string b = a;
|
|
string c = "Aaa";
|
|
string d = "AB";
|
|
string e = "Aa";
|
|
|
|
check(a.compare(b), 0);
|
|
check(a.compare(c), -1);
|
|
check(c.compare(a), 1);
|
|
|
|
check(c.compare(d), 1);
|
|
check(c.compare(e), 1);
|
|
|
|
check(a.compare(1, 10, b), 1);
|
|
check(a.compare(1, 10, b, 1, 10), 0);
|
|
check(a.compare(lbl), 0);
|
|
check(a.compare(1, 3, lbl + 1, 3), 0);
|
|
}
|
|
#ifdef FULL_FIRE
|
|
{
|
|
string a = " 011100 ", b;
|
|
|
|
b = a;
|
|
b.ltrim();
|
|
validate(b, "011100 ");
|
|
|
|
b = a;
|
|
b.rtrim();
|
|
validate(b, " 011100");
|
|
|
|
b = a;
|
|
b.trim(" 0");
|
|
validate(b, "111");
|
|
|
|
b = a;
|
|
b.alltrim("02 ");
|
|
validate(b, "111");
|
|
|
|
b = a;
|
|
b.trim("012");
|
|
validate(b, " 011100 ");
|
|
|
|
validate(a, " 011100 ");
|
|
}
|
|
{
|
|
string a = lbl;
|
|
a += '\377';
|
|
string b = a;
|
|
a += " ";
|
|
a.rtrim();
|
|
validate(a, b.c_str());
|
|
}
|
|
{
|
|
string a = "AaBbCc", b;
|
|
|
|
b = a;
|
|
b.lower();
|
|
validate(b, "aabbcc");
|
|
|
|
b = a;
|
|
b.upper();
|
|
validate(b, "AABBCC");
|
|
|
|
validate(a, "AaBbCc");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
clock_t t;
|
|
|
|
void start() {
|
|
t = clock();
|
|
}
|
|
|
|
#ifdef DEV_BUILD
|
|
#define TEST_ITEMS 1
|
|
#else
|
|
#define TEST_ITEMS 100000
|
|
#endif
|
|
|
|
void report() {
|
|
clock_t d = clock();
|
|
printf("Test of %d iterations with %s took %d milliseconds.\n",
|
|
TEST_ITEMS, NAME, (int)(d-t)*1000/CLOCKS_PER_SEC);
|
|
}
|
|
|
|
int main(int ac, char **av) {
|
|
int n = TEST_ITEMS;
|
|
start();
|
|
while (n--) {
|
|
test();
|
|
}
|
|
report();
|
|
#if defined(DEV_BUILD) && defined(FIRESTR)
|
|
getDefaultMemoryPool()->print_contents(stdout, false);
|
|
#endif
|
|
printf("Press enter to continue\n");
|
|
getchar();
|
|
return 0;
|
|
}
|