Commit 705882c6 authored by Alexander A. Maly's avatar Alexander A. Maly

Restructured kumirstdlib.hpp

parent 84a6923e
Pipeline #1967 failed with stages
in 2 minutes and 35 seconds
......@@ -4,7 +4,9 @@ cmake_minimum_required(VERSION 3.0)
find_package(Kumir2 REQUIRED)
set(SOURCES
kumirstdlib.cpp
kcore.cpp
kfiles.cpp
kmath.cpp
)
kumir2_add_library(
......
#include "kumirstdlib.hpp"
namespace Kumir {
static String kumirError;
static Core::AbortHandlerType abortHandler = 0;
const String &Core::getError()
{
return kumirError;
}
String &Core::takeError()
{
return kumirError;
}
Core::AbortHandlerType Core::getAbortHandler()
{
return abortHandler;
}
void Core::setAbortHandler(Core::AbortHandlerType ah)
{
abortHandler = ah;
}
String Core::fromUtf8(const std::string &s)
{
EncodingError encodingError;
String result = Coder::decode(UTF8, s, encodingError);
return result;
}
String Core::fromAscii(const std::string &s)
{
EncodingError encodingError;
String result = Coder::decode(ASCII, s, encodingError);
return result;
}
std::string Core::toLowerCase(const std::string &s)
{
// !!!! Only for ASCII in onebyte case !!!!!
std::string result;
result.reserve(s.length());
for (size_t i = 0; i < s.length(); i++) {
char ch = s[i];
if (ch >= 'A' && ch <= 'Z') {
ch += 32;
}
result.push_back(ch);
}
return result;
}
std::string Core::toUpperCase(const std::string &s)
{
// !!!! Only for ASCII in onebyte case !!!!!
std::string result;
result.reserve(s.length());
for (size_t i = 0; i < s.length(); i++) {
char ch = s[i];
if (ch >= 'a' && ch <= 'z') {
ch -= 32;
}
result.push_back(ch);
}
return result;
}
std::wstring Core::toLowerCaseW(const std::wstring &s)
{
std::wstring result;
result.reserve(s.length());
for (size_t i = 0; i < s.length(); i++) {
wchar_t ch = s[i];
if (ch >= L'A' && ch <= L'Z') {
ch += 32;
} else if (ch >= 0x0400 && ch <= 0x042F) {
ch += 0x20;
}
result.push_back(ch);
}
return result;
}
std::wstring Core::toUpperCaseW(const std::wstring &s)
{
std::wstring result;
result.reserve(s.length());
for (size_t i = 0; i < s.length(); i++) {
wchar_t ch = s[i];
if (ch >= L'a' && ch <= L'z') {
ch -= 32;
} else if (ch >= 0x0430 && ch <= 0x044F) {
ch -= 0x20;
}
result.push_back(ch);
}
return result;
}
String Core::joinStrings(const std::deque<String> &sl, Char sep)
{
String result;
size_t resultSize = 0, l = sl.size();
if (l == 0)
return result;
for (size_t i = 0; i < l; i++) {
resultSize += sl.at(i).length();
}
resultSize += l - 1;
result.reserve(resultSize);
for (size_t i = 0; i < l; i++) {
result.append(sl.at(i));
if (i < l - 1) {
result.push_back(sep);
}
}
return result;
}
std::deque<String> Core::splitString(
const String &s,
const Char sep,
bool skipEmptyParts
) {
std::deque<String> result;
size_t prev_index;
prev_index = 0;
while (true) {
size_t cur_index = s.find(sep, prev_index);
if (cur_index == s.npos) {
cur_index = s.length();
}
size_t length = cur_index - prev_index;
if (length == 0 && !skipEmptyParts) {
result.push_back(String());
} else if (length > 0) {
result.push_back(s.substr(prev_index, length));
}
prev_index = cur_index + 1;
if (prev_index >= s.length()) {
break;
}
}
return result;
}
Encoding Core::getSystemEncoding()
{
#if defined(WIN32) || defined(_WIN32)
return CP1251;
#elif defined(DOS)
return CP866;
#else
char *lc = 0;
lc = getenv("LC_CTYPE");
if (!lc) {
lc = getenv("LC_ALL");
}
if (!lc) {
return UTF8;
}
std::deque<String> parts = splitString(
fromAscii(std::string(lc)),
Char('.'),
true
);
if (parts.size() == 0) {
return UTF8;
}
EncodingError encodingError;
std::string last = Coder::encode(
ASCII,
parts.at(parts.size() - 1),
encodingError
);
if (last == std::string("KOI8-R")) {
return KOI8R;
} else if (last == std::string("CP866") ||
last == std::string("IBM866") ||
last == std::string("CP-866") ||
last == std::string("IBM-866")) {
return CP866;
} else if (last == std::string("CP1251") ||
last == std::string("WINDOWS1251") ||
last == std::string("CP-1251") ||
last == std::string("WINDOWS-1251")) {
return CP1251;
} else {
return UTF8;
}
#endif
}
void Core::abort(const String &e)
{
kumirError = e;
if (abortHandler) {
abortHandler();
}
}
} // namespace Kumir
This diff is collapsed.
#include "kumirstdlib.hpp"
#include <time.h>
#if !defined(APPLE) && !defined(USE_MINGW_TOOLCHAIN)
#include <random>
#endif
#include <math.h>
#include <float.h>
namespace Kumir
{
void Random::init()
{
#if !defined(WIN32)
unsigned int seed = 0xDEADBEEF;
FILE *urandom = fopen("/dev/urandom", "rb");
fread(&seed, 1, sizeof(unsigned), urandom);
fclose(urandom);
srand(seed);
#elif defined(USE_MINGW_TOOLCHAIN)
srand(time(NULL));
#endif
}
inline unsigned int Random::get_max()
{
#if !defined(WIN32) || defined(USE_MINGW_TOOLCHAIN)
return RAND_MAX;
#else
return std::random_device::max() - std::random_device::min();
#endif
}
unsigned int Random::get_sample()
{
#if !defined(WIN32) || defined(USE_MINGW_TOOLCHAIN)
return rand();
#else
std::random_device rd;
return rd() - rd::min();
#endif
}
int Random::irand(int a, int b)
{
if (a >= b) {
if (a > b) {
Core::abort(Core::fromUtf8("Неверный диапазон чисел"));
return 0;
}
return a;
}
unsigned int d = b - a + 1;
unsigned int rd = get_max(), rq = rd / d + (rd % d + 1) / d;
assert (0 < rq);
for (;;) {
unsigned int v = get_sample(), res = v / rq;
if (res < d) {
return a + res;
}
}
}
int Random::irnd(int x)
{
return irand(1, x);
}
real Random::rrand(real a, real b)
{
if (!(a < b)) {
if (!(a <= b)) {
Core::abort(Core::fromUtf8("Неверный диапазон чисел"));
return 0.0;
}
return a;
}
real d = b - a;
if (!isfinite(d)) {
Core::abort(Core::fromUtf8("Слишком широкий диапазон чисел"));
return 0.0;
}
real rd = get_max() + 1.0;
unsigned int v = get_sample();
real res = v / rd * d;
if (v < res) {
res = v;
}
return res;
}
real Random::rrnd(real x)
{
return rrand(0, x);
}
int System::time()
{
int hours = 0, mins = 0, secs = 0, msecs = 0;
#if defined(WIN32) || defined(_WIN32)
SYSTEMTIME st;
memset(&st, 0, sizeof(SYSTEMTIME));
GetSystemTime(&st);
hours = st.wHour;
mins = st.wMinute;
secs = st.wSecond;
msecs = st.wMilliseconds;
#else
struct timeval tv;
gettimeofday(&tv, 0);
tzset();
struct tm dummy;
time_t epoch = ::time(NULL);
struct tm *loc = localtime_r(&epoch, &dummy);
hours = loc->tm_hour;
mins = loc->tm_min;
secs = loc->tm_sec;
msecs = tv.tv_usec / 1000;
#endif
int result = ((hours * 60 + mins) * 60 + secs) * 1000 + msecs;
return result % 86400000;
}
}
#include "kumirstdlib.hpp"
namespace Kumir
{
String Core::error = String();
void (*Core::AbortHandler)() = 0;
std::deque<FileType> Files::openedFiles;
AbstractInputBuffer *Files::consoleInputBuffer = 0;
AbstractOutputBuffer *Files::consoleOutputBuffer = 0;
AbstractOutputBuffer *Files::consoleErrorBuffer = 0;
FILE *Files::assignedIN = stdin;
FILE *Files::assignedOUT = stdout;
#if defined(WIN32) || defined(_WIN32)
Encoding IO::LOCALE_ENCODING = CP866;
#else
Encoding IO::LOCALE_ENCODING = UTF8;
#endif
Encoding Files::fileEncoding;
String Kumir::IO::inputDelimeters = Kumir::Core::fromAscii(" \n\t");
} // namespace Kumir
This diff is collapsed.
......@@ -965,7 +965,7 @@ void OneSession::tryFinishInput()
}
}
if (actor) {
stream.skipDelimiters(Kumir::IO::inputDelimeters);
stream.skipDelimiters(Kumir::String());
conversionErrorStart = stream.currentPosition();
QString lexem = QString::fromStdWString(Kumir::IO::readString(stream));
QVariant value;
......
......@@ -19,7 +19,11 @@ extern "C" {
using namespace Kumir;
static Encoding LOCALE;
#if defined(WIN32) || defined(_WIN32)
static Encoding LOCALE = CP866;
#else
static Encoding LOCALE = UTF8;
#endif
static void do_output(const String &s)
{
......@@ -176,11 +180,7 @@ int main(int argc, char *argv[])
Kumir::EncodingError encodingError;
// sleep(15); // for remote debugger
// Look at arguments
#if defined(WIN32) || defined(_WIN32)
IO::LOCALE_ENCODING = LOCALE = CP866;
#else
IO::LOCALE_ENCODING = LOCALE = UTF8;
#endif
IO::setLocaleEncoding(LOCALE);
std::string programName;
std::deque<std::string> args;
bool testingMode = false;
......@@ -202,7 +202,8 @@ int main(int argc, char *argv[])
quietMode = true;
}
else if (arg==minus_ansi) {
IO::LOCALE_ENCODING = LOCALE = CP1251;
LOCALE = CP1251;
IO::setLocaleEncoding(LOCALE);
}
else {
programName = arg;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment