git-svn-id: svn://ultimatepp.org/upp/trunk@332 f0d560ea-af0d-0410-9eb7-867de7ffcac7

This commit is contained in:
cxl 2008-08-15 10:11:34 +00:00
parent 6842990fa9
commit 2667dfc1d5
385 changed files with 188873 additions and 2 deletions

View file

@ -0,0 +1,110 @@
#include <CppBase/CppBase.h>
using namespace Upp;
#define NCOUNT 50
#define MAX_THREADS 100
String text[MAX_THREADS];
void Work(int i = 0)
{
CppBase base;
MemReadStream in(text[i], text[i].GetLength());
Parse(in, Vector<String>(), base, "", Callback2<int, const String&>());
}
void ThreadWork(int ii)
{
for(int i = 0; i < NCOUNT; i++)
Work(ii);
}
void ChrisTest();
void sLarge(String& text, int *large, int count, const char *txt)
{
int n = min(1024, count);
Sort(large, large + n, StdLess<int>());
int i = 0;
while(i < n) {
int q = large[i];
int nn = i++;
while(i < n && large[i] == q) i++;
nn = i - nn;
if(q < 10000)
text << Format("%4d B, %5d %s (%6d KB)\r\n", q, nn, txt, (nn * q) >> 10);
else
text << Format("%4d`KB, %5d %s (%6d KB)\r\n", q >> 10, nn, txt, (nn * q) >> 10);
}
}
String sProfile(MemoryProfile& mem)
{
String text;
int acount = 0;
size_t asize = 0;
int fcount = 0;
size_t fsize = 0;
for(int i = 0; i < 1024; i++)
if(mem.allocated[i]) {
int sz = 4 * i;
text << Format("%4d B, %6d allocated (%5d KB), %6d fragmented (%5d KB)\n",
sz, mem.allocated[i], (mem.allocated[i] * sz) >> 10,
mem.fragmented[i], (mem.fragmented[i] * sz) >> 10);
acount += mem.allocated[i];
asize += mem.allocated[i] * sz;
fcount += mem.fragmented[i];
fsize += mem.fragmented[i] * sz;
}
text << Format(" TOTAL, %6d allocated (%5d KB), %6d fragmented (%5d KB)\n",
acount, int(asize >> 10), fcount, int(fsize >> 10));
text << "Free pages " << mem.freepages << " (" << mem.freepages * 4 << " KB)\n";
text << "Large block count " << mem.large_count
<< ", total size " << (mem.large_total >> 10) << " KB\n";
sLarge(text, mem.large_size, mem.large_count, "allocated");
text << "Large fragments count " << mem.large_free_count
<< ", total size " << (mem.large_free_total >> 10) << " KB\n";
sLarge(text, mem.large_free_size, mem.large_free_count, "fragments");
return text;
}
CONSOLE_APP_MAIN
{
// PeakMemoryProfile();
#if 0
ChrisTest();
#else
StdLogSetup(LOG_FILE|LOG_COUT);
String fn = GetDataFile("x.cpp");
fn = AppendFileName(GetFileFolder(GetFileFolder(GetFileFolder(fn))),
"uppsrc/CtrlLib/ArrayCtrl.cpp");
String file = LoadFile(fn);
for(int i = 0; i < MAX_THREADS; i++)
text[i] = file;
#ifdef _MULTITHREADED
Thread x[MAX_THREADS];
for(int n = 64; n < MAX_THREADS; n = 2 * n) {
TimeStop tm;
for(int i = 0; i < n; i++)
x[i].Run(callback1(ThreadWork, i));
for(int i = 0; i < n; i++)
x[i].Wait();
RLOG(n << " thread(s) " << tm.Elapsed() << " ms");
}
TimeStop tm;
{
CoWork co;
for(int i = 0; i < 10000; i++)
co & callback1(Work, 0);
}
RLOG("CoWork (1000 runs): " << tm.Elapsed() << " ms");
#else
TimeStop tm;
for(int i = 0; i < 1000; i++)
Work();
RLOG("Single thread: " << tm.Elapsed() << " ms");
#endif
#endif
// RLOG(sProfile(*PeakMemoryProfile()));
}

View file

@ -0,0 +1,23 @@
optimize_speed;
uses
Core,
CppBase;
library(asdf) "pthreadVCE2.lib pthreadVCE2.lib";
file
Chris.cpp,
Chris2.cpp,
AllocMT.cpp,
result.txt;
mainconfig
"" = "MT",
"" = "",
"" = "USEMALLOC MT",
"" = "USEMALLOC",
"" = "USEMALLOC CHRIS MT",
"" = "USEMALLOC CHRIS",
"" = "MT PROFILEMT";

View file

@ -0,0 +1,938 @@
#if 0
#define NDEBUG
/*
Virtually Zero-Overhead Memory Allocator
Copyright (C) 2008 Christopher Michael Thomasson
This program 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.
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
along with this program. If not, see <http://www.gnu.org/licenses/>.
_______________________________________________________________________
// *** Version 0.0.0 (Pre-Alpha ***
_______________________________________________________________________*/
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <cstdio>
#include <exception>
#include <new>
#include <pthread.h>
#include <Core/Core.h>
#if defined(_MSC_VER)
# pragma warning (disable : 4290)
#endif
/* Global Settings
_____________________________________________________________*/
#ifdef flagCHRIS
#define THREAD_MALLOC_OVERLOAD_NEW_DELETE
#endif
#if ! defined(THREAD_ALLOCATOR_HEAP_SIZE)
# define THREAD_ALLOCATOR_HEAP_SIZE 262144
#endif
#if ! defined(THREAD_ALLOCATOR_DTOR_MARK)
# define THREAD_ALLOCATOR_DTOR_MARK 0x80000000
#endif
#if ! defined(THREAD_ALLOCATOR_PRIME_COUNT)
# define THREAD_ALLOCATOR_PRIME_COUNT 1
#endif
#if ! defined(THREAD_ALLOCATOR_MAX_COUNT)
# define THREAD_ALLOCATOR_MAX_COUNT 2
#endif
/* Helper Macros
_____________________________________________________________*/
#if ! defined(NDEBUG)
# include <cstdio>
# define DBG_PRINTF(mp_exp) std::printf mp_exp
#else
# define DBG_PRINTF(mp_exp)
#endif
#define ALIGN_SIZE(mp_this, mp_type, mp_align) ((mp_type) \
(((std::ptrdiff_t const)((mp_this))) + \
((std::ptrdiff_t const)((mp_align)) - 1) & \
(-((std::ptrdiff_t const)((mp_align))))) \
)
#define IS_ALIGNED(mp_this, mp_align) ( \
! (((std::ptrdiff_t const)((mp_this))) % \
((std::ptrdiff_t const)((mp_align)))) \
)
/* Quick and Dirty i686 Atomic Operations
_____________________________________________________________*/
typedef int atomic_word_i686;
typedef char static_assert_i686 [
(sizeof(atomic_word_i686) == 4) ? 1 : -1
];
__declspec(naked)
atomic_word_i686
atomic_i686_xadd(
atomic_word_i686 volatile* const _this,
atomic_word_i686 const addend
) {
_asm {
MOV ECX, [ESP + 4]
MOV EAX, [ESP + 8]
LOCK XADD [ECX], EAX
RET
}
}
__declspec(naked)
atomic_word_i686
atomic_i686_xchg(
atomic_word_i686 volatile* const _this,
atomic_word_i686 const value
) {
_asm {
MOV ECX, [ESP + 4]
MOV EAX, [ESP + 8]
XCHG [ECX], EAX
RET
}
}
typedef atomic_word_i686 atomic_word;
#define atomic_xadd atomic_i686_xadd
#define atomic_xchg atomic_i686_xchg
/* General Purpose Intrusive Double Linked-List
_____________________________________________________________*/
template<typename T>
static T dlist_init(T _this) throw() {
_this->m_head = _this->m_tail = NULL;
return _this;
}
template<typename T>
static T dlnode_init(T _this) throw() {
_this->m_next = _this->m_prev = NULL;
return _this;
}
template<typename T, typename N>
static N dlist_pop(T _this, N node) throw() {
N const next = node->m_next;
N const prev = node->m_prev;
if (! next && ! prev) {
_this->m_head = 0;
_this->m_tail = 0;
} else if (next && ! prev) {
next->m_prev = 0;
_this->m_head = next;
} else if (! next && prev) {
prev->m_next = 0;
_this->m_tail = prev;
} else {
next->m_prev = prev;
prev->m_next = next;
}
return node;
}
template<typename T, typename N>
static N dlist_push_head(T _this, N node) throw() {
node->m_prev = 0;
if (! _this->m_head) {
_this->m_tail = node;
node->m_next = NULL;
} else {
node->m_next = _this->m_head;
_this->m_head->m_prev = node;
}
_this->m_head = node;
return node;
}
/* General Purpose Thread-Safe Allocator
_____________________________________________________________*/
#if ! defined(NDEBUG)
static atomic_word g_dbg_thread_malloc_count = 0;
#define dbg_thread_get_count() (g_dbg_thread_malloc_count)
#define dbg_thread_adjust_count(mp_value) \
atomic_xadd(&g_dbg_thread_malloc_count, (mp_value))
#else
#define dbg_thread_get_count() (0)
#define dbg_thread_adjust_count(mp_value) (0)
#endif
extern "C" void* thread_malloc(std::size_t const);
extern "C" void thread_free(void const* const);
template<
std::size_t T_heap_size = THREAD_ALLOCATOR_HEAP_SIZE,
atomic_word T_dtor_mark = THREAD_ALLOCATOR_DTOR_MARK
> struct thread_allocator {
union aligner {
char m_char;
short m_short;
int m_int;
long m_long;
double m_double;
float m_float;
aligner* m_this;
void* m_ptr;
void* (*m_fptr) (void*);
std::size_t m_size_t;
std::ptrdiff_t m_ptrdiff_t;
};
struct region {
unsigned char m_heap[T_heap_size];
region* m_next;
region* m_prev;
std::size_t m_offset;
atomic_word m_lcount;
atomic_word m_rcount;
thread_allocator* m_owner;
void* m_base_mem;
private:
void dtor() throw() {
assert(! m_offset);
assert(! m_lcount);
assert(m_rcount & T_dtor_mark);
DBG_PRINTF(("(%p)-thread_allocator::~thread_allocator()\n", (void*)this));
std::free(m_base_mem);
dbg_thread_adjust_count(-1);
}
public:
static region*
create(thread_allocator* const owner) throw(std::bad_alloc) {
void* const ptr = std::malloc(sizeof(region) + T_heap_size - 1);
if (! ptr) {
DBG_PRINTF(("(%p)-thread_allocator::region::create() - bad alloc\n", (void*)owner));
throw std::bad_alloc();
}
region* const _this = ALIGN_SIZE(ptr, region*, T_heap_size);
assert(IS_ALIGNED(_this, T_heap_size));
assert(IS_ALIGNED(_this->m_heap, sizeof(aligner)));
_this->m_base_mem = ptr;
_this->m_offset = 0;
_this->m_lcount = 1;
_this->m_rcount = 0;
_this->m_owner = owner;
dlnode_init(_this);
DBG_PRINTF(("(%p/%p)-thread_allocator::region::create() - ctor\n",
(void*)_this, (void*)owner));
dbg_thread_adjust_count(1);
return _this;
}
inline static region* from_ptr(void const* const ptr) throw() {
if (! IS_ALIGNED(ptr, T_heap_size)) {
return (region*)(ALIGN_SIZE(ptr, unsigned char const*, T_heap_size) - T_heap_size);
}
return (region*)ptr;
}
inline bool is_full() const throw() {
return (! (m_offset < T_dtor_mark));
}
inline void reset(std::size_t const offset = 0) throw() {
assert(m_lcount < 2);
if (m_offset = offset) {
m_lcount = 2;
}
DBG_PRINTF(("(%p/%p)-thread_allocator::region::reset()\n",
(void*)this, (void*)m_owner));
}
inline void* allocate_remote(std::size_t const sz) throw() {
assert(sz <= T_heap_size);
atomic_word const rcount = atomic_xchg(&m_rcount, 0);
assert(! (rcount & T_dtor_mark));
m_lcount -= rcount;
if (m_lcount == 1) {
reset(sz);
DBG_PRINTF(("(%p/%p/%u)-thread_allocator::region::allocate_remote()\n",
(void*)this, (void*)m_owner, m_offset));
return m_heap;
}
return NULL;
}
inline void* allocate_local(std::size_t const sz) throw() {
assert(sz <= T_heap_size);
std::size_t const offset = m_offset;
if (offset + sz <= T_heap_size) {
m_offset = offset + sz;
++m_lcount;
assert(IS_ALIGNED(m_heap + offset, sizeof(aligner)));
return m_heap + offset;
}
return allocate_remote(sz);
}
inline void deallocate_remote() throw() {
/*
DBG_PRINTF(("(%p/%u)-thread_allocator::region::deallocate_remote()\n",
(void*)this, m_offset));
*/
atomic_word rcount = atomic_xadd(&m_rcount, 1);
if (rcount & T_dtor_mark) {
if (atomic_xadd(&m_lcount, -1) == 1) {
DBG_PRINTF(("(%p/%p/%u)-thread_allocator::region::deallocate_remote() - dtor\n",
(void*)this, (void*)m_owner, m_offset));
reset();
dtor();
}
}
}
inline bool deallocate_local() throw() {
if ((--m_lcount) == 1) {
reset();
return true;
}
return false;
}
void shutdown() throw() {
atomic_word const rcount = atomic_xchg(&m_rcount, T_dtor_mark);
if (atomic_xadd(&m_lcount, -(rcount + 1)) == rcount + 1) {
DBG_PRINTF(("(%p/%p/%u)-thread_allocator::region::deallocate_local() - dtor\n",
(void*)this, (void*)m_owner, m_offset));
reset();
dtor();
}
};
};
region* m_head;
region* m_tail;
unsigned int m_count;
unsigned int m_max_count;
bool m_startup;
private:
region* expand() throw(std::bad_alloc) {
region* const r = dlist_push_head(this, region::create(this));
++m_count;
DBG_PRINTF(("(%p/%p/%d/%d)-thread_allocator::expand()\n",
(void*)this, (void*)r, m_count, m_max_count));
return r;
}
void shrink(region* const r) throw() {
--m_count;
dlist_pop(this, r)->shutdown();
DBG_PRINTF(("(%p/%p/%d/%d)-thread_allocator::shrink()\n",
(void*)this, (void*)r, m_count, m_max_count));
}
void promote(region* const r) throw() {
assert(r != m_head);
dlist_pop(this, r);
dlist_push_head(this, r);
DBG_PRINTF(("(%p/%p/%d/%d)-thread_allocator::promote()\n",
(void*)this, (void*)r, m_count, m_max_count));
}
public:
void startup(
unsigned int const prime = THREAD_ALLOCATOR_PRIME_COUNT,
unsigned int const max_count = THREAD_ALLOCATOR_MAX_COUNT
) throw(std::bad_alloc) {
if (! m_startup) {
m_count = 0;
m_max_count = max_count;
dlist_init(this);
for (unsigned int i = 0; i < prime && i < m_max_count; ++i) {
expand();
}
DBG_PRINTF(("(%p)-thread_allocator::startup()\n", (void*)this));
m_startup = true;
}
}
void shutdown() throw() {
assert(m_startup);
if (m_startup) {
region* node = m_head;
while (node) {
region* const next = node->m_next;
node->shutdown();
--m_count;
node = next;
}
assert(! m_count);
m_startup = false;
DBG_PRINTF(("(%p)-thread_allocator::shutdown()\n", (void*)this));
}
}
void* allocate(std::size_t sz) throw(std::bad_alloc) {
// assert(m_startup);
startup();
if (! m_startup) {
std::printf("STATIC STARTUP ORDER ERROR!!!!!!!!!!\n");
}
sz = ALIGN_SIZE(sz, std::size_t, sizeof(aligner));
if (sz <= T_heap_size) {
region* node = m_head;
while (node) {
void* const ptr = node->allocate_local(sz);
if (ptr) {
if (node != m_head) {
if (! node->is_full()) {
promote(node);
}
}
return ptr;
}
node = node->m_next;
}
return expand()->allocate_local(sz);
}
return NULL;
}
void deallocate(void const* const ptr) throw() {
assert(m_startup);
if (ptr) {
region* const r = region::from_ptr(ptr);
if (r->m_owner == this) {
if (r->deallocate_local()) {
if (m_count > m_max_count) {
shrink(r);
}
}
} else {
r->deallocate_remote();
}
}
}
};
__declspec(thread) thread_allocator<> tls_malloc = {
NULL, NULL, 0, 0, false
};
#if defined(THREAD_MALLOC_OVERLOAD_NEW_DELETE)
//# define THREAD_MALLOC_AUTO_STARTUP
# if ! defined(thread_malloc)
# if defined(THREAD_MALLOC_AUTO_STARTUP)
# define thread_malloc(mp_sz) ( \
tls_malloc.startup(), tls_malloc.allocate(sz) \
)
# else
# define thread_malloc(mp_sz) tls_malloc.allocate((mp_sz))
# endif
# endif
# if ! defined(thread_free)
# define thread_free(mp_ptr) tls_malloc.deallocate((mp_ptr))
# endif
#if ! defined(NDEBUG)
void* operator new(std::size_t sz) throw(std::bad_alloc) {
void* const ptr = thread_malloc(sz);
dbg_thread_adjust_count(1);
return ptr;
}
void* operator new[](std::size_t sz) throw(std::bad_alloc) {
void* const ptr = thread_malloc(sz);
dbg_thread_adjust_count(1);
return ptr;
}
void operator delete(void* ptr) throw() {
dbg_thread_adjust_count(-1);
thread_free(ptr);
}
void operator delete[](void* ptr) throw() {
dbg_thread_adjust_count(-1);
thread_free(ptr);
}
# else
void* operator new(std::size_t sz) throw(std::bad_alloc) {
return thread_malloc(sz);
}
void* operator new[](std::size_t sz) throw(std::bad_alloc) {
return thread_malloc(sz);
}
void operator delete(void* ptr) throw() {
thread_free(ptr);
}
void operator delete[](void* ptr) throw() {
thread_free(ptr);
}
# endif
#endif
/* Simple PThread Abstraction
_________________________________________________________________*/
class mutex_guard {
pthread_mutex_t* m_plock;
public:
struct error {
struct base : public std::exception {};
struct lock_failure : public base {};
struct unlock_failure : public base {};
};
public:
mutex_guard(pthread_mutex_t* const plock)
: m_plock(plock) {
lock();
}
~mutex_guard() throw() {
unlock();
}
void lock() throw(error::lock_failure) {
int const status = pthread_mutex_lock(m_plock);
if (status) {
throw error::lock_failure();
}
}
void unlock() throw(error::lock_failure) {
int const status = pthread_mutex_unlock(m_plock);
if (status) {
throw error::unlock_failure();
}
}
pthread_mutex_t* get_capi() const throw() {
return m_plock;
}
};
class cond_guard {
pthread_cond_t* m_pcond;
public:
struct error {
struct base : public std::exception {};
struct signal_failure : public base {};
struct wait_failure : public base {};
};
public:
cond_guard(pthread_cond_t* const pcond)
: m_pcond(pcond) {
}
void wait(mutex_guard& mutex) throw(error::wait_failure) {
int const status = pthread_cond_wait(m_pcond, mutex.get_capi());
if (status) {
throw error::wait_failure();
}
}
void signal() throw(error::signal_failure) {
int const status = pthread_cond_signal(m_pcond);
if (status) {
throw error::signal_failure();
}
}
void broadcast() throw(error::signal_failure) {
int const status = pthread_cond_broadcast(m_pcond);
if (status) {
throw error::signal_failure();
}
}
};
extern "C" void* thread_sys_entry(void*);
class thread_base {
virtual void on_entry() = 0;
pthread_t m_tid;
public:
virtual ~thread_base() = 0;
void run() {
int const status =
pthread_create(&m_tid, NULL, thread_sys_entry, this);
if (status) {
throw std::exception();
}
}
void join() {
int const status = pthread_join(m_tid, NULL);
if (status) {
throw std::exception();
}
}
void startup_local() throw(std::bad_alloc) {
tls_malloc.startup();
}
void execute_entry() {
on_entry();
}
void shutdown_local() throw() {
#ifdef flagUSEMALLOC
tls_malloc.shutdown();
#else
UPP::MemoryFreeThread();
#endif
}
};
class thread_guard {
thread_base* m_pbase;
public:
thread_guard(thread_base* const pbase = NULL) throw(std::bad_alloc)
:m_pbase(pbase) {
if (m_pbase) {
m_pbase->startup_local();
} else {
tls_malloc.startup();
}
}
~thread_guard() {
if (m_pbase) {
m_pbase->shutdown_local();
} else {
tls_malloc.shutdown();
}
}
thread_base* get_base() const throw() {
return m_pbase;
}
};
thread_base::~thread_base() throw() {}
extern "C" void*
thread_sys_entry(
void* state
) throw() {
thread_base* const _this =
reinterpret_cast<thread_base*>(state);
_this->startup_local();
_this->execute_entry();
_this->shutdown_local();
return NULL;
}
/* Sample Application
_________________________________________________________________*/
#include <cstdio>
#include <climits>
#include <ctime>
#include <list>
#include <iostream>
template<typename T, template<typename, typename> class C>
class ptr_collection {
typedef C<T*, std::allocator<T*> > col_type;
col_type m_col;
static pthread_mutex_t g_lock;
static pthread_cond_t g_cond_capi;
static cond_guard g_cond;
unsigned int prv_try_flush(unsigned int const max_count) {
assert(max_count > 0);
unsigned int count = 0;
while (! m_col.empty() && count < max_count) {
T* const node = m_col.front();
m_col.pop_front();
delete node;
++count;
}
return count;
}
public:
void push_back(T* const node) {
{
mutex_guard lock(&g_lock);
m_col.push_back(node);
}
g_cond.signal();
}
unsigned int wait_flush(unsigned int const max_count) {
unsigned int count;
mutex_guard lock(&g_lock);
while (! (count = prv_try_flush(max_count))) {
g_cond.wait(lock);
}
assert(count && count <= max_count);
return count;
}
};
template<typename T, template<typename, typename> class C>
pthread_mutex_t
ptr_collection<T, C>::g_lock = PTHREAD_MUTEX_INITIALIZER;
template<typename T, template<typename, typename> class C>
pthread_cond_t
ptr_collection<T, C>::g_cond_capi = PTHREAD_COND_INITIALIZER;
template<typename T, template<typename, typename> class C>
cond_guard
ptr_collection<T, C>::g_cond(&ptr_collection<T, C>::g_cond_capi);
#define THREAD_COUNT 6
#define PRIVATE_COUNT 50000
#define CTOR_COUNT (THREAD_COUNT * 100000)
#define PRODUCER_CTOR_COUNT (CTOR_COUNT / THREAD_COUNT)
#define CONSUMER_DTOR_COUNT (CTOR_COUNT / THREAD_COUNT)
#define DBG_THREAD_PRINTF_VERBOSITY 25000000
struct TestVal {
int q;
int c, d, e;
TestVal(int x) { q = x; }
};
static ptr_collection<TestVal, std::list>* g_int_ptrs = NULL;
class producer_thread : public thread_base {
void on_entry() {
DBG_PRINTF(("(%p)-producer_thread::on_entry()\n", (void*)this));
int i;
for (i = 1; i < PRODUCER_CTOR_COUNT + 1; ++i) {
g_int_ptrs->push_back(new TestVal(i));
if (! (i % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-producer_thread - %d - create\n", (void*)this, i);
}
}
}
};
class consumer_thread : public thread_base {
void on_entry() {
DBG_PRINTF(("(%p)-consumer_thread::on_entry()\n", (void*)this));
int i = 0;
while ((i += g_int_ptrs->wait_flush(CONSUMER_DTOR_COUNT - i)) != CONSUMER_DTOR_COUNT) {
if (! (i % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-consumer_thread - %d - delete\n", (void*)this, i);
}
}
std::printf("(%p)-consumer_thread - %d - delete\n", (void*)this, i);
assert(i == CONSUMER_DTOR_COUNT);
}
};
class private_thread : public thread_base {
void on_entry() {
DBG_PRINTF(("(%p)-private_thread::on_entry()\n", (void*)this));
for (int runs = 1; runs < 10; ++runs) {
std::list<TestVal*> int_ptrs_local;
for (int i = 1; i < (runs * PRIVATE_COUNT) + 1; ++i) {
int_ptrs_local.push_back(new TestVal(i));
if (! (i % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-private_thread - %d\n", (void*)this, i);
}
}
while (! int_ptrs_local.empty()) {
TestVal* const number = int_ptrs_local.front();
if (! (number->q % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-main - %d delete\n", (void*)this, *number);
}
delete number;
int_ptrs_local.pop_front();
}
}
}
};
#define TEST_RUNS 20
void ChrisTest() {
std::clock_t total_time = 0;
for(int runs = 1; runs < TEST_RUNS + 1; ++runs) {
std::printf("(%d) - test running\n", runs);
thread_guard this_thread;
std::clock_t const startt = std::clock();
{
producer_thread producer[THREAD_COUNT];
consumer_thread consumer[THREAD_COUNT];
private_thread privatet;
ptr_collection<TestVal, std::list> int_ptrs_global;
g_int_ptrs = &int_ptrs_global;
int i;
for (i = 0; i < THREAD_COUNT; ++i) {
consumer[i].run();
}
for (i = 0; i < THREAD_COUNT; ++i) {
producer[i].run();
}
privatet.run();
std::list<TestVal*> int_ptrs_local;
for (i = 1; i < runs * PRIVATE_COUNT + 1; ++i) {
int_ptrs_local.push_back(new TestVal(i));
if (! (i % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-main - %d\n", (void*)&this_thread, i);
}
}
while (! int_ptrs_local.empty()) {
TestVal* const number = int_ptrs_local.front();
if (! (number->q % DBG_THREAD_PRINTF_VERBOSITY)) {
std::printf("(%p)-main - %d delete\n", (void*)&this_thread, *number);
}
delete number;
int_ptrs_local.pop_front();
}
if (! (runs % 2)) {
for (i = 0; i < THREAD_COUNT; ++i) {
consumer[i].join();
}
privatet.join();
for (i = 0; i < THREAD_COUNT; ++i) {
producer[i].join();
}
} else {
for (i = 0; i < THREAD_COUNT; ++i) {
producer[i].join();
}
for (i = 0; i < THREAD_COUNT; ++i) {
consumer[i].join();
}
privatet.join();
}
}
std::clock_t const endt = std::clock();
total_time += endt - startt;
std::printf("(%d) - test finished\n", runs);
}
std::cout << "\n\ntest time: " <<
double(total_time)/CLOCKS_PER_SEC * 1000 << " ms\n--------------------\n";
if (dbg_thread_get_count()) {
std::printf("\n\nMEMORY LEAK: %d BLOCKS\n\n", dbg_thread_get_count());
}
DBG_PRINTF(("\n\n\n__________________________\npress <ENTER> to exit...\n"));
std::getchar();
}
#endif

View file

@ -0,0 +1,315 @@
#if 0
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <exception>
#include <new>
#define NDEBUG
/* Helper Macros
_____________________________________________________________*/
#if ! defined(NDEBUG)
# include <cstdio>
# define DBG_PRINTF(mp_exp) std::printf mp_exp
#else
# define DBG_PRINTF(mp_exp)
#endif
#define ALIGN_SIZE(mp_this, mp_type, mp_align) ((mp_type) \
(((std::ptrdiff_t const)((mp_this))) + \
((std::ptrdiff_t const)((mp_align)) - 1) & \
(-((std::ptrdiff_t const)((mp_align))))) \
)
/* General Purpose Intrusive Double Linked-List
_____________________________________________________________*/
template<typename T>
static T dlist_init(T _this) throw() {
_this->m_head = _this->m_tail = NULL;
return _this;
}
template<typename T>
static T dlnode_init(T _this) throw() {
_this->m_next = _this->m_prev = NULL;
return _this;
}
template<typename T, typename N>
static N dlist_pop(T _this, N node) throw() {
N const next = node->m_next;
N const prev = node->m_prev;
if (! next && ! prev) {
_this->m_head = 0;
_this->m_tail = 0;
} else if (next && ! prev) {
next->m_prev = 0;
_this->m_head = next;
} else if (! next && prev) {
prev->m_next = 0;
_this->m_tail = prev;
} else {
next->m_prev = prev;
prev->m_next = next;
}
return node;
}
template<typename T, typename N>
static N dlist_push_head(T _this, N node) throw() {
node->m_prev = 0;
if (! _this->m_head) {
_this->m_tail = node;
node->m_next = NULL;
} else {
node->m_next = _this->m_head;
_this->m_head->m_prev = node;
}
_this->m_head = node;
return node;
}
/* General Purpose Dynamic Region Allocator
_____________________________________________________________*/
template<std::size_t T_depth>
struct region_allocator {
union aligner {
char m_char;
short m_short;
int m_int;
long m_long;
double m_double;
float m_float;
aligner* m_this;
void* m_ptr;
std::size_t m_size_t;
std::ptrdiff_t m_ptrdiff_t;
};
struct heap {
unsigned char m_base[T_depth];
heap* m_next;
heap* m_prev;
std::size_t m_offset;
std::size_t m_depth;
void ctor() {
dlnode_init(this);
m_offset = m_depth = 0;
}
void* allocate(std::size_t const sz) throw() {
std::size_t const offset = m_offset;
if (offset + sz < T_depth - 1) {
++m_depth;
m_offset += sz;
return m_base + offset;
}
return NULL;
}
bool deallocate() throw() {
if (! (--m_depth)) {
m_offset = 0;
return true;
}
return false;
}
bool is_heap(void const* const ptr) const throw() {
unsigned char const* const head =
reinterpret_cast<unsigned char const*>(m_base);
unsigned char const* const tail =
reinterpret_cast<unsigned char const*>(m_base + T_depth - 1);
unsigned char const* const buf =
reinterpret_cast<unsigned char const*>(ptr);
return (buf >= head && buf < tail);
}
};
heap* m_head;
heap* m_tail;
std::size_t m_depth;
std::size_t const m_max_depth;
heap* create_heap() {
heap* const h = reinterpret_cast<heap*>(std::malloc(sizeof(*h)));
if (! h) {
throw std::bad_alloc();
}
h->ctor();
dlist_push_head(this, h);
++m_depth;
DBG_PRINTF(("(%p/%d/%d) Dynamic Region Expand\n",
(void*)h, m_depth, m_max_depth));
return h;
}
void destroy_heap(heap* const h) throw() {
dlist_pop(this, h);
std::free(h);
--m_depth;
DBG_PRINTF(("(%p/%d/%d) Dynamic Region Shrink\n",
(void*)h, m_depth, m_max_depth));
}
heap* find_heap(void const* const ptr) const throw() {
heap* h = m_head;
while (h) {
if (h->is_heap(ptr)) {
return h;
}
h = h->m_next;
}
return NULL;
}
region_allocator(
std::size_t const prime,
std::size_t const max_depth
) : m_depth(0),
m_max_depth(max_depth) {
dlist_init(this);
for (std::size_t i = 0; i < prime && i < max_depth; ++i) {
create_heap();
}
}
~region_allocator() throw() {
heap* h = m_head;
while (h) {
heap* const next = h->m_next;
destroy_heap(h);
h = next;
}
}
inline void* allocate(std::size_t sz) throw(std::bad_alloc) {
sz = ALIGN_SIZE(sz, std::size_t, sizeof(aligner));
if (sz <= T_depth) {
heap* h = m_head;
while (h) {
void* const ptr = h->allocate(sz);
if (ptr) {
if (h != m_head) {
dlist_pop(this, h);
dlist_push_head(this, h);
DBG_PRINTF(("(%p/%d/%d) Dynamic Region Heap Adjust\n",
(void*)h, m_depth, m_max_depth));
}
return ptr;
}
h = h->m_next;
}
void* const ptr = create_heap()->allocate(sz);
if (ptr) {
return ptr;
}
}
void* const ptr = std::malloc(sz);
if(! ptr) {
throw std::bad_alloc();
}
return ptr;
}
inline void deallocate(void* const ptr) throw() {
heap* const h = find_heap(ptr);
if (h) {
if (h->deallocate()) {
if (m_depth > m_max_depth) {
destroy_heap(h);
}
}
} else {
std::free(ptr);
}
}
};
/* Global Allocator Overloads
_____________________________________________________________*/
#ifdef flagCHRIS
#define TEST_USE_REGION_ALLOCATOR
#endif
#if defined(TEST_USE_REGION_ALLOCATOR)
// global allocator instance
static region_allocator<5000000> g_region_malloc(1, 3);
// global operator new/delete overloads
void* operator new(std::size_t sz) throw(std::bad_alloc) {
return g_region_malloc.allocate(sz);
}
void* operator new [](std::size_t sz) throw(std::bad_alloc) {
return g_region_malloc.allocate(sz);
}
void operator delete(void* ptr) throw() {
g_region_malloc.deallocate(ptr);
}
void operator delete [](void* ptr) throw() {
g_region_malloc.deallocate(ptr);
}
#endif
/* Simple Test Application
_____________________________________________________________*/
#include <ctime>
#include <cstdio>
#include <iostream>
#include <list>
#define SEQUENCE_DEPTH 999999
void ChrisTest() {
std::clock_t start = std::clock();
{
int i;
std::list<int> sequence1;
std::list<int*> sequence2;
for (i = 0; i < SEQUENCE_DEPTH; ++i) {
sequence1.push_back(i);
}
for (i = 0; i < SEQUENCE_DEPTH; ++i) {
sequence2.push_back(new int(i));
}
while (! sequence1.empty()) {
sequence1.pop_front();
}
while (! sequence2.empty()) {
delete sequence2.front();
sequence2.pop_front();
}
}
std::clock_t endt = std::clock();
std::cout <<"Time: " <<
double(endt-start)/CLOCKS_PER_SEC * 1000 << " ms\n\n"
<< "Press <ENTER> to exit...\n";
}
#endif

5
benchmarks/AllocMT/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _AllocMT_icpp_init_stub
#define _AllocMT_icpp_init_stub
#include "Core/init"
#include "CppBase/init"
#endif

View file

@ -0,0 +1,50 @@
* c:\out\MSC71cdb.Mt.Usemalloc\AllocMT.exe 27.04.2008 20:50:24, user: Luzr
Single thread: 6015
Two threads: 6641
CoWork (1000 runs): 3359
* c:\out\MSC71cdb.Mt\AllocMT.exe 27.04.2008 20:51:34, user: Luzr
Single thread: 5110
Two threads: 5343
CoWork (1000 runs): 2657
* c:\out\MSC71cdb\AllocMT.exe 27.04.2008 20:53:44, user: Luzr
Single thread: 4875
* c:\out\MSC71cdb.Usemalloc\AllocMT.exe 27.04.2008 20:54:32, user: Luzr
Single thread: 6297
* c:\out\MSC71cdb.Chris.Mt.Usemalloc\AllocMT.exe 28.04.2008 10:24:51, user: Luzr
Single thread: 5688
Two threads: 6219
CoWork (1000 runs): 3000
// ----------
* c:\out\MSC71cdb.Mt\AllocMT.exe 28.04.2008 11:55:03, user: Luzr
1 thread(s) 250 ms
2 thread(s) 265 ms
4 thread(s) 532 ms
8 thread(s) 1031 ms
16 thread(s) 2062 ms
32 thread(s) 4141 ms
64 thread(s) 8312 ms
CoWork (1000 runs): 2594 ms
* c:\out\MSC71cdb.Chris.Mt.Usemalloc\AllocMT.exe 28.04.2008 12:04:59, user: Luzr
1 thread(s) 282 ms
2 thread(s) 296 ms
4 thread(s) 641 ms
8 thread(s) 1188 ms
16 thread(s) 2343 ms
32 thread(s) 4688 ms
64 thread(s) 9312 ms
CoWork (1000 runs): 2953 ms

View file

@ -0,0 +1,71 @@
#include <Core/Core.h>
#include <deque>
using namespace Upp;
using namespace std;
#define N 500000
int dummy;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_FILE|LOG_COUT);
{
TimeStop tm;
Vector<int> d;
for(int n = 0; n < N; n++) {
d.clear();
for(int i = 0; i < 200; i++) {
d.Add(i);
d.Add(i);
}
}
RLOG("Vector add " << tm);
tm.Reset();
for(int n = 0; n < N; n++)
for(int i = 0; i < (int)d.size(); i++)
dummy += d[i];
RLOG("Vector read " << tm);
}
{
TimeStop tm;
deque<int> d;
for(int n = 0; n < N; n++) {
d.clear();
for(int i = 0; i < 200; i++) {
d.push_back(i);
d.push_front(i);
}
}
RLOG("deqeue add " << tm);
tm.Reset();
for(int n = 0; n < N; n++)
for(int i = 0; i < (int)d.size(); i++)
dummy += d[i];
RLOG("deqeue index read " << tm);
tm.Reset();
for(int n = 0; n < N; n++)
for(deque<int>::iterator i = d.begin(); i != d.end(); i++)
dummy += *i;
RLOG("deqeue iterator read " << tm);
}
{
TimeStop tm;
BiVector<int> d;
for(int n = 0; n < N; n++) {
d.Clear();
for(int i = 0; i < 200; i++) {
d.AddTail(i);
d.AddHead(i);
}
}
RLOG("BiVector add " << tm);
tm.Reset();
for(int n = 0; n < N; n++)
for(int i = 0; i < d.GetCount(); i++) {
dummy += d[i];
}
RLOG("BiVector read " << tm);
}
}

View file

@ -0,0 +1,12 @@
optimize_speed;
uses
Core;
file
BiVector.cpp,
results.txt;
mainconfig
"" = "";

4
benchmarks/BiVector/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _BiVector_icpp_init_stub
#define _BiVector_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,9 @@
* c:\out\MSC71cdb\BiVector.exe 04.05.2008 12:11:12, user: Luzr
deqeue add 3.859
deqeue index read 0.594
deqeue iterator read 0.437
BiVector add 2.110
BiVector read 1.156
=============================

View file

@ -0,0 +1,54 @@
#include <Core/Core.h>
#include <vector>
#include <map>
using namespace Upp;
using namespace std;
//#define TEST_STL
//#define TEST_UPP
struct Foo : Moveable<Foo> {
int a, b;
Foo(int a, int b) : a(a), b(b) {}
Foo() {}
};
CONSOLE_APP_MAIN
{
{
std::string key = "key";
vector<int> fa;
fa.push_back(10);
map<string, int> fb;
fb[key] = 10;
#ifdef TEST_STL
vector<Foo> x;
x.push_back(Foo(1, 2));
map<int, Foo> map1;
map1[20].a = 10;
map<std::string, Foo> map2;
map2[key].a = 10;
#endif
}
{
String key = "key";
Vector<int> fa;
fa.Add(10);
VectorMap<String, int> fb;
fb.GetAdd(key) = 10;
#ifdef TEST_UPP
Vector<Foo> x;
x.Add(Foo(1, 2));
VectorMap<int, Foo> map1;
map1.GetAdd(20).a = 10;
VectorMap<String, Foo> map2;
map2.GetAdd(key).a = 10;
#endif
}
}

View file

@ -0,0 +1,10 @@
uses
Core;
file
data.txt,
Bloat.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,8 @@
base 477828
STL: 484452 6624
UPP: 480356 2528
SIZE 353380
STL: 358980 5600
UPP: 354340 969

4
benchmarks/Bloat/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _Bloat_icpp_init_stub
#define _Bloat_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,20 @@
#include <Core/Core.h>
using namespace Upp;
class Test {
public:
Test (int c) {count = c;}
// virtual ~Test() { }
int count;
};
CONSOLE_APP_MAIN
{
RTIMING("NewDelete");
for (int i=0; i<=10000000; i++) {
Test *test = new Test(i);
delete test;
}
}

View file

@ -0,0 +1,10 @@
uses
Core;
file
NewDelete.cpp;
mainconfig
"" = "",
"" = "USEMALLOC";

View file

@ -0,0 +1,4 @@
#ifndef _NewDelete_icpp_init_stub
#define _NewDelete_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,34 @@
#include <Core/Core.h>
using namespace Upp;
struct Tree {
Tree *left;
Tree *right;
};
Tree *CreateTree(int n)
{
if(n <= 0)
return NULL;
Tree *t = new Tree;
t->left = CreateTree(n - 1);
t->right = CreateTree(n - 1);
return t;
}
void DeleteTree(Tree *t)
{
if(t) {
DeleteTree(t->left);
DeleteTree(t->right);
delete t;
}
}
CONSOLE_APP_MAIN
{
RTIMING("Tree new/delete");
for(int i = 0; i < 100; i++)
DeleteTree(CreateTree(20));
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
NewDeleteTree.cpp;
mainconfig
"" = "";

69
benchmarks/Sort/Sort.cpp Normal file
View file

@ -0,0 +1,69 @@
#include <Core/Core.h>
#include <algorithm>
#include <vector>
using namespace Upp;
#define BM_(k, x1, x, sort) { d1 <<= d; RTIMING(k " " #sort); sort(d1); }
#define BV(k, sort) BM_(k, d1, d, sort)
#define BA(k, sort) BM_(k " Array", a1, a, sort)
#define Bv(k, sort) { s1 = s; RTIMING(k " " #sort " vector<string>"); sort(s1.begin(), s1.end()); }
#define BS(k, sort) { d1 <<= d; RTIMING(k " " #sort " String"); sort(d1.Begin(), d1.End()); }
#define Bm(k)\
BV(k, Sort)\
BV(k, GetSortOrder)\
BV(k, StableSort)\
BV(k, GetStableSortOrder)\
BV(k, StableSortCmp)\
BV(k, GetStableSortOrderCmp)\
BS(k, std::sort)\
BS(k, std::stable_sort)\
Bv(k, std::sort)\
Bv(k, std::stable_sort)\
BA(k, Sort)\
BA(k, StableSort)\
BA(k, StableSortCmp)\
CONSOLE_APP_MAIN
{
for(int q = 0; q < 100; q++) {
Vector<String> d, d1;
Array<String> a, a1;
std::vector<std::string> s, s1;
for(int i = 0; i < 10000; i++) {
String x = AsString(rand());
d.Add(x);
a.Add(x);
s.push_back(to_string(x));
}
Bm("S");
}
for(int q = 0; q < 100; q++) {
Vector<String> d, d1;
std::vector<std::string> s, s1;
for(int i = 0; i < 10000; i++) {
String x = AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand());
d.Add(x);
s.push_back(to_string(x));
}
Bm("M");
}
for(int q = 0; q < 100; q++) {
Vector<String> d, d1;
std::vector<std::string> s, s1;
for(int i = 0; i < 10000; i++) {
String x = AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand())
+ AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand())
+ AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand())
+ AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand()) + AsString(rand());
d.Add(x);
s.push_back(to_string(x));
}
Bm("L");
}
}

9
benchmarks/Sort/Sort.upp Normal file
View file

@ -0,0 +1,9 @@
uses
Core;
file
Sort.cpp optimize_speed;
mainconfig
"" = "";

4
benchmarks/Sort/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _Sort_icpp_init_stub
#define _Sort_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,33 @@
#include <Core/Core.h>
using namespace Upp;
#define N 10000000
CONSOLE_APP_MAIN
{
String s;
s << GetSysDate() << "Hello world!!!";
int q = 0;
{
RTIMING("Find 2");
for(int i = 0; i < N; i++)
q += s.FindFirstOf("rd");
}
{
RTIMING("Find 3");
for(int i = 0; i < N; i++)
q += s.FindFirstOf("!ab");
}
{
RTIMING("Find 4");
for(int i = 0; i < N; i++)
q += s.FindFirstOf("!abc");
}
{
RTIMING("Find 5");
for(int i = 0; i < N; i++)
q += s.FindFirstOf("!abcd");
}
RDUMP(q);
}

View file

@ -0,0 +1,12 @@
optimize_speed;
uses
Core;
file
StringFindOf.cpp,
numbers.txt;
mainconfig
"" = "";

View file

@ -0,0 +1,4 @@
#ifndef _StringFindOf_icpp_init_stub
#define _StringFindOf_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,17 @@
* e:\out\MSC71cdb\StringFindOf.exe 07.06.2008 15:49:10, user: cxl
q = 800000000
TIMING Find 5 : 1.42 s - 1.42 s ( 1.42 s / 1 ), min: 1.42 s , max: 1.42 s , nesting: 1 - 1
TIMING Find 4 : 1.06 s - 1.06 s ( 1.06 s / 1 ), min: 1.06 s , max: 1.06 s , nesting: 1 - 1
TIMING Find 3 : 891.00 ms - 891.00 ms (891.00 ms / 1 ), min: 891.00 ms, max: 891.00 ms, nesting: 1 - 1
TIMING Find 2 : 1.24 s - 1.24 s ( 1.24 s / 1 ), min: 1.24 s , max: 1.24 s , nesting: 1 - 1
*************************
* e:\out\MSC71cdb\StringFindOf.exe 07.06.2008 15:50:27, user: cxl
q = 800000000
TIMING Find 5 : 1.23 s - 1.23 s ( 1.23 s / 1 ), min: 1.23 s , max: 1.23 s , nesting: 1 - 1
TIMING Find 4 : 485.00 ms - 485.00 ms (485.00 ms / 1 ), min: 485.00 ms, max: 485.00 ms, nesting: 1 - 1
TIMING Find 3 : 621.00 ms - 621.00 ms (621.00 ms / 1 ), min: 621.00 ms, max: 621.00 ms, nesting: 1 - 1
TIMING Find 2 : 263.00 ms - 263.00 ms (263.00 ms / 1 ), min: 263.00 ms, max: 263.00 ms, nesting: 1 - 1

View file

@ -0,0 +1,20 @@
#include "bsb.h"
CONSOLE_APP_MAIN
{
for(int q = 5; q < 1000; q = 5 * q / 4) {
{
TimeStop tm;
for(int i = 0; i < 1000000; i++)
BenchStringBuffer(q);
Cout() << q << ' ' << tm << " - ";
}
{
TimeStop tm;
for(int i = 0; i < 1000000; i++)
BenchString(q);
Cout() << tm << "\r\n";
}
}
}

View file

@ -0,0 +1,11 @@
uses
Core;
file
bsb.h,
bsb.cpp,
benchSBuffer.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,17 @@
#include "bsb.h"
String BenchStringBuffer(int n)
{
StringBuffer b;
for(int i = 0; i < n; i++)
b.Cat(i);
return b;
}
String BenchString(int n)
{
String b;
for(int i = 0; i < n; i++)
b.Cat(i);
return b;
}

View file

@ -0,0 +1,11 @@
#ifndef _benchSBuffer_bsb_h_
#define _benchSBuffer_bsb_h_
#include <Core/Core.h>
using namespace Upp;
String BenchStringBuffer(int n);
String BenchString(int n);
#endif

View file

@ -0,0 +1,4 @@
#ifndef _benchSBuffer_icpp_init_stub
#define _benchSBuffer_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,57 @@
#include <Core/Core.h>
#ifdef _DEBUG
#define N 1000
#else
#define N 1000 * 100
#endif
#define THREADS 5
using namespace Upp;
Mutex mutex;
Semaphore todo;
BiVector<int *> queue;
void ProducerThread()
{
for(int i = 0; i < N; i++) {
mutex.Enter();
queue.AddHead() = new int;
mutex.Leave();
todo.Release();
}
}
void ConsumerThread()
{
for(;;) {
todo.Wait();
Mutex::Lock __(mutex);
if(queue.GetCount()) {
int *ptr = queue.Tail();
if(!ptr) break;
queue.DropTail();
delete ptr;
}
}
}
CONSOLE_APP_MAIN {
Thread producer[THREADS];
Thread consumer[THREADS];
for(int i = 0; i < THREADS; i++) {
producer[i].Run(callback(ProducerThread));
consumer[i].Run(callback(ConsumerThread));
}
for(int i = 0; i < THREADS; i++)
producer[i].Wait();
mutex.Enter();
queue.AddHead(NULL);
mutex.Leave();
for(int i = 0; i < THREADS; i++)
todo.Release();
for(int i = 0; i < THREADS; i++)
consumer[i].Wait();
}

View file

@ -0,0 +1,10 @@
uses
Core;
file
chris.cpp;
mainconfig
"" = "MT",
"" = "MT USEMALLOC";

4
benchmarks/chris/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _chris_icpp_init_stub
#define _chris_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,17 @@
description "C++ standard library vs. U++ Core benchmark";
optimize_speed;
uses
Core;
file
main.cpp;
mainconfig
"" = "",
"" = "USEMALLOC",
"" = "MT",
"" = "USEMALLOC MT",
"" = "HEAPSTAT";

View file

@ -0,0 +1,4 @@
#ifndef _idmapBench_icpp_init_stub
#define _idmapBench_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,207 @@
#define NDEBUG
#define _SECURE_SCL 0
#include <Core/Core.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <vector>
#include <algorithm>
#include <map>
#include <deque>
#include <string>
#define TEST_HASHMAP
#ifdef TEST_HASHMAP
#ifdef COMPILER_GCC
#include <tr1/unordered_map>
#else
#include <hash_map>
#endif
#endif
using namespace std;
using namespace Upp;
#define NO_OUTPUT // for benchmark purposes, output is omitted
void BenchNTL(const char *file) {
FileIn in(file);
if (!in) {
std::cout << "Cannot open input file.\n";
return;
}
VectorMap<String, Vector<int> > map;
int line = 1;
for(;;) {
int c = in.Get();
if(c < 0) break;
if(IsAlpha(c) || c == '_') {
String id;
id.Cat(c);
c = in.Get();
while(c >= 0 && (IsAlNum(c) || c == '_')) {
id.Cat(c);
c = in.Get();
}
map.GetAdd(id).Add(line);
}
else
if(IsDigit(c))
do c = in.Get();
while(c >= 0 && (IsAlNum(c) || c == '.'));
if(c == '\n')
++line;
}
Vector<int> order = GetSortOrder(map.GetKeys());
#ifndef NO_OUTPUT
for(int i = 0; i < order.GetCount(); i++) {
std::cout << ~map.GetKey(order[i]) << ": ";
const Vector<int>& l = map[order[i]];
for(int i = 0; i < l.GetCount(); i++) {
if(i) std::cout << ", ";
std::cout << l[i];
}
std::cout << '\n';
}
#endif
}
template <class Container>
void BenchSTL(Container& imap, const char *file) {
std::ifstream in(file);
if (!in) {
std::cout << "Cannot open input file.\n";
return;
}
int line = 1;
for(;;) {
int c = in.get();
if(c == EOF) break;
if(isalpha(c) || c == '_') {
string id;
id += c;
c = in.get();
while(c != EOF && (isalnum(c) || c == '_')) {
id += c;
c = in.get();
}
imap[id].push_back(line);
}
else
if(isdigit(c))
do c = in.get();
while(c != EOF && (isalnum(c) || c == '.'));
if(c == '\n')
++line;
}
}
void BenchMap(const char *file)
{
map< string, vector<int> > imap;
BenchSTL(imap, file);
#ifndef NO_OUTPUT
map< std::string, vector<int> >::const_iterator e = imap.end();
for(map< std::string, vector<int> >::const_iterator i = imap.begin(); i != e; i++) {
std::cout << i->first << ": ";
vector<int>::const_iterator e = i->second.end();
vector<int>::const_iterator b = i->second.begin();
for(vector<int>::const_iterator j = b; j != e; j++) {
if(j != b) std::cout << ", ";
std::cout << *j;
}
std::cout << '\n';
}
#endif
}
#ifdef TEST_HASHMAP
#ifdef COMPILER_GCC
typedef std::tr1::unordered_map< string, vector<int> > HashMap;
#else
typedef stdext::hash_map< string, vector<int> > HashMap;
#endif
inline bool h_less(const HashMap::value_type *a, const HashMap::value_type *b)
{
return a->first < b->first;
}
void BenchHashMap(const char *file)
{
HashMap imap;
BenchSTL(imap, file);
vector< const HashMap::value_type * > order;
for(HashMap::const_iterator i = imap.begin(); i != imap.end(); i++)
order.push_back(&*i);
sort(order.begin(), order.end(), h_less);
#ifndef NO_OUTPUT
vector< const HashMap::value_type * >::const_iterator e = order.end();
for(vector< const HashMap::value_type * >::const_iterator i = order.begin(); i != e; i++) {
std::cout << (*i)->first << ": ";
vector<int>::const_iterator e = (*i)->second.end();
vector<int>::const_iterator b = (*i)->second.begin();
for(vector<int>::const_iterator j = b; j != e; j++) {
if(j != b) std::cout << ", ";
std::cout << *j;
}
std::cout << '\n';
}
#endif
}
#endif
#define N 10000
CONSOLE_APP_MAIN
{
String fn;
int argc = CommandLine().GetCount();
const Vector<String>& argv = CommandLine();
if(argc < 1)
fn = GetDataFile("main.cpp");
else
fn = argv[0];
BenchNTL(fn); // first run to cache the file
#ifdef TEST_HASHMAP
{
BenchHashMap(fn);
TimeStop tm;
for(int n = 0; n < N; n++)
BenchHashMap(fn);
cout << "STL hash_map time: " << tm.Elapsed() << " ms \n";
}
#endif
{
BenchMap(fn);
TimeStop tm;
for(int n = 0; n < N; n++)
BenchMap(fn);
cout << "STL map time: " << tm.Elapsed() << " ms \n";
}
{
BenchNTL(fn);
TimeStop tm;
for(int n = 0; n < N; n++)
BenchNTL(fn);
cout << "NTL time: " << tm.Elapsed() << " ms\n";
}
}

4
benchmarks/sizeof/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _sizeof_icpp_init_stub
#define _sizeof_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,41 @@
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
RDUMP(sizeof(bool));
RDUMP(sizeof(int));
RDUMP(sizeof(unsigned));
RDUMP(sizeof(long int));
RDUMP(sizeof(long));
RDUMP(sizeof(unsigned long));
RDUMP(sizeof(short int));
RDUMP(sizeof(byte));
RDUMP(sizeof(word));
RDUMP(sizeof(dword));
RDUMP(sizeof(qword));
RDUMP(sizeof(int64));
RDUMP(sizeof(uint64));
RDUMP(sizeof(float));
RDUMP(sizeof(double));
RDUMP(sizeof(long double));
RDUMP(sizeof(Vector<int>));
RDUMP(sizeof(Array<int>));
RDUMP(sizeof(Index<int>));
RDUMP(sizeof(ArrayIndex<int>));
RDUMP(sizeof(ArrayMap<int, int>));
RDUMP(sizeof(VectorMap<int, int>));
RDUMP(sizeof(BiArray<int>));
RDUMP(sizeof(BiVector<int>));
RDUMP(sizeof(String));
RDUMP(sizeof(WString));
RDUMP(sizeof(Date));
RDUMP(sizeof(Time));
RDUMP(sizeof(Size));
RDUMP(sizeof(Point));
RDUMP(sizeof(Rect));
RDUMP(sizeof(Color));
RDUMP(sizeof(Mutex));
RDUMP(sizeof(RWMutex));
}

View file

@ -0,0 +1,6 @@
file
e:\out\upp/sizeof/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\sizeof.log,
e:\out\upp/sizeof/CONSOLE-DEBUG-GNU-IA32-MAIN-ST-STATIC-WIN32\sizeof.log,
e:\out\upp/sizeof/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\sizeof.log,
e:/hjelp,
e:\out\upp/sizeof/CONSOLE-DEBUG-GNU-IA32-MAIN-ST-STATIC-WIN32\sizeof.log;

View file

@ -0,0 +1,10 @@
uses
Core;
file
main.cpp
depends() test.h;
mainconfig
"" = "CONSOLE MT";

View file

@ -0,0 +1,15 @@
description "Demonstration of \"blue\" ToolBar and MenuBar skin";
uses
CtrlLib,
RichEdit,
PdfDraw,
art\BlueBar;
file
UWord.cpp,
UWord.iml;
mainconfig
"" = "GUI",
"" = "GUI .NOGTK";

275
examples/BlueBar/UWord.cpp Normal file
View file

@ -0,0 +1,275 @@
#include <RichEdit/RichEdit.h>
#include <PdfDraw/PdfDraw.h>
#include <art/BlueBar/BlueBar.h>
using namespace Upp;
#define IMAGECLASS UWordImg
#define IMAGEFILE <UWord/UWord.iml>
#include <Draw/iml.h>
FileSel& UWordFs()
{
static FileSel fs;
return fs;
}
FileSel& PdfFs()
{
static FileSel fs;
return fs;
}
class UWord : public TopWindow {
public:
virtual void DragAndDrop(Point, PasteClip& d);
virtual void FrameDragAndDrop(Point, PasteClip& d);
protected:
RichEdit editor;
MenuBar menubar;
ToolBar toolbar;
StatusBar statusbar;
String filename;
static LRUList& lrufile() { static LRUList l; return l; }
void Load(const String& filename);
void OpenFile(const String& fn);
void New();
void Open();
void Save0();
void Save();
void SaveAs();
void Print();
void Pdf();
void About();
void Destroy();
void SetBar();
void FileBar(Bar& bar);
void AboutMenu(Bar& bar);
void MainMenu(Bar& bar);
void MainBar(Bar& bar);
public:
typedef UWord CLASSNAME;
static void SerializeApp(Stream& s);
UWord();
};
void UWord::FileBar(Bar& bar)
{
bar.Add("New", CtrlImg::new_doc(), THISBACK(New))
.Key(K_CTRL_N)
.Help("Open new window");
bar.Add("Open..", CtrlImg::open(), THISBACK(Open))
.Key(K_CTRL_O)
.Help("Open existing document");
bar.Add(editor.IsModified(), "Save", CtrlImg::save(), THISBACK(Save))
.Key(K_CTRL_S)
.Help("Save current document");
bar.Add("SaveAs", CtrlImg::save_as(), THISBACK(SaveAs))
.Help("Save current document with a new name");
bar.ToolGap();
bar.MenuSeparator();
bar.Add("Print..", CtrlImg::print(), THISBACK(Print))
.Key(K_CTRL_P)
.Help("Print document");
bar.Add("Export to PDF..", UWordImg::pdf(), THISBACK(Pdf))
.Help("Export document to PDF file");
if(bar.IsMenuBar()) {
if(lrufile().GetCount())
lrufile()(bar, THISBACK(OpenFile));
bar.Separator();
bar.Add("Exit", THISBACK(Destroy));
}
}
void UWord::AboutMenu(Bar& bar)
{
bar.Add("About..", THISBACK(About));
}
void UWord::MainMenu(Bar& bar)
{
bar.Add("File", THISBACK(FileBar));
bar.Add("Window", callback(WindowsMenu));
bar.Add("Help", THISBACK(AboutMenu));
}
void UWord::New()
{
new UWord;
}
void UWord::Load(const String& name)
{
lrufile().NewEntry(name);
editor.SetQTF(LoadFile(name));
filename = name;
editor.ClearModify();
Title(filename);
}
void UWord::OpenFile(const String& fn)
{
if(filename.IsEmpty() && !editor.IsModified())
Load(fn);
else
(new UWord)->Load(fn);
}
void UWord::Open()
{
FileSel& fs = UWordFs();
if(fs.ExecuteOpen())
OpenFile(fs);
else
statusbar.Temporary("Loading aborted.");
}
void UWord::DragAndDrop(Point, PasteClip& d)
{
if(AcceptFiles(d)) {
Vector<String> fn = GetFiles(d);
for(int i = 0; i < fn.GetCount(); i++)
if(FileExists(fn[i]))
OpenFile(fn[i]);
}
}
void UWord::FrameDragAndDrop(Point p, PasteClip& d)
{
DragAndDrop(p, d);
}
void UWord::Save0()
{
lrufile().NewEntry(filename);
if(filename.IsEmpty())
SaveAs();
else
if(SaveFile(filename, editor.GetQTF())) {
statusbar.Temporary("File " + filename + " was saved.");
ClearModify();
}
else
Exclamation("Error saving the file [* " + DeQtf(filename) + "]!");
}
void UWord::Save()
{
if(!editor.IsModified()) return;
Save0();
}
void UWord::SaveAs()
{
FileSel& fs = UWordFs();
if(fs.ExecuteSaveAs()) {
filename = fs;
Title(filename);
Save0();
}
}
void UWord::Print()
{
editor.Print();
}
void UWord::Pdf()
{
FileSel& fs = PdfFs();
if(!fs.ExecuteSaveAs("Output PDF file"))
return;
Size page = Size(3968, 6074);
PdfDraw pdf;
UPP::Print(pdf, editor.Get(), page);
SaveFile(~fs, pdf.Finish());
}
void UWord::About()
{
PromptOK("[A5 uWord]&Using [*^www://upp.sf.net^ Ultimate`+`+] technology.");
}
void UWord::Destroy()
{
if(editor.IsModified()) {
switch(PromptYesNoCancel("Do you want to save the changes to the document?")) {
case 1:
Save();
break;
case -1:
return;
}
}
delete this;
}
void UWord::MainBar(Bar& bar)
{
FileBar(bar);
bar.Separator();
editor.DefaultBar(bar);
}
void UWord::SetBar()
{
toolbar.Set(THISBACK(MainBar));
}
UWord::UWord()
{
AddFrame(menubar);
AddFrame(TopSeparatorFrame());
AddFrame(toolbar);
AddFrame(statusbar);
Add(editor.SizePos());
menubar.Set(THISBACK(MainMenu));
Sizeable().Zoomable();
WhenClose = THISBACK(Destroy);
menubar.WhenHelp = toolbar.WhenHelp = statusbar;
static int doc;
Title(Format("Document%d", ++doc));
Icon(CtrlImg::File());
editor.ClearModify();
editor <<= THISBACK(SetBar);
SetBar();
editor.WhenRefreshBar = THISBACK(SetBar);
OpenMain();
ActiveFocus(editor);
}
void UWord::SerializeApp(Stream& s)
{
int version = 1;
s / version;
s % UWordFs()
% PdfFs();
if(version >= 1)
s % lrufile();
}
GUI_APP_MAIN
{
SetLanguage(LNG_ENGLISH);
SetDefaultCharset(CHARSET_UTF8);
InstallBlueBar();
UWordFs().Type("QTF files", "*.qtf")
.AllFilesType()
.DefaultExt("qtf");
PdfFs().Type("PDF files", "*.pdf")
.AllFilesType()
.DefaultExt("pdf");
LoadFromFile(callback(UWord::SerializeApp));
new UWord;
Ctrl::EventLoop();
StoreToFile(callback(UWord::SerializeApp));
}

View file

@ -0,0 +1,18 @@
IMAGE_BEGIN(pdf)
IMAGE_SCAN("Č\0\0\0")
IMAGE_SCAN("Ä\1\0\0\0Š\0\0\377\1\0\0\0")
IMAGE_SCAN("Ä\1\0\0\0\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\1\0\0\0")
IMAGE_SCAN("Ä\13\0\0\0\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\0\0\377\1\0\0\0")
IMAGE_SCAN("Ä\1\0\0\0\377\377\377\0\0\377\4\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\1\0\0\0")
IMAGE_SCAN("Ä\2\0\0\0\377\377\377ƒ\0\0\377\6\377\377\377\0\0\377\377\377\377\0\0\377\377\377\377\0\0\377\1\0\0\0")
IMAGE_SCAN("Á\1\0\0\0Â\2\0\0\0\377\377\377ƒ\0\0\377\377\377\377\0\0\377\2\377\377\377\0\0\377\1\0\0\0")
IMAGE_SCAN("Á‚\0\0\0Á\1\0\0\0Š\0\0\377\1\0\0\0")
IMAGE_SCAN("Áƒ\0\0\0Á\0\0\0")
IMAGE_SCAN("…\0\0\0Á‰\377\377\377\1\0\0\0")
IMAGE_SCAN("Áƒ\0\0\0ÁŠ\377\377\377\1\0\0\0")
IMAGE_SCAN("Á‚\0\0\0Š\377\377\377\1\0\0\0")
IMAGE_SCAN("Á\1\0\0\0Â\1\0\0\0‰\377\377\377\0\0\0")
IMAGE_SCAN("Ä\1\0\0\0ˆ\377\377\377\2\0\0\0€€€\1\0\0\0")
IMAGE_SCAN("Ä\1\0\0\0‡\377\377\377\1\0\0\0€€€\1\0\0\0")
IMAGE_SCAN("Č\0\0\0")
IMAGE_PACKED(pdf, "\2\20\0\0\0\20\0\0\0\0\0\0\0\377\377\377\377\0\0\0\0")

7
examples/BlueBar/init Normal file
View file

@ -0,0 +1,7 @@
#ifndef _BlueBar_icpp_init_stub
#define _BlueBar_icpp_init_stub
#include "CtrlLib/init"
#include "RichEdit/init"
#include "PdfDraw/init"
#include "art\BlueBar/init"
#endif

5
examples/DbfView/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _DbfView_icpp_init_stub
#define _DbfView_icpp_init_stub
#include "plugin\dbf/init"
#include "CtrlLib/init"
#endif

6
examples/OleCalc/init Normal file
View file

@ -0,0 +1,6 @@
#ifndef _OleCalc_icpp_init_stub
#define _OleCalc_icpp_init_stub
#include "Ole\Ctrl/init"
#include "CtrlLib/init"
#include "Esc/init"
#endif

4
examples/idmapBench/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _idmapBench_icpp_init_stub
#define _idmapBench_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,15 @@
description "Example of editing SQL table using SqlArray";
uses
CtrlLib,
plugin/sqlite3,
SqlCtrl;
file
app.lay,
db.sch,
main.cpp;
mainconfig
"" = "GUI";

View file

@ -0,0 +1,9 @@
LAYOUT(AppLayout, 652, 200)
ITEM(SqlArray, master, LeftPosZ(4, 308).TopPosZ(4, 188))
ITEM(SqlArray, detail, LeftPosZ(316, 128).TopPosZ(4, 188))
ITEM(Label, dv___2, SetLabel(t_("Borrowed")).LeftPosZ(452, 56).TopPosZ(4, 20))
ITEM(EditString, borrowed, LeftPosZ(512, 108).TopPosZ(4, 19))
ITEM(Label, dv___4, SetLabel(t_("Returned")).LeftPosZ(452, 56).TopPosZ(28, 20))
ITEM(EditString, returned, LeftPosZ(512, 108).TopPosZ(28, 19))
END_LAYOUT

13
reference/SqlArray/db.sch Normal file
View file

@ -0,0 +1,13 @@
TABLE_(BOOK)
INT_ (ID) PRIMARY_KEY AUTO_INCREMENT
STRING_ (AUTHOR, 2000)
STRING_ (TITLE, 2000)
END_TABLE
TABLE_(BORROW_RECORD)
INT (ID) PRIMARY_KEY AUTO_INCREMENT
INT_ (BOOK_ID) REFERENCES(BOOK)
STRING_ (PERSON, 2000) INDEX
STRING_ (BORROWED, 200) INDEX
STRING_ (RETURNED, 200) INDEX
END_TABLE

6
reference/SqlArray/init Normal file
View file

@ -0,0 +1,6 @@
#ifndef _SqlArray_icpp_init_stub
#define _SqlArray_icpp_init_stub
#include "CtrlLib/init"
#include "plugin/sqlite3/init"
#include "SqlCtrl/init"
#endif

View file

@ -0,0 +1,70 @@
#include <SqlCtrl/SqlCtrl.h>
#include <plugin/sqlite3/Sqlite3.h>
using namespace Upp;
#define MODEL <SQLArray/db.sch>
#define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>
#include "Sql/sch_header.h"
#define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>
#include "Sql/sch_source.h"
#define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>
#include "Sql/sch_schema.h"
#define LAYOUTFILE <SqlArray/app.lay>
#include <CtrlCore/lay.h>
struct App : public WithAppLayout<TopWindow> {
EditString author;
EditString title;
EditString person;
App() {
CtrlLayout(*this, "SqlArray SQL table editing example");
master.SetTable(BOOK);
master.AddKey(ID);
master.AddColumn(AUTHOR, "Author").Edit(author);
master.AddColumn(TITLE, "Title").Edit(title);
master.Appending().Removing();
master.SetOrderBy(AUTHOR, TITLE);
detail.SetTable(BORROW_RECORD);
detail.AddKey(ID);
detail.Join(BOOK_ID, master);
detail.AddColumn(PERSON, "Borrowed by").Edit(person);
detail.AddCtrl(BORROWED, borrowed);
detail.AddCtrl(RETURNED, returned);
detail.Appending().Removing();
detail.SetOrderBy(PERSON);
master.Query();
}
};
GUI_APP_MAIN
{
Sqlite3Session sqlite3;
if(!sqlite3.Open(ConfigFile("simple.db"))) {
Exclamation("Can't create or open database file\n");
return;
}
SQL = sqlite3;
SqlSchema sch(SQLITE3);
sqlite3.SetTrace();
All_Tables(sch);
if(sch.ScriptChanged(SqlSchema::UPGRADE))
Sqlite3PerformScript(sch.Upgrade());
if(sch.ScriptChanged(SqlSchema::ATTRIBUTES))
Sqlite3PerformScript(sch.Attributes());
if(sch.ScriptChanged(SqlSchema::CONFIG)) {
Sqlite3PerformScript(sch.ConfigDrop());
Sqlite3PerformScript(sch.Config());
}
sqlite3.SetTrace();
App().Run();
}

141
reference/SqlExp/SqlExp.cpp Normal file
View file

@ -0,0 +1,141 @@
#include <RichText/RichText.h>
#include <Sql/Sql.h>
using namespace Upp;
#ifdef flagQTF
#define GENERATE_QTF
#endif
#define SQLID(x) SqlId x(#x)
SQLID(COLUMN);
SQLID(COLUMN1);
SQLID(COLUMN2);
SQLID(TABLE);
SQLID(TABLE1);
SQLID(TABLE2);
SQLID(SEQ);
SQLID(A);
#define EXP(s) Exp(#s, s)
#ifdef GENERATE_QTF
String qtf;
void Put(String s, const char *splits)
{
Vector<String> split = Split(splits, ';');
bool was = false;
for(int i = 0; i < split.GetCount(); i++) {
int q = s.Find(split[i]);
if(q >= 0) {
if(was)
qtf << "&\n";
qtf << DeQtf(s.Mid(0, q));
s = s.Mid(q);
was = true;
}
}
if(was)
qtf << "&\n";
qtf << DeQtf(s);
}
void Exp(const char *s, SqlStatement sql)
{
qtf << "\n:: ";
Put(s, ".From;.Where;.OrderBy");
qtf << "\n:: ";
Put(sql.Get(PGSQL), " from; where; order by");
}
#else
void Exp(const char *s, SqlStatement sql)
{
LOG(s);
LOG('\t' << sql.Get(PGSQL));
}
#endif
CONSOLE_APP_MAIN
{
#ifdef GENERATE_QTF
qtf << "[C1 {{1:1 SqlExp C`+`+:: PostgreSQL";
#else
StdLogSetup(LOG_FILE|LOG_COUT);
#endif
EXP(Select(COLUMN).From(TABLE));
EXP(Select(COLUMN.Of(TABLE)).From(TABLE));
EXP(Select(COLUMN.As(A)).From(TABLE));
EXP(Select(COLUMN&A).From(TABLE));
EXP(Select(COLUMN[3]).From(TABLE));
EXP(Select(COLUMN1 % COLUMN2).From(TABLE));
EXP(Select(COLUMN1 | COLUMN2).From(TABLE));
EXP(Select(SqlFunc("any_fn", COLUMN, 2)).From(TABLE));
EXP(Select(Distinct(COLUMN)).From(TABLE));
EXP(Select(Distinct(SqlSet(COLUMN1, COLUMN2))).From(TABLE));
EXP(Select(All(COLUMN)).From(TABLE));
EXP(Select(Count(COLUMN)).From(TABLE));
EXP(Select(SqlAll()).From(TABLE));
EXP(Select(SqlCountRows()).From(TABLE));
EXP(Select(COLUMN).From(TABLE).OrderBy(Descending(COLUMN)));
EXP(Select(SqlMax(COLUMN)).From(TABLE));
EXP(Select(SqlMin(COLUMN)).From(TABLE));
EXP(Select(SqlSum(COLUMN)).From(TABLE));
EXP(Select(Avg(COLUMN)).From(TABLE));
EXP(Select(Stddev(COLUMN)).From(TABLE));
EXP(Select(Variance(COLUMN)).From(TABLE));
EXP(Select(Greatest(COLUMN1, COLUMN2)).From(TABLE));
EXP(Select(Least(COLUMN1, COLUMN2)).From(TABLE));
EXP(Select(Upper(COLUMN)).From(TABLE));
EXP(Select(Lower(COLUMN)).From(TABLE));
EXP(Select(Substr(COLUMN, 1)).From(TABLE));
EXP(Select(Substr(COLUMN, 2, 1)).From(TABLE));
EXP(Select(Instr(COLUMN, "hello")).From(TABLE));
EXP(Select(SqlNvl(COLUMN1, COLUMN2)).From(TABLE));
EXP(Select(NextVal(SEQ)).Get());
EXP(Select(CurrVal(SEQ)).Get());
EXP(Select(SqlArg()).From(TABLE));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN / 2 > 1 && COLUMN1 == "A" || COLUMN2 == Date(2006, 1, 1)));
EXP(Select(COLUMN).From(TABLE).Where(!(COLUMN == 1)));
EXP(Select(COLUMN).From(TABLE).Where((COLUMN1 == 1) - (COLUMN2 == 1)));
EXP(Select(COLUMN).From(TABLE).Where(IsNull(COLUMN1)));
EXP(Select(COLUMN).From(TABLE).Where(NotNull(COLUMN1)));
EXP(Select(COLUMN).From(TABLE).Where(Like(COLUMN1, Wild("A*"))));
EXP(Select(COLUMN).From(TABLE).Where(NotLike(COLUMN1, Wild("A*"))));
EXP(Select(COLUMN).From(TABLE).Where(In(COLUMN, Select(COLUMN).From(TABLE1))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN == Select(COLUMN).From(TABLE1)));
EXP(Select(COLUMN).From(TABLE).Where(NotIn(COLUMN, Select(COLUMN).From(TABLE1))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN != Select(COLUMN).From(TABLE1)));
EXP(Select(COLUMN).From(TABLE).Where(Exists(Select(COLUMN).From(TABLE1))));
EXP(Select(COLUMN).From(TABLE).Where(NotExists(Select(COLUMN).From(TABLE1))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN == (Select(COLUMN1).From(TABLE1) | Select(COLUMN2).From(TABLE2))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN == (Select(COLUMN1).From(TABLE1) & Select(COLUMN2).From(TABLE2))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN == (Select(COLUMN1).From(TABLE1) - Select(COLUMN2).From(TABLE2))));
EXP(Select(COLUMN).From(TABLE).Where(COLUMN == 0).GroupBy(COLUMN).Having(COLUMN == 0).OrderBy(Descending(COLUMN)));
EXP(Select(COLUMN).From(TABLE).Limit(100));
EXP(Select(COLUMN).From(TABLE).Limit(100, 10));
EXP(Select(COLUMN).From(TABLE).Offset(20));
EXP(Select(25 * 34).Get());
EXP(Select(COLUMN).From(TABLE).Hint("hint"));
EXP(Select(COLUMN).From(TABLE).InnerJoin(TABLE1).On(COLUMN.Of(TABLE) == COLUMN1.Of(TABLE1)));
EXP(Select(COLUMN).From(TABLE).LeftJoin(TABLE1).On(COLUMN.Of(TABLE) == COLUMN1.Of(TABLE1)));
EXP(Select(COLUMN).From(TABLE).RightJoin(TABLE1).On(COLUMN.Of(TABLE) == COLUMN1.Of(TABLE1)));
EXP(Select(COLUMN).From(TABLE).FullJoin(TABLE1).On(COLUMN.Of(TABLE) == COLUMN1.Of(TABLE1)));
EXP(Delete(TABLE).Where(COLUMN < 0));
EXP(Insert(TABLE)(COLUMN1, 12)(COLUMN2, "hello")(COLUMN, Date(2007, 1, 1)));
EXP(Insert(TABLE)(COLUMN1, 12)(COLUMN2)(COLUMN).From(TABLE1).Where(COLUMN >= 0));
EXP(Update(TABLE)(COLUMN1, 13)(COLUMN2, "world").Where(COLUMN > Date(2007, 1, 1)));
#ifdef GENERATE_QTF
qtf << "}}";
ParseQTF(qtf);
SaveFile(ConfigFile("sqlexp.qtf"), qtf);
#endif
}

View file

@ -0,0 +1,14 @@
description "Examples of SqlExp expressions";
uses
Core,
Sql,
RichText;
file
SqlExp.cpp;
mainconfig
"" = "",
"" = "QTF";

6
reference/SqlExp/init Normal file
View file

@ -0,0 +1,6 @@
#ifndef _SqlExp_icpp_init_stub
#define _SqlExp_icpp_init_stub
#include "Core/init"
#include "Sql/init"
#include "RichText/init"
#endif

View file

@ -0,0 +1,129 @@
#include <CppBase/CppBase.h>
#include "Analyse.h"
static bool ContainsAt(const String &source, const String &pattern, int pos = 0)
{
return pos >= 0
&& pos + pattern.GetLength() <= source.GetLength()
&& 0 == memcmp(source.Begin() + pos, pattern.Begin(), pattern.GetLength());
}
static bool StartsWith(const String &source, const String &pattern)
{
return ContainsAt(source, pattern, 0);
}
static bool EndsWith(const String &source, const String &pattern)
{
return ContainsAt(source, pattern, source.GetLength() - pattern.GetLength());
}
static String InsertNestingToSignature(String natural, String nesting)
{
if(StartsWith(nesting, "::"))
nesting.Remove(0, 2);
if(nesting.GetCount() && !EndsWith(nesting, "::"))
nesting << "::";
int pos = natural.Find('('); // find the first opening parenthesis
pos--;
while(pos >= 0 && !iscid(natural[pos])) // skip over non-id chars before paren.
pos--;
if(pos < 0) return "";
while(pos >= 0 && iscid(natural[pos])) // skip over last id before paren
pos--;
if(pos >= 0 && '~' == natural[pos]) --pos;
natural.Insert(pos+1, nesting);
return natural;
}
static int BodyPos(const Vector<CppPos> &pos)
{
for(int i = 0; i < pos.GetCount(); i++)
if(pos[i].impl)
return pos[i].line;
return 0;
}
void CodeMetric::Metric::add(int value)
{
sum += value;
maximum = max(value, maximum);
}
CodeMetric::CodeMetric(const String &fileContent) :
orphanLines(0), blankLines(0), commentLines(0)
{
StringStream stream(fileContent);
CppBase base;
Parser parser;
parser.whenFnEnd = THISBACK(StoreMetric);
parser.dobody = true;
parser.Do(stream, Vector<String>(), base, "file", THISBACK(StoreError));
const SrcFile &srcFile = parser.getPreprocessedFile();
commentLines = srcFile.commentLinesRemoved;
blankLines = srcFile.blankLinesRemoved;
orphanLines = parser.symbolsOutsideFunctions.GetStat(';');
totalLLOC = orphanLines + srcFile.preprocessorLinesRemoved;
for(int i = 0; i < functions.GetCount(); i++)
{
lloc.add(functions[i].logicalLinesOfCode);
cc1.add(functions[i].cyclomaticComplexity1);
cc2.add(functions[i].cyclomaticComplexity2);
depth.add(functions[i].scopeDepth);
}
totalLLOC += lloc.sum;
}
String CodeMetric::ToString() const
{
String s;
s << "LLOC: " << totalLLOC
<< ", Blank: " << blankLines
<< ", Comments: " << commentLines;
if(errors != "")
s << "\nErrors:\n" << errors;
return s;
}
void CodeMetric::StoreError(int line, const String &msg)
{
errors << "line " << line << ": " << msg << "\n";
}
int CodeMetric::LogicalLinesOfCode(const LexSymbolStat &symbolStat)
{
static Vector<int> oneLiners(
Vector<int>() << tk_if << tk_else << tk_switch << tk_case
<< tk_for << tk_do << tk_while << tk_try << tk_catch
<< tk_struct << tk_class << tk_namespace
<< tk_public << tk_private << tk_protected
<< ';');
return symbolStat.SumStat( oneLiners );
}
void CodeMetric::StoreMetric(const Parser::FunctionStat & functionStat)
{
static Vector<int> cc1_symbols(
Vector<int>() << tk_if << tk_case << tk_for << tk_while << tk_catch);
static Vector<int> cc2_symbols(
Vector<int>() << t_and << t_or << '?');
FunctionEntry &entry = functions.Add();
entry.pos = BodyPos(functionStat.cppItem.pos);
entry.name = InsertNestingToSignature(functionStat.cppItem.natural,
functionStat.nesting);
int cc1 = 1 + functionStat.symbolStat.SumStat( cc1_symbols );
entry.cyclomaticComplexity1 = cc1;
entry.cyclomaticComplexity2 = cc1 + functionStat.symbolStat.SumStat( cc2_symbols );
entry.logicalLinesOfCode = 2 + LogicalLinesOfCode(functionStat.symbolStat);
entry.scopeDepth = functionStat.maxScopeDepth;
}

View file

@ -0,0 +1,41 @@
#ifndef _CppAnalyse_Analyze_h_
#define _CppAnalyse_Analyze_h_
#include <CppBase/CppBase.h>
struct CodeMetric
{
public:
struct FunctionEntry : public Moveable<FunctionEntry>
{
String name;
int pos;
int cyclomaticComplexity1;
int cyclomaticComplexity2;
int logicalLinesOfCode;
int scopeDepth;
};
struct Metric
{
int sum, maximum;
Metric() : sum(0), maximum(0) {}
void add(int value);
};
int orphanLines, blankLines, commentLines, totalLLOC;
Metric cc1, cc2, depth, lloc;
Vector<FunctionEntry> functions;
String errors;
explicit CodeMetric(const String &fileContent);
String ToString() const;
private:
typedef CodeMetric CLASSNAME;
void StoreError(int line, const String &msg);
void StoreMetric(const Parser::FunctionStat & functionStat);
int LogicalLinesOfCode(const LexSymbolStat &symbolStat);
};
#endif

View file

@ -0,0 +1,34 @@
#ifndef _CppAnalyse_AnalyseGui_h
#define _CppAnalyse_AnalyseGui_h
#include <CtrlLib/CtrlLib.h>
class WarningDisplay : public Display
{
int limit;
Color warningColor;
public:
WarningDisplay(int limit, Color warningColor = Color(255, 128, 128));
void PaintBackground(Draw& w, const Rect& r, const Value& q,
Color ink, Color paper, dword style) const;
};
class AnalyseGui : public TopWindow
{
public:
typedef AnalyseGui CLASSNAME;
MenuBar menu;
Splitter splitter;
LineEdit source;
ArrayCtrl chart;
LineEdit textMetric;
WarningDisplay ccDisplay, llocDisplay, depthDisplay;
AnalyseGui();
void MainMenu(Bar& menu);
void Open();
void UpdateMetric();
void GotoFunction();
};
#endif

View file

@ -0,0 +1,18 @@
IMAGE_BEGIN(GaugeIcon)
IMAGE_SCAN("Æ„\377\377\377")
IMAGE_SCAN("Ä‚\377\377\377„\0\0\0\377\377\377")
IMAGE_SCAN("Ã\1\377\377\377\0\0\0\2\377\377\377\0\0\0\377\377\377\0\0\0\1\377\377\377")
IMAGE_SCAN("Â\3\377\377\377\0\0\377€€€\377\377\377\1\0\0\0ƒ\377\377\377\3€€€\0\0\0\377\377\377")
IMAGE_SCAN("Á\2\377\377\377\0\0\0\0\0\377\1\377„\377\377\377\5ÀÀÀ\0\0\0€€€\0\0\0\377\377\377")
IMAGE_SCAN("Á\3\377\377\377\0\0\0\377\377\377\0\0\377\1\377ƒ\377\377\377\5\0\0\0ÀÀÀ\377\377\377\0\0\0\377\377\377")
IMAGE_SCAN("\2\377\377\377\0\0\0\377\377\377\1\377\0\0\377\1\377†\377\377\377\2\0\0\0\377\377\377")
IMAGE_SCAN("\2\377\377\377\0\0\0ƒ\377\377\377\1\377\0\0\377\1\0\0\0…\377\377\377\2\0\0\0\377\377\377")
IMAGE_SCAN("\1\377\377\377ƒ\0\0\0\377\377\377\3\377\0\0\377\0\0\0ƒ\377\377\377ƒ\0\0\0\1\377\377\377")
IMAGE_SCAN("\2\377\377\377\0\0\0\0\377\0\1˜\377˜†\377\377\377\1\377\0\0\377\2\0\0\0\377\377\377")
IMAGE_SCAN("Á\2\377\377\377\0\0\0\0\377\0\1˜\377˜„\377\377\377\1\377\0\0\377\2\0\0\0\377\377\377")
IMAGE_SCAN("Á\2\377\377\377\0\0\0ƒ\0\377\0„\377\377\377ƒ\0\0\377\2\0\0\0\377\377\377")
IMAGE_SCAN("Â\4\377\377\377\0\0\0\0\377\0\0\0\0„\377\377\377\4\0\0\0\0\0\377\0\0\0\377\377\377")
IMAGE_SCAN("Ã\3\377\377\377\0\0\0\0\377\0„\377\377\377\3\0\0\377\0\0\0\377\377\377")
IMAGE_SCAN("Ĉ\377\377\377")
IMAGE_SCAN("Æ„\377\377\377")
IMAGE_PACKED(GaugeIcon, "\2\20\0\0\0\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")

View file

@ -0,0 +1,13 @@
uses
CtrlLib,
CppBase;
file
AnalyseGui.h,
Analyse.h,
AnalyseGui.iml,
Analyse.cpp,
main.cpp;
mainconfig
"" = "GUI";

153
uppbox/CodeMetric/main.cpp Normal file
View file

@ -0,0 +1,153 @@
#include "AnalyseGui.h"
#include "Analyse.h"
#define IMAGECLASS Images
#define IMAGEFILE <CodeMetric/AnalyseGui.iml>
#include <Draw/iml.h>
String defaultCode =
"/*"
" This tool measures certain source code metrics.\n"
" You can type, paste, or load the code you would like measure into this text area.\n"
" Metrics provided are:\n"
" - Cyclomatic complexity 1: counts the decision points per method, thus estimating the\n"
" number of testcases needed for each method.\n"
" - Cyclomatic complexity 2: CC1 extended with the implicit decisions created by the\n"
" && || and ?: operators. Evaluation:\n"
" CC2 1-10 simple, low risk method\n"
" CC2 10-20 moderate complexity & risk method\n"
" CC2 21-50 high complexity & risk method\n"
" CC2 >50 too complex, untestable method, should be refactored\n"
" - Depth: measures deepest scope embedding level per method. This estimates the human\n"
" memory needed to keep in mind the current context. Any methods with depth > 5 is\n"
" considered too complex, and candidate for refactoring\n"
" - Logical Lines Of Code: estimates the amount of source code per method in a way\n"
" which is mostly independent from code formatting style. Methods longer than 80 LLOC are\n"
" too long, and should be refactored.\n"
"*/\n"
"int main()\n"
"{\n"
" return 0;\n"
"}\n";
String defaultTitle = "CodeMetric GUI 1.2";
WarningDisplay::WarningDisplay(int limit, Color warningColor) :
limit(limit), warningColor(warningColor)
{
}
void WarningDisplay::PaintBackground(Draw& w, const Rect& r, const Value& q,
Color ink, Color paper, dword style) const
{
double v = atof(q.ToString());
if(v >= limit)
paper = warningColor;
Display::PaintBackground(w, r, q, ink, paper, style);
}
void AnalyseGui::MainMenu(Bar &bar)
{
bar.Add("Load file", THISBACK(Open));
}
void AnalyseGui::Open()
{
FileSelector fsel;
fsel.ExecuteOpen("Select file");
String fileName = fsel.Get();
if(fileName == "")
return;
source <<= LoadFile(fileName);
UpdateMetric();
Title(defaultTitle + " [" + fileName + "]");
}
void AnalyseGui::UpdateMetric()
{
String s = ~source;
CodeMetric metric(s);
int functionCount = metric.functions.GetCount();
chart.Clear();
if(functionCount)
{
double llocAvg = (double)metric.lloc.sum / functionCount,
cc1Avg = (double)metric.cc1.sum / functionCount,
cc2Avg = (double)metric.cc2.sum / functionCount,
depthAvg = (double)metric.depth.sum / functionCount;
chart.Add( "Average",
"",
Format("%.2f",cc1Avg),
Format("%.2f",cc2Avg),
Format("%.2f",llocAvg),
Format("%.2f",depthAvg));
chart.Add( "Maximum",
"",
metric.cc1.maximum,
metric.cc2.maximum,
metric.lloc.maximum,
metric.depth.maximum);
}
for(int i = 0; i < functionCount; i++)
{
CodeMetric::FunctionEntry & entry =
metric.functions[i];
chart.Add(entry.name,
entry.pos,
entry.cyclomaticComplexity1,
entry.cyclomaticComplexity2,
entry.logicalLinesOfCode,
entry.scopeDepth);
}
textMetric.SetData(metric.ToString());
}
void AnalyseGui::GotoFunction()
{
int cursor = chart.GetCursor();
if(cursor >= 0 && cursor < chart.GetCount())
{
int pos = (int)chart.Get(cursor, 1);
source.SetCursor( source.GetPos(pos) );
source.CenterCursor();
}
}
AnalyseGui::AnalyseGui() :
ccDisplay(50), llocDisplay(80), depthDisplay(5)
{
Title(defaultTitle);
Icon(Images::GaugeIcon);
AddFrame(menu);
menu.Set( THISBACK(MainMenu) );
source <<= THISBACK(UpdateMetric);
source <<= defaultCode;
textMetric.SetEditable(false);
chart.AddColumn("Function", 80);
chart.AddColumn("Pos", 15);
chart.AddColumn("CC1", 15).SetDisplay(ccDisplay);
chart.AddColumn("CC2", 15).SetDisplay(ccDisplay);
chart.AddColumn("LLOC", 15).SetDisplay(llocDisplay);
chart.AddColumn("Depth", 15).SetDisplay(depthDisplay);
chart.WhenLeftDouble = THISBACK(GotoFunction);
chart.OddRowColor(Color(240, 240, 190));
UpdateMetric();
splitter.Vert() << source << chart << textMetric;
splitter.SetPos(9000, 1);
splitter.SetPos(6500, 0);
Add(splitter.SizePos());
Sizeable().Zoomable();
}
GUI_APP_MAIN
{
AnalyseGui().Run();
}

2
uppbox/CppBase2/AUTHORS Normal file
View file

@ -0,0 +1,2 @@
Mirek Fidler <cxl@ntllib.org>
Tomas Rylek <rylek@volny.cz>

397
uppbox/CppBase2/Base.cpp Normal file
View file

@ -0,0 +1,397 @@
#include "CppBase.h"
#ifdef _MSC_VER
#pragma inline_depth(255)
#pragma optimize("t", on)
#endif
#define LLOG(x)
#define LTIMING(x) // RTIMING(x)
void CppWordsHash::AddWord(const String& s)
{
int i = GetHashValue(s) & 127;
w[i >> 5] |= 1 << (i & 31);
}
void CppWordsHash::AddWords(const char *s)
{
CParser p(s);
while(p)
if(p.IsId())
AddWord(p.ReadId());
else
p.SkipTerm();
}
CppWordsHash AllCppWords()
{
CppWordsHash h;
h.SetAll();
return h;
}
CppItem& CppNest::GetAdd(const String& _key, const String& _name)
{
int i = key.Find(_key);
if(i < 0) {
key.Add(_key);
name.Add(_name);
return item.Add();
}
return item[i];
}
bool CppBase::IsType(int i) const
{
return GetKey(i) != "::";
}
Nestfo::Nestfo(const CppBase& base, int nesti)
: base(base), nesti(nesti)
{
Init();
}
Nestfo::Nestfo(int nesti, const CppBase& base)
: base(base), nesti(nesti)
{
Init();
}
Nestfo::Nestfo(const CppBase& base, const String& nest)
: base(base), nesti(base.Find(nest))
{
Init();
}
Nestfo::Nestfo(const Nestfo& f)
: base(f.base)
{
nests <<= f.nests;
bvalid = nvalid = false;
nesti = f.nesti;
}
void Nestfo::Init()
{
bvalid = nvalid = false;
}
void Nestfo::Bases(int i, Vector<int>& g)
{
LTIMING("GetBases");
if(base.IsType(i)) {
const CppNest& n = base.nest[i];
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& im = n[i];
if(im.IsType()) {
const char *q = im.qptype;
const char *b = q;
for(;;) {
if(*q == ';' || *q == '\0') {
if(b < q) {
int nq = base.Find(String(b, q));
if(nq >= 0)
g.Add(nq);
}
if(*q == '\0')
return;
q++;
b = q;
}
else
q++;
}
}
}
}
}
const Vector<String>& Nestfo::GetBases()
{
if(!bvalid) {
bvalid = true;
baselist.Clear();
if(nesti < 0)
return baselist;
Vector<int> b;
Index<int> bi;
Bases(nesti, b);
while(b.GetCount()) {
Vector<int> bb;
for(int i = 0; i < b.GetCount(); i++) {
int q = b[i];
if(bi.Find(q) < 0) {
bi.Add(q);
Bases(b[i], bb);
}
}
b = bb;
}
for(int i = 0; i < bi.GetCount(); i++)
baselist.Add(base.GetKey(bi[i]) + "::");
}
return baselist;
}
const Vector<String>& Nestfo::GetNests()
{
if(!nvalid) {
nvalid = true;
nests.Clear();
if(nesti < 0)
return nests;
String nn = base.GetKey(nesti);
while(nn.GetCount()) {
if(nn[0] == ':' && nn.GetCount() == 2) {
nests.Add(nn);
return nests;
}
nests.Add(nn + "::");
int q = nn.ReverseFind(':');
nn.Trim(max(0, q - 1));
}
nests.Add("::");
}
return nests;
}
String Qualify0(Nestfo& nf, const String& type)
{
if(IsNull(type) || type == "const" ||
type == "int" || type == "double" || type == "long" || type == "char" || type == "void")
return type;
const Vector<String>& nd = nf.GetNests();
if(type[0] == ':') {
if(nf.base.Find(type) >= 0)
return type;
}
else
if(nd.GetCount()) {
LTIMING("First test");
String qt = nd[0] + type;
if(nf.base.Find(qt) >= 0)
return qt;
}
if(nf.GetNest() >= 0) {
int q = type.ReverseFind(':');
if(q >= 0) {
LTIMING("Qualifying qualification");
Nestfo hnf(nf);
hnf.NoBases();
String qn = Qualify(hnf, type.Mid(0, max(q - 1, 0)));
if(qn[0] != ':')
return type;
int nesti = nf.base.Find(qn);
if(nesti < 0)
return type;
String tp = type.Mid(q + 1);
Nestfo nnf(nf.base, nesti);
const Vector<String>& bs = nnf.GetBases();
for(int i = 0; i < bs.GetCount(); i++) {
String qt = bs[i] + tp;
if(nf.base.Find(qt) >= 0)
return qt;
}
}
else {
const Vector<String>& bs = nf.GetBases();
for(int i = 0; i < bs.GetCount(); i++) {
String qt = bs[i] + type;
if(nf.base.Find(qt) >= 0)
return qt;
}
}
}
if(type[0] != ':') {
LTIMING("Testing nests");
for(int i = 1; i < nd.GetCount(); i++) {
String qt = nd[i] + type;
if(nf.base.Find(qt) >= 0)
return qt;
}
}
return type;
}
String Qualify(Nestfo& nf, const String& type)
{
int q = nf.cache.Find(type);
if(q >= 0)
return nf.cache[q];
String x = Qualify0(nf, type);
nf.cache.Add(type, x);
return x;
}
String QualifyIds(Nestfo& nf, const String& k, CppWordsHash& w)
{
String r;
CParser p(k);
Vector<String> empty;
while(p) {
if(p.IsChar2(':', ':')) {
String t;
while(p.Char2(':', ':')) {
t << "::";
if(p.IsId()) {
String id = p.ReadId();
w.AddWord(id);
t << id;
}
}
Nestfo nnf(nf.GetNest(), nf.base);
t = Qualify(nnf, t);
if(iscid(*r.Last()) && iscid(*t))
r << ' ';
r << t;
}
else
if(p.IsId()) {
String t = p.ReadId();
w.AddWord(t);
while(p.Char2(':', ':')) {
t << "::";
if(p.IsId()) {
String id = p.ReadId();
w.AddWord(id);
t << id;
}
}
t = Qualify(nf, t);
if(iscid(*r.Last()) && iscid(*t))
r << ' ';
r << t;
}
else {
int c = p.GetChar();
r.Cat(c);
p.Spaces();
}
}
return r;
}
String Qualify(const CppBase& base, const String& nest, const String& type)
{
CppWordsHash dummy;
Nestfo nf(base, nest);
return QualifyIds(nf, type, dummy);
}
String QualifyKey(const CppBase& base, const String& nest, const String& type)
{
CppWordsHash dummy;
Nestfo nf(base, nest);
return QualifyIds(nf, type, dummy);
}
void QualifyTypes(Nestfo& nf, CppItem& m)
{
m.qtype = QualifyIds(nf, m.type, m.words);
m.qptype = QualifyIds(nf, m.ptype, m.words);
}
void QualifyTypes(CppBase& base, const String& nest, CppItem& m)
{
Nestfo nf(base, nest);
QualifyTypes(nf, m);
}
void QualifyPass1(CppBase& base, const CppWordsHash& words)
{
LTIMING("Qualify1");
for(int ni = 0; ni < base.GetCount(); ni++) {
CppNest& n = base[ni];
Nestfo nf(base, ni);
for(int i = 0; i < n.GetCount(); i++) {
CppItem& m = n.item[i];
if((m.words.IsAll() || (m.words & words)) && m.IsType()) {
m.words.Clear();
QualifyTypes(nf, m);
}
}
}
}
void QualifyPass2(CppBase& base, const CppWordsHash& words)
{
LTIMING("Qualify2");
for(int ni = 0; ni < base.GetCount(); ni++) {
CppNest& n = base[ni];
Nestfo nf(base, ni);
Index<int> rem;
for(int i = 0; i < n.GetCount(); i++) {
CppItem& m = n.item[i];
if((m.words.IsAll() || (words & m.words)) && !m.IsType()) {
m.words.Clear();
QualifyTypes(nf, m);
if(m.IsCode()) {
String k = n.key[i];
String r = QualifyIds(nf, m.key, m.words);
if(k != r) {
int q = n.key.Find(r);
if(q >= 0 && q != i)
if(m.decla) {
m.pos.Append(n.item[q].pos);
rem.FindAdd(q);
n.key.Set(i, r);
}
else {
n.item[q].pos.Append(m.pos);
rem.FindAdd(i);
}
else
n.key.Set(i, r);
}
}
}
}
Vector<int> rm = rem.PickKeys();
Sort(rm);
n.Remove(rm);
}
}
void Qualify(CppBase& base, const CppWordsHash& words)
{
LTIMING("Qualify");
QualifyPass1(base, words);
QualifyPass2(base, words);
}
void Remove(CppBase& base, const Vector<String>& pf)
{
int ni = 0;
Vector<int> file;
for(int i = 0; i < pf.GetCount(); i++)
file.Add(GetCppFileIndex(pf[i]));
while(ni < base.GetCount()) {
CppNest& n = base[ni];
Vector<int> nr;
for(int mi = 0; mi < n.GetCount(); mi++) {
CppItem& m = n.item[mi];
int i = 0;
while(i < m.pos.GetCount())
if(FindIndex(file, m.pos[i].file) >= 0)
m.pos.Remove(i);
else
i++;
if(m.pos.GetCount() == 0)
nr.Add(mi);
}
n.Remove(nr);
if(n.GetCount() == 0)
base.nest.Remove(ni);
else
ni++;
}
}
void CppItem::Serialize(Stream& s)
{
s % kind % access;
s % natural % at % tparam % param % pname % tname % type % ptype % virt % key;
}

30
uppbox/CppBase2/COPYING Normal file
View file

@ -0,0 +1,30 @@
Copyright (C) 2005 Mirek Fidler, Tomas Rylek and various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies of the Software and its Copyright notices. In addition publicly
documented acknowledgment must be given that this software has been used if no
source code of this software is made available publicly. This includes
acknowledgments in either Copyright notices, Manuals, Publicity and Marketing
documents or any documentation provided with any product containing this
software. This License does not apply to any software that links to the
libraries provided by this software (statically or dynamically), but only to
the software provided.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------
Please see the COPYING.PLAIN for a plain-english explanation of this notice
and it's intent.

View file

@ -0,0 +1,33 @@
Plain English Copyright Notice
This file is not intended to be the actual License. The reason this file
exists is that we here are programmers and engineers. We aren't lawyers. We
provide licenses that we THINK say the right things, but we have our own
intentions at heart. This is a plain-english explanation of what those
intentions are, and if you follow them you will be within the "spirit" of
the license.
The intent is for us to enjoy writing software that is useful to us (the
AUTHORS) and allow others to use it freely and also benefit from the work we
put into making it. We don't want to restrict others using it. They should
not *HAVE* to make the source code of the applications they write that
simply link to these libraries (be that statically or dynamically), or for
them to be limited as to what license they choose to use (be it open, closed
or anything else). But we would like to know you are using these libraries.
We simply would like to know that it has been useful to someone. This is why
we ask for acknowledgement of some sort.
You can do what you want with the source of this software - it doesn't
matter. We still have it here for ourselves and it is open and free to use
and download and play with. It can't be taken away. We don't really mind what
you do with the source to your software. We would simply like to know that
you are using it - especially if it makes it to a commerical product. If you
simply e-mail all the AUTHORS (see COPYING and AUTHORS files) telling us, and
then make sure you include a paragraph or page in the manual or in the "About.."
box for the product with the copyright notice and state that you used this
software, we will be very happy. If you want to contribute back modifications
and fixes you may have made we will welcome those too with open arms (generally).
If you want help with changes needed, ports needed or features to be added,
arrangements can be easily made with some dialogue.
Mirek Fidler <cxl@ntllib.org>

478
uppbox/CppBase2/CppBase.h Normal file
View file

@ -0,0 +1,478 @@
#ifndef DOCPP_H
#define DOCPP_H
#include <Core/Core.h>
int GetCppFileIndex(const String& path);
const String& GetCppFile(int i);
enum {
Tmarker_before_first = 255,
#define CPPID(x) tk_##x,
#include "keyword.i"
#undef CPPID
};
class CppWordsHash {
dword w[4];
public:
void Clear() { w[0] = w[1] = w[2] = w[3] = 0; }
void SetAll() { w[0] = w[1] = w[2] = w[3] = ~0; }
void AddWord(const String& s);
void AddWords(const char *s);
bool operator&(const CppWordsHash& b) const {
return (w[0] & b.w[0]) | (w[1] & b.w[1]) | (w[2] & b.w[2]) | (w[3] & b.w[3]);
}
bool IsAll() const { return (w[0] & w[1] & w[2] & w[3]) == (dword)~0; }
CppWordsHash() { Clear(); }
};
CppWordsHash AllCppWords();
enum {
t_eof,
t_string = -200,
t_integer,
t_double,
t_character,
t_dblcolon,
t_mulass,
t_divass,
t_modass,
t_xorass,
t_neq,
t_dot_asteriks,
t_elipsis,
t_inc,
t_addass,
t_dec,
t_arrow_asteriks,
t_arrow,
t_subass,
t_and,
t_andass,
t_or,
t_orass,
t_eq,
t_shl,
t_shlass,
t_le,
t_shr,
t_shrass,
t_ge,
te_integeroverflow,
te_badcharacter,
te_badstring,
};
const char **CppKeyword();
bool InScList(const char *s, const char *list);
class LexSymbolStat
{
public:
LexSymbolStat();
void Reset(int minSymbol, int maxSymbol);
void IncStat(int symbol);
int GetStat(int symbol) const;
int SumStat(const Vector<int> & symbols) const;
void Merge(const LexSymbolStat & other);
private:
Vector<int> v;
int minSymbol;
};
class Lex {
#ifdef _DEBUG
const char *pp;
#endif
const char *ptr;
const char *pos;
Index<String> id;
Index<int> ignore;
int endkey;
int braceslevel;
int ignore_low, ignore_high;
struct Term : Moveable<Term>{
const char *ptr;
int code;
String text;
double number;
};
bool statsCollected;
LexSymbolStat symbolStat;
BiVector<Term> term;
bool Char(int c) { if(*ptr == c) { ptr++; return true; } else return false; }
void AddCode(int code) { Term& tm = term.AddTail(); tm.code = code; tm.ptr = pos; }
void AssOp(int noass, int ass) { AddCode(Char('=') ? ass : noass); }
void Next();
bool Prepare(int pos);
int GetCharacter();
public:
int Code(int pos = 0);
bool IsId(int pos = 0);
String Id(int pos = 0);
int Int(int pos = 0);
double Double(int pos = 0);
int Chr(int pos = 0);
String Text(int pos = 0);
void Get(int n = 1);
int GetCode() { int q = Code(); Get(); return q; }
String GetId() { String q = Id(); Get(); return q; }
int GetInt() { int q = Int(); Get(); return q; }
double GetDouble() { double q = Double(); Get(); return q; }
int GetChr() { int q = Chr(); Get(); return q; }
String GetText() { String q = Text(); Get(); return q; }
int Id(const String& s) { return id.FindAdd(s) + 256; }
int GetBracesLevel() const { return braceslevel; }
const char *Pos(int pos = 0);
int operator[](int pos) { return Code(pos); }
operator int() { return Code(0); }
void operator++() { Get(); }
void Init(const char *s, const Vector<String>& ignore);
void StartStatCollection();
const LexSymbolStat & FinishStatCollection();
Lex();
};
struct SrcFile {
SrcFile();
String text;
Vector<int> linepos;
int preprocessorLinesRemoved;
int blankLinesRemoved;
int commentLinesRemoved;
};
SrcFile PreProcess(Stream& in);
enum Kind {
STRUCT,
STRUCTTEMPLATE,
TYPEDEF,
CONSTRUCTOR,
DESTRUCTOR,
FUNCTION,
INSTANCEFUNCTION,
CLASSFUNCTION,
FUNCTIONTEMPLATE,
INSTANCEFUNCTIONTEMPLATE,
CLASSFUNCTIONTEMPLATE,
INLINEFRIEND,
VARIABLE,
INSTANCEVARIABLE,
CLASSVARIABLE,
ENUM,
MACRO,
};
inline bool IsCppType(int i)
{
return i >= STRUCT && i <= TYPEDEF;
}
inline bool IsCppCode(int i) {
return i >= CONSTRUCTOR && i <= INLINEFRIEND;
};
inline bool IsCppData(int i) {
return i >= VARIABLE && i <= ENUM;
}
inline bool IsCppMacro(int i) {
return i == MACRO;
}
inline bool IsCppTemplate(int i) {
return i == STRUCTTEMPLATE || i >= FUNCTIONTEMPLATE && i <= CLASSFUNCTIONTEMPLATE;
}
enum {
PUBLIC,
PROTECTED,
PRIVATE,
};
struct CppPos : Moveable<CppPos> {
bool impl;
int line;
int file;
String GetFile() const { return GetCppFile(file); }
// void Serialize(Stream& s) { s % impl % line % file; }
CppPos() { line = 0; impl = false; }
};
struct CppSimpleItem {
String natural;
String type;
String qtype;
String tparam;
String param;
String pname;
String ptype;
String qptype;
String tname;
byte access;
byte kind;
int16 at;
bool virt;
bool decla;
bool IsType() const { return IsCppType(kind); }
bool IsCode() const { return IsCppCode(kind); }
bool IsData() const { return IsCppData(kind); }
bool IsMacro() const { return IsCppMacro(kind); }
bool IsTemplate() const { return IsCppTemplate(kind); }
CppSimpleItem() { decla = false; virt = false; at = 0; }
};
struct CppItem : CppSimpleItem {
Vector<CppPos> pos;
String key;
CppWordsHash words;
void Serialize(Stream& s);
CppItem() { words.SetAll(); }
};
struct CppNest {
int namespacel;
Index<String> key;
Index<String> name;
Array<CppItem> item;
void Remove(const Vector<int>& rm) { key.Remove(rm); name.Remove(rm); item.Remove(rm); }
int GetCount() const { return item.GetCount(); }
const CppItem& operator[](int i) const { return item[i]; }
CppItem& GetAdd(const String& key, const String& name);
CppNest() { namespacel = 0; }
};
struct CppBase {
ArrayMap<String, CppNest> nest;
CppNest& operator[](int i) { return nest[i]; }
int GetCount() const { return nest.GetCount(); }
const String& GetKey(int i) const { return nest.GetKey(i); }
void Clear() { nest.Clear(); }
int Find(const String& s) const { return nest.Find(s); }
CppNest& GetAdd(const String& s) { return nest.GetAdd(s); }
bool IsType(int i) const;
// Vector<int> GetBases(int i) const;
};
class Parser {
struct Context {
int namespacel;
String nesting;
Vector<int> tparam;
Index<int> typenames;
int access;
bool noclass;
void operator<<=(const Context& t);
String Dump() const;
};
struct Decla {
bool s_static:1;
bool s_extern:1;
bool s_register:1;
bool s_auto:1;
bool s_mutable:1;
bool s_explicit:1;
bool s_virtual:1;
String name;
bool function:1;
bool type_def:1;
bool isfriend:1;
bool istemplate:1;
bool istructor:1;
bool isdestructor:1;
bool isptr:1;
bool nofn:1;
String tnames;
String type;
String natural;
Decla();
};
struct Decl : Decla {
Array<Decl> param;
};
struct RecursionCounter
{
int change;
int &count;
RecursionCounter(int &count_i, int change_i = 1) :
count(count_i), change(change_i)
{
count += change;
}
~RecursionCounter() { count -= change; }
};
Context context;
SrcFile file;
Lex lex;
int filei;
bool inbody;
Callback2<int, const String&> err;
int lpos, line;
CppBase *base;
int RPtr();
bool Key(int code);
bool EatBody();
void Cv();
String SimpleType(Decla& d);
void Qualifier();
void ParamList(Decl& d);
void Declarator(Decl& d, const char *p);
void EatInitializers();
Decl Type();
void Vars(Array<Decl>& r, const char *p, bool type_def, bool more);
Array<Decl> Declaration(bool l0 = false, bool more = false);
void Elipsis(Decl& d);
Decl& Finish(Decl& d, const char *p);
bool Nest(const String& tp, const String& tn);
String TemplateParams(String& pnames);
String TemplateParams();
String TemplatePnames();
String Name(String& h);
String Name();
String Constant();
String ReadOper();
int GetLine(const char *pos);
void Line();
void Check(bool b, const char *err);
void CheckKey(int c);
void SetNestCurrent();
void NestBody();
void Do();
CppItem& Item(const String& nesting, const String& item, const String& name, bool impl);
CppItem& Item(const String& nesting, const String& item, const String& name);
CppItem& Fn(const Decl& d, const String& templ, bool body, int kind);
struct Error {};
void ThrowError(const String& e);
void Resume(int bl);
void MatchPars();
bool TryDecl();
void Statement();
void Locals(const String& type);
String Tparam(int& q);
public:
struct FunctionStat
{
FunctionStat(const String & nesting,
const CppItem & cppItem,
const LexSymbolStat &symbolStat,
int maxScopeDepth);
String nesting;
const CppItem & cppItem;
const LexSymbolStat &symbolStat;
int maxScopeDepth;
};
bool IsInBody() const { return inbody; }
typedef Callback1<const FunctionStat &> FnEndCallback;
bool dobody;
String current_nest;
int current_namespacel;
String current_key;
CppItem current;
int currentScopeDepth;
int maxScopeDepth;
VectorMap<String, String> local;
FnEndCallback whenFnEnd;
LexSymbolStat symbolsOutsideFunctions;
const SrcFile &getPreprocessedFile() { return file; }
void Do(Stream& s, const Vector<String>& ignore, CppBase& base, const String& fn,
Callback2<int, const String&> err, const Vector<String>& typenames = Vector<String>());
Parser() : dobody(false) {}
};
String NoTemplatePars(const String& type);
class Nestfo {
bool bvalid, nvalid;
Vector<String> baselist;
Vector<String> nests;
int nesti;
void Bases(int i, Vector<int>& g);
void Init();
public:
const CppBase& base;
VectorMap<String, String> cache;
const Vector<String>& GetBases();
const Vector<String>& GetNests();
int GetNest() const { return nesti; }
void NoBases() { baselist.Clear(); bvalid = true; }
Nestfo(const CppBase& base, int nesti = -1);
Nestfo(int nesti, const CppBase& base);
Nestfo(const CppBase& base, const String& nest);
Nestfo(const Nestfo& f);
};
String Qualify(Nestfo& nf, const String& type);
String Qualify(const CppBase& base, const String& nest, const String& type);
void QualifyTypes(CppBase& base, const String& nest, CppItem& m);
String QualifyKey(const CppBase& base, const String& nest, const String& type);
void Qualify(CppBase& base, const CppWordsHash& words);
void Parse(Stream& s, const Vector<String>& ignore, CppBase& base, const String& fn,
Callback2<int, const String&> err);
void Remove(CppBase& base, const Vector<String>& fn);
#endif

View file

@ -0,0 +1,20 @@
optimize_speed;
uses
Core;
file
CppBase.h,
keyword.i,
Pre.cpp,
cpplex.cpp,
Parser.cpp,
Base.cpp,
perf.txt,
Info readonly separator,
COPYING,
COPYING-PLAIN,
AUTHORS;
mainconfig
"" = "";

1432
uppbox/CppBase2/Parser.cpp Normal file

File diff suppressed because it is too large Load diff

176
uppbox/CppBase2/Pre.cpp Normal file
View file

@ -0,0 +1,176 @@
#include "CppBase.h"
#ifdef _MSC_VER
#pragma inline_depth(255)
#pragma optimize("t", on)
#endif
static Index<String> cpp_file;
int GetCppFileIndex(const String& path)
{
return cpp_file.FindAdd(path);
}
const String& GetCppFile(int i)
{
return cpp_file[i];
}
/*
void CppPos::Serialize(Stream& s)
{
s % impl % line;
String fn = GetCppFile(file);
s % fn;
file = GetCppFileIndex(fn);
}
String SSpaces(const char *txt)
{
StringBuffer r;
while(*txt)
if(*txt == ' ') {
while((byte)*txt <= ' ' && *txt) txt++;
r.Cat(' ');
}
else
r.Cat(*txt++);
return r;
}
*/
void SLPos(SrcFile& res)
{
res.linepos.Add(res.text.GetLength());
}
SrcFile::SrcFile() :
preprocessorLinesRemoved(0),
blankLinesRemoved(0),
commentLinesRemoved(0)
{
}
SrcFile PreProcess(Stream& in)
{
SrcFile res;
bool include = true;
while(!in.IsEof()) {
String ln = in.GetLine();
SLPos(res);
while(*ln.Last() == '\\') {
ln.Trim(ln.GetLength() - 1);
ln.Cat(in.GetLine());
SLPos(res);
}
const char *rm = ln;
while(*rm == ' ' || *rm == '\t') rm++;
if(*rm == '\0')
res.blankLinesRemoved++;
else
if(*rm == '#')
{
if(rm[1] == 'd' && rm[2] == 'e' && rm[3] == 'f' &&
rm[4] == 'i' && rm[5] == 'n' && rm[6] == 'e' && !iscid(rm[7])) {
const char *s = rm + 8;
while(*s == ' ') s++;
String macro;
while(iscid(*s))
macro.Cat(*s++);
if(*s == '(') {
while(*s != ')' && *s)
macro.Cat(*s++);
macro << ')';
}
// res.text << '#' << AsCString(SSpaces(macro));
res.text << '#' << AsCString(macro);
}
res.preprocessorLinesRemoved++;
}
else {
bool lineContainsComment = false;
bool lineContainsNonComment = false;
String cmd;
while(*rm) {
if(*rm == '\"') {
lineContainsNonComment = true;
res.text << '\"';
rm++;
while((byte)*rm && *rm != '\r' && *rm != '\n') {
if(*rm == '\"') {
res.text << '\"';
rm++;
break;
}
if(*rm == '\\' && rm[1]) {
if(include)
res.text.Cat(*rm);
rm++;
}
if(include)
res.text.Cat(*rm);
rm++;
}
}
else
if(*rm == '\\' && rm[1]) {
lineContainsNonComment = true;
if(include) {
res.text.Cat(*rm++);
res.text.Cat(*rm++);
}
else
rm += 2;
}
else
if(rm[0] == '/' && rm[1] == '/') {
cmd = rm + 2;
if(!lineContainsNonComment)
res.commentLinesRemoved++;
break;
}
else
if(rm[0] == '/' && rm[1] == '*') {
lineContainsComment = true;
rm += 2;
for(;;) {
if(*rm == '\0') {
if(!lineContainsNonComment)
res.commentLinesRemoved++;
if(in.IsEof()) break;
SLPos(res);
ln = in.GetLine();
rm = ~ln;
lineContainsNonComment = false;
}
if(rm[0] == '*' && rm[1] == '/') {
rm += 2;
break;
}
rm++;
}
if(include)
res.text.Cat(' ');
}
else {
lineContainsNonComment = true;
if(include)
res.text.Cat(*rm);
rm++;
}
}
if(include)
res.text << ' ';
if(cmd[0] == '$') {
if(cmd[1] == '-') include = false;
if(cmd[1] == '+') include = true;
if(cmd[1]) {
res.text.Cat(~cmd + 2);
res.text.Cat(' ');
}
}
if(lineContainsComment && !lineContainsNonComment)
res.commentLinesRemoved++;
}
}
return res;
}

421
uppbox/CppBase2/cpplex.cpp Normal file
View file

@ -0,0 +1,421 @@
#include "CppBase.h"
#ifdef _MSC_VER
#pragma inline_depth(255)
#pragma optimize("t", on)
#endif
#define case_id \
case '_':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h': \
case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q': \
case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z': \
case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I': \
case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R': \
case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z'
#define case_nonzero_digit \
case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9'
const char *_CppKeyword[] = {
#define CPPID(x) #x,
#include "keyword.i"
#undef CPPID
NULL
};
const char **CppKeyword() { return _CppKeyword; }
LexSymbolStat::LexSymbolStat() :
minSymbol(0)
{
}
void LexSymbolStat::Reset(int minSymbol, int maxSymbol)
{
ASSERT(minSymbol <= maxSymbol);
v.Clear();
this->minSymbol = minSymbol;
v.SetCount(maxSymbol - minSymbol + 1, 0);
}
void LexSymbolStat::IncStat(int symbol)
{
int symbolIndex = symbol - minSymbol;
if(symbolIndex >= 0 && symbolIndex < v.GetCount())
v[symbolIndex]++;
}
int LexSymbolStat::GetStat(int symbol) const
{
int symbolIndex = symbol - minSymbol;
return (symbolIndex >= 0 && symbolIndex < v.GetCount()) ?
v[symbolIndex] :
0;
}
int LexSymbolStat::SumStat(const Vector<int> & symbols) const
{
int sum = 0;
for(int i = 0; i < symbols.GetCount(); i++)
sum += GetStat(symbols[i]);
return sum;
}
void LexSymbolStat::Merge(const LexSymbolStat & other)
{
if(v.GetCount() == 0) {
minSymbol = other.minSymbol;
v <<= other.v;
return;
}
ASSERT(other.minSymbol == minSymbol && other.v.GetCount() == v.GetCount());
for(int i = 0; i < v.GetCount(); i++)
v[i] += other.v[i];
}
Lex::Lex() :
statsCollected(false)
{
const char **cppk = CppKeyword();
for(int i = 0; cppk[i]; i++)
id.Add(cppk[i]);
endkey = id.GetCount();
braceslevel = ignore_low = ignore_high = 0;
}
void Lex::Init(const char *s, const Vector<String>& ig)
{
ptr = s;
ignore_low = id.GetCount();
for(int i = 0; i < ig.GetCount(); i++)
id.Add(ig[i]);
ignore_high = id.GetCount();
}
void Lex::StartStatCollection()
{
symbolStat.Reset(-200, endkey+256);
statsCollected = true;
}
const LexSymbolStat & Lex::FinishStatCollection()
{
statsCollected = false;
return symbolStat;
}
int Lex::GetCharacter()
{
if(*ptr == '\0') return t_eof;
int c = *ptr++;
if(c == '\\') {
c = *ptr++;
switch(c) {
case 'a': return '\a';
case 'b': return '\b';
case 't': return '\t';
case 'v': return '\v';
case 'n': return '\n';
case 'r': return '\r';
case 'f': return '\f';
case 'x':
c = 0;
if(isxdigit(*ptr)) {
c = (*ptr >= 'A' ? ToUpper(*ptr) - 'A' + 10 : *ptr - '0');
ptr++;
if(isxdigit(*ptr)) {
c = 16 * c + (*ptr >= 'A' ? ToUpper(*ptr) - 'A' + 10 : *ptr - '0');
ptr++;
}
}
break;
default:
if(c >= '0' && c <= '7') {
c -= '0';
if(*ptr >= '0' && *ptr <= '7')
c = 8 * c + *ptr++ - '0';
if(*ptr >= '0' && *ptr <= '7')
c = 8 * c + *ptr++ - '0';
}
}
}
return (byte)c;
}
#pragma optimize("t", on)
void Lex::Next()
{
while((byte)*ptr <= ' ') {
if(*ptr == '\0') return;
ptr++;
}
pos = ptr;
int c = (byte)*ptr++;
if(c == '\0') return;
switch(c) {
case_id: {
String x;
x.Reserve(12);
x.Cat(c);
while(iscid(*ptr))
x.Cat(*ptr++);
int q = id.FindAdd(x);
if(q >= ignore_low && q < ignore_high)
while((byte)*ptr <= ' ') {
ptr++;
if(*ptr == '(') {
int level = 1;
while(*ptr && level) {
if(*ptr == '(')
level++;
if(*ptr == ')')
level--;
ptr++;
}
}
}
else
AddCode(q + 256);
break;
}
case ':': AddCode(Char(':') ? t_dblcolon : ':'); break;
case '*': AssOp('*', t_mulass); break;
case '/': AssOp('/', t_divass); break;
case '%': AssOp('%', t_modass); break;
case '^': AssOp('^', t_xorass); break;
case '!': AssOp('!', t_neq); break;
case '.':
if(Char('*')) AddCode(t_dot_asteriks);
else
if(*ptr == '.' && ptr[1] == '.') {
AddCode(t_elipsis);
ptr += 2;
}
else
AddCode('.');
break;
case '+':
if(Char('+')) AddCode(t_inc);
else
AssOp('+', t_addass);
return;
case '-':
if(Char('-')) AddCode(t_dec);
else
if(Char('>'))
AddCode(Char('*') ? t_arrow_asteriks : t_arrow);
else
AssOp('-', t_subass);
break;
case '&':
if(Char('&'))
AddCode(t_and);
else
AssOp('&', t_andass);
break;
case '|':
if(Char('|'))
AddCode(t_or);
else
AssOp('|', t_orass);
break;
case '=':
AssOp('=', t_eq);
break;
case '<':
if(Char('<'))
AssOp(t_shl, t_shlass);
else
AssOp('<', t_le);
break;
case '>':
if(Char('>'))
AssOp(t_shr, t_shrass);
else
AssOp('>', t_ge);
break;
case '0': {
dword w = 0;
if(Char('x') || Char('X')) {
for(;;) {
int d;
if(*ptr >= '0' && *ptr <= '9')
d = *ptr - '0';
else
if(*ptr >= 'A' && *ptr <= 'F')
d = *ptr - 'A' + 10;
else
if(*ptr >= 'a' && *ptr <= 'f')
d = *ptr - 'a' + 10;
else
break;
if(w >= 0x8000000u - d) {
AddCode(te_integeroverflow);
return;
}
w = w * 16 + d - '0';
ptr++;
}
}
else
while(*ptr >= '0' && *ptr <= '7') {
int d = *ptr++ - '0';
if(w >= 0x1000000u - d) {
AddCode(te_integeroverflow);
return;
}
w = w * 8 + d - '0';
}
Term& tm = term.AddTail();
tm.code = t_integer;
tm.ptr = pos;
tm.number = w;
}
break;
case_nonzero_digit: {
double w = c - '0';
bool fp = false;
while(*ptr >= '0' && *ptr <= '9')
w = w * 10 + *ptr++ - '0';
if(*ptr == '.') { // TO BE Completed !!!
fp = true;
ptr++;
double x = 0.1;
while(*ptr >= '0' && *ptr <= '9') {
w += x * (*ptr++ - '0');
x /= 10;
}
}
Term& tm = term.AddTail();
if(fp || w < INT_MIN || w > INT_MAX)
tm.code = t_double;
else
tm.code = t_integer;
tm.ptr = pos;
tm.number = w;
}
break;
case '\'': {
Term& tm = term.AddTail();
tm.code = t_character;
tm.ptr = pos;
tm.text = String(GetCharacter(), 1);
if(*ptr == '\'')
ptr++;
else
tm.code = te_badcharacter;
}
break;
case '\"': {
Term& tm = term.AddTail();
tm.code = t_string;
tm.ptr = pos;
for(;;) {
while(*ptr != '\"') {
if((byte)*ptr < ' ') {
tm.code = te_badstring;
return;
}
tm.text.Cat(GetCharacter());
}
ptr++;
while(*ptr && (byte)*ptr <= ' ') ptr++;
if(*ptr != '\"') break;
ptr++;
}
}
break;
default:
AddCode(c);
return;
}
}
#pragma optimize("t", off)
bool Lex::Prepare(int pos) {
while(term.GetCount() <= pos) {
if(*ptr == '\0') return false;
Next();
}
#ifdef _DEBUG
pp = term[0].ptr;
#endif
return true;
}
int Lex::Code(int pos)
{
if(!Prepare(pos)) return t_eof;
return term[pos].code;
}
bool Lex::IsId(int pos)
{
return Code(pos) >= endkey + 256;
}
String Lex::Id(int pos)
{
ASSERT(IsId(pos));
return id[Code(pos) - 256];
}
void Lex::Get(int n)
{
while(n--) {
if(term.GetCount()) {
int chr = term.Head().code;
if(statsCollected)
symbolStat.IncStat(chr);
if(chr == '{')
braceslevel++;
else
if(chr == '}')
braceslevel--;
term.DropHead();
}
if(term.GetCount() == 0)
Next();
}
}
int Lex::Int(int pos)
{
Prepare(pos);
ASSERT(term[pos].code == t_integer);
return (int)term[pos].number;
}
double Lex::Double(int pos)
{
Prepare(pos);
ASSERT(term[pos].code == t_double);
return term[pos].number;
}
String Lex::Text(int pos)
{
Prepare(pos);
ASSERT(term[pos].code == t_string);
return term[pos].text;
}
int Lex::Chr(int pos)
{
Prepare(pos);
ASSERT(term[pos].code == t_character);
return (byte)*term[pos].text;
}
const char *Lex::Pos(int pos)
{
Prepare(pos);
return pos < term.GetCount() ? term[pos].ptr : ptr;
}

81
uppbox/CppBase2/keyword.i Normal file
View file

@ -0,0 +1,81 @@
#pragma BLITZ_APPROVE
CPPID(__asm)
CPPID(else)
CPPID(struct)
CPPID(enum)
CPPID(auto)
CPPID(__except)
CPPID(template)
CPPID(explicit)
CPPID(this)
CPPID(bool)
CPPID(extern)
CPPID(mutable)
CPPID(thread)
CPPID(break)
CPPID(false)
CPPID(throw)
CPPID(case)
//CPPID(__fastcall)
CPPID(namespace)
CPPID(true)
//CPPID(__finally)
CPPID(new)
//CPPID(__cdecl)
CPPID(float)
CPPID(__try)
CPPID(char)
CPPID(operator)
CPPID(typedef)
CPPID(class)
CPPID(friend)
CPPID(private)
CPPID(typeid)
CPPID(const)
CPPID(goto)
CPPID(protected)
CPPID(typename)
CPPID(const_cast)
CPPID(public)
CPPID(union)
CPPID(continue)
CPPID(inline)
CPPID(register)
CPPID(unsigned)
//CPPID(__declspec)
//CPPID(__inline)
CPPID(reinterpret_cast)
CPPID(using)
CPPID(default)
CPPID(int)
CPPID(return)
CPPID(delete)
CPPID(__int8)
CPPID(short)
CPPID(__uuidof)
CPPID(dllexport)
CPPID(__int16)
CPPID(signed)
CPPID(virtual)
CPPID(dllimport)
CPPID(__int32)
CPPID(sizeof)
CPPID(void)
CPPID(__int64)
CPPID(static)
CPPID(volatile)
CPPID(double)
CPPID(__leave)
CPPID(static_cast)
CPPID(dynamic_cast)
CPPID(long)
//CPPID(__stdcall)
CPPID(if)
CPPID(while)
CPPID(switch)
CPPID(for)
CPPID(try)
CPPID(catch)
CPPID(do)

9
uppbox/CppBase2/perf.txt Normal file
View file

@ -0,0 +1,9 @@
Qualify:
base performance 2.25 s
better bases 2.05 s
-------------
Optimized:
MSC71cdb 1.05s
MSC80cbd 1.32s (-O1, speeed optimization in file)

View file

@ -0,0 +1,723 @@
#include <CtrlLib/CtrlLib.h>
#include "DateTimeCtrl.h"
#define TFILE <DateTimeCtrl/DateTimeCtrl.t>
#include <Core/t.h>
#define IMAGEFILE "DateTimeCtrl.iml"
#include <Draw/iml_source.h>
const Point DateTimePopUp::nullday = Point(-1, -1);
const char *BtnTip(int n)
{
switch(n)
{
case 0: return t_("Previous month"); break;
case 1: return t_("Next month"); break;
case 2: return t_("Previous year"); break;
case 3: return t_("Next year"); break;
default: return "??";
}
}
const char *Days(int day)
{
switch(day)
{
case 0: return t_("Mo");
case 1: return t_("Tu");
case 2: return t_("We");
case 3: return t_("Th");
case 4: return t_("Fr");
case 5: return t_("Sa");
case 6: return t_("Su");
default: return "??";
}
}
const char *Months(int month)
{
switch(month)
{
case 0: return t_("January");
case 1: return t_("February");
case 2: return t_("March");
case 3: return t_("April");
case 4: return t_("May");
case 5: return t_("June");
case 6: return t_("July");
case 7: return t_("August");
case 8: return t_("September");
case 9: return t_("October");
case 10: return t_("November");
case 11: return t_("December");
default: return "??";
}
}
DateTimePopUp::DateTimePopUp()
{
SetFrame(BlackFrame());
Add(mleft);
Add(mright);
Add(yleft);
Add(yright);
mleft <<= THISBACK(OnMonthLeft);
mright <<= THISBACK(OnMonthRight);
yleft <<= THISBACK(OnYearLeft);
yright <<= THISBACK(OnYearRight);
open = false;
userdate = false;
selall = false;
colHeader = Color(46, 149, 210);
colBg = White;
colFg = Black;
colCurDayBg = Color(200, 250, 0);
colCurDayFg = Black;
colCurDayBr = Black;
colSelDayBg = Color(255, 254, 220);
colSelDayFg = Black;
colSelDayBr = Black;
colGrayDay = Color(200, 200, 200);
colCurDate = White;
colToday = Black;
colSelToday = Green;
colSelDay = Green;
colHLine = Gray;
colVLine = Gray;
colDayNames = Black;
colWeek = Black;
bs = 5;
lx = 30;
ly = 15;
hs = 18;
ts = 15;
ls = 3;
}
void DateTimePopUp::Reset()
{
Date tdate = GetSysDate();
tday = tdate.day;
tmonth = tdate.month;
tyear = tdate.year;
Date cdate = (Date) (*date);
if(cdate.IsValid())
{
cday = cdate.day;
cmonth = cdate.month;
cyear = cdate.year;
}
else
{
cday = tday;
cmonth = tmonth;
cyear = tyear;
}
if(!userdate)
{
day = cday;
month = cmonth;
year = cyear;
}
userdate = false;
selday = 0;
newday = oldday = nullday;
col = row = -1;
today = Format("%s: %.2d.%.2d.%.4d", t_("Today"), tdate.day, tdate.month, tdate.year);
istoday = false;
mleft.Tip(BtnTip(0));
mright.Tip(BtnTip(1));
yleft.Tip(BtnTip(2));
yright.Tip(BtnTip(3));
}
void DateTimePopUp::OnMonthLeft()
{
if(--month < 1)
{
month = 12;
if(year > 0)
year--;
}
col = row = -1;
Refresh();
}
void DateTimePopUp::OnMonthRight()
{
if(++month > 12)
{
month = 1;
year++;
}
col = row = -1;
Refresh();
}
void DateTimePopUp::OnYearLeft()
{
if(year > 0) year--;
col = row = -1;
Refresh();
}
void DateTimePopUp::OnYearRight()
{
year++;
col = row = -1;
Refresh();
}
int DateTimePopUp::DayOfWeek(int day, int month, int year, int zelleroffset)
{
if(month < 3)
{
month += 12 ;
year -= 1 ;
}
int n1 = (26 * (month + 1)) / 10;
int n2 = (125 * year) / 100;
return ((day + n1 + n2 - (year / 100) + (year / 400) - zelleroffset) % 7);
}
int DateTimePopUp::WeekOfYear(int day, int month, int year) /* ISO-8601 */
{
const static int mnth[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
int weeknum;
bool cleapyear = IsLeapYear(year);
bool bleapyear = IsLeapYear(year - 1);
int daynum = day + mnth[month - 1];
if(cleapyear && month > 2)
daynum += 1;
int yy = (year - 1) % 100;
int c = (year - 1) - yy;
int g = yy + yy / 4;
int jan1weekday = 1 + (((((c / 100) % 4) * 5) + g) % 7);
int h = daynum + (jan1weekday - 1);
int weekday = 1 + ((h -1) % 7);
int yearnum;
if(daynum <= (8 - jan1weekday) && jan1weekday > 4)
{
yearnum = year - 1;
if(jan1weekday == 5 || (jan1weekday == 6 && bleapyear))
weeknum = 53;
else
weeknum = 52;
}
else yearnum = year;
if(yearnum == year)
{
int yeardays = cleapyear ? 366 : 365;
if((yeardays - daynum) < (4 - weekday))
{
yearnum = year + 1;
weeknum = 1;
}
}
if(yearnum == year)
{
int fday = daynum + (7 - weekday) + (jan1weekday -1);
weeknum = fday / 7;
if(jan1weekday > 4)
weeknum -= 1;
}
return weeknum;
}
void DateTimePopUp::LeftDown(Point p, dword keyflags)
{
int day = Day(newday);
if(!selall && day < 0) return;
GetParent()->IgnoreMouseClick();
Close();
if(newday != nullday)
{
if(day < 0)
{
day = -day;
if(lastrow < 3)
month--;
else
month++;
if(month < 1) month = 12;
if(month > 12) month = 1;
}
}
else
day = 1;
if(p.y <= hs)
day = 1;
date->RemoveSelection();
if(istoday)
*date <<= Date(tyear, tmonth, tday);
else
*date <<= Date(year, month, day);
date->WhenAction();
}
void DateTimePopUp::MouseMove(Point p, dword keyflags)
{
newday = GetDay(p);
if(newday != oldday)
{
if(oldday != nullday)
{
bool b = (selall == false ? Day(oldday) > 0 : true);
if(b)
{
selday = 0;
col = oldday.x;
row = oldday.y;
RefreshDay(oldday);
}
}
if(newday != nullday)
{
bool b = (selall == false ? Day(newday) > 0 : true);
if(b)
{
selday = Day(newday);
col = newday.x;
row = newday.y;
RefreshDay(newday);
}
}
oldday = newday;
}
istoday = MouseOnToday(p);
if(istoday != wastoday)
{
wastoday = istoday;
Size sz = GetSize();
Refresh(0, sz.cy - ts - bs, sz.cx, ts + bs);
}
}
Image DateTimePopUp::CursorImage(Point p, dword keyflags)
{
bool b = (selall == false ? Day(newday) > 0 : true);
if((newday != nullday && b) || istoday)
return CtrlImg::HandCursor();
else
return Image::Arrow();
}
bool DateTimePopUp::MouseOnToday(Point p)
{
Size sz = GetSize();
int x0 = (sz.cx - sztoday.cx) / 2;
int x1 = x0 + sztoday.cx;
int y0 = sz.cy - (ts + bs + sztoday.cy) / 2;
int y1 = y0 + sztoday.cy;
return (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1);
}
void DateTimePopUp::RefreshDay(Point p)
{
int y0 = hs + ly + ls + p.y * rowh;
int y1 = y0 + rowh;
int x0 = lx + ls + p.x * colw;
int x1 = x0 + colw;
Refresh(Rect(x0, y0, x1, y1));
Sync();
}
Point DateTimePopUp::GetDay(Point p)
{
for(int i = 0; i < rows; i++)
{
int y0 = hs + ly + ls + i * rowh;
int y1 = y0 + rowh;
if(p.y >= y0 && p.y < y1)
for(int j = 0; j < cols; j++)
{
int x0 = lx + ls + j * colw;
int x1 = x0 + colw;
if(p.x >= x0 && p.x < x1)
return Point(j, i);
}
}
return Point(-1, -1);
}
void DateTimePopUp::Paint(Draw &w)
{
Size sz = GetSize();
Size tsz;
String str;
int yp;
int d, m, y;
int im, jm, is, js;
m = month;
y = year;
colw = (sz.cx - lx - ls * 2) / cols;
rowh = (sz.cy - hs - ly - ts - ls * 2) / rows;
Font fnt = StdFont();
Color color;
bool refall = (col < 0 && row < 0);
if(refall)
{
w.DrawRect(0, 0, sz.cx, hs, colHeader);
w.DrawRect(Rect(0, hs, sz.cx, sz.cy - ts - bs), colBg);
w.DrawLine(bs, ly + hs, sz.cx - bs, ly + hs, 0, colHLine);
w.DrawLine(lx, hs + bs, lx, sz.cy - bs - ts, 0, colVLine);
yp = hs + ly / 2;
str = Format("%s %d", Months(month - 1), year);
tsz = w.GetTextSize(str);
w.DrawText((sz.cx - tsz.cx) / 2, (hs - tsz.cy) / 2, str, StdFont().Bold(), colCurDate);
tsz = w.GetTextSize(t_("Wk"));
w.DrawText((lx - tsz.cx) / 2, yp - tsz.cy / 2, t_("Wk"), StdFont(), colWeek);
for(int i = 0; i < cols; i++)
{
tsz = w.GetTextSize(Days(i));
w.DrawText(lx + ls + i * colw + (colw - tsz.cx) / 2, yp - tsz.cy / 2,
Days(i), StdFont(), colDayNames);
}
color = colToday;
fnt.Bold().NoUnderline();
if(istoday)
{
color = colSelToday;
fnt.Underline();
}
sztoday = w.GetTextSize(today, fnt);
w.DrawRect(Rect(0, sz.cy - ts - bs, sz.cx, sz.cy), colBg);
w.DrawText((sz.cx - sztoday.cx) / 2, sz.cy - (ts + bs + sztoday.cy) / 2, today, fnt, color);
d = 1;
int fd = DayOfWeek(1, month, year);
if(fd > 0)
{
if(--m < 1)
{
m = 12;
y -= 1;
}
d = GetDaysOfMonth(m, y) - fd + 1;
}
}
color = colFg;
int fh = w.GetFontInfo().GetHeight();
if(refall)
{
im = rows;
jm = cols;
is = js = 0;
}
else
{
im = row + 1;
jm = col + 1;
is = row;
js = col;
d = Day(col, row);
if(d < 0) m = 0;
}
for(int i = is; i < im; i++)
{
int yp = hs + ly + ls + i * rowh;
int yc = (rowh - fh) / 2;
str = AsString(WeekOfYear(d, m, y));
w.DrawText((lx - w.GetTextSize(str).cx) / 2, yp + yc, str, StdFont(), colWeek);
for(int j = js; j < jm; j++)
{
fnt.NoBold().NoUnderline();
int xp = lx + ls + j * colw;
bool special = false;
if(m == month)
{
Day(j, i) = d;
color = Black;
if(j == 6)
{
color = Red;
}
if(d == tday && m == tmonth && y == tyear)
{
int x0 = xp;
int x1 = xp + colw;
w.DrawRect(x0 + 1, yp - 0, colw - 1, rowh - 1, colCurDayBg);
DrawFrame(w, x0 + 1, yp - 0, colw - 1, rowh - 1, colCurDayBr);
color = colCurDayFg;
fnt.Bold();
special = true;
}
if(d == cday && m == cmonth && y == cyear)
{
int x0 = xp;
int x1 = xp + colw;
w.DrawRect(x0 + 1, yp - 0, colw - 1, rowh - 1, colSelDayBg);
DrawFrame(w, x0 + 1, yp - 0, colw - 1, rowh - 1, colSelDayBr);
color = colSelDayFg;
fnt.Bold();
special = true;
}
}
else
{
color = colGrayDay;
Day(j, i) = d > 0 ? -d : d;
}
if(d == selday)
{
if(d < 0 && selall)
{
color = colGrayDay;
fnt.Bold();
if(!special) fnt.Underline();
}
if(d > 0 && month == m)
{
color = colSelDay;
fnt.Bold();
if(!special) fnt.Underline();
}
selmonth = m;
}
if(col >= 0)
{
if(special)
{
w.DrawRect(xp, yp, 1, rowh, colBg);
w.DrawRect(xp, yp + rowh - 1, colw, 1, colBg);
}
else
w.DrawRect(xp, yp, colw, rowh, colBg);
}
str = AsString(abs(d));
w.DrawText(xp + (colw - w.GetTextSize(str, fnt).cx) / 2, yp + yc , str, fnt, color);
if(++d > GetDaysOfMonth(m, y))
{
d = 1;
if(++m > 12)
{
m = 1;
y += 1;
}
}
}
}
lastrow = row;
col = row = -1;
}
void DateTimePopUp::Deactivate()
{
if(open)
{
open = false;
Close();
IgnoreMouseClick();
}
}
bool DateTimePopUp::Key(dword key, int count)
{
if(key == K_ESCAPE)
Deactivate();
return true;
}
void DateTimePopUp::PopUp(Ctrl *owner, Rect &rt)
{
Close();
Reset();
mleft.LeftPos(2, 15).TopPos(2, 13);
mleft.SetLeft().DrawEdge(0).SetImage(ImgLeft2());
mright.LeftPos(17, 15).TopPos(2, 13);
mright.SetRight().DrawEdge(0).SetImage(ImgRight2());
yright.RightPos(2, 15).TopPos(2, 13);
yright.SetRight().DrawEdge(0).SetImage(ImgRight2());
yleft.RightPos(17, 15).TopPos(2, 13);
yleft.SetLeft().DrawEdge(0).SetImage(ImgLeft2());
SetRect(rt);
Ctrl::PopUp(owner, true, true, IsXPStyle());
open = true;
}
DateTimeCtrl::DateTimeCtrl()
{
AddFrame(drop);
drop.SetMonoImage(IsXPStyle() ? CtrlImg::SmallDown() : CtrlImg::smalldown());
drop.NoWantFocus();
calendar.date = this;
width = defWidth;
height = defHeight;
drop <<= THISBACK(OnDrop);
}
DateTimeCtrl& DateTimeCtrl::SetDate(int d, int m, int y)
{
calendar.day = d;
calendar.month = m;
calendar.year = y;
calendar.userdate = true;
SetData(Date(y, m, d));
return *this;
}
DateTimeCtrl& DateTimeCtrl::SetSize(int w, int h)
{
if(w >= defWidth)
width = w;
if(h >= defHeight)
height = h;
return *this;
}
void DateTimeCtrl::OnDrop()
{
Rect rw = Ctrl::GetWorkArea();
Rect rs = GetScreenRect();
Rect r;
r.left = rs.left;
r.right = rs.left + width;
r.top = rs.bottom;
r.bottom = rs.bottom + height;
if(r.bottom > rw.bottom)
{
r.top = rs.top - height;
r.bottom = rs.top;
}
if(r.right > rw.right)
{
int diff;
if(rs.right <= rw.right)
diff = rs.right - r.right;
else
diff = rw.right - r.right;
r.left += diff;
r.right += diff;
}
if(r.left < rw.left)
{
int diff = rw.left - r.left;
r.left += diff;
r.right += diff;
}
calendar.PopUp(this, r);
}
FlatButton::FlatButton()
{
hl = Color(235, 240, 243);
bg = Color(179, 220, 253);
fg = White;
left = true;
}
void FlatButton::DrawFrame(Draw &w, const Rect &r, Color lc, Color tc, Color rc, Color bc)
{
w.DrawRect(r.left, r.top, r.left + 1, r.bottom, lc);
w.DrawRect(r.right - 1, r.top, r.right, r.bottom, rc);
w.DrawRect(r.left, r.top, r.right, r.top + 1, tc);
w.DrawRect(r.left, r.bottom - 1, r.right, r.bottom, bc);
}
void FlatButton::Paint(Draw &w)
{
Size sz = GetSize();
Size isz = img.GetSize();
if(HasMouse())
w.DrawRect(sz, hl);
else
w.DrawRect(sz, bg);
if(drawedge)
::DrawFrame(w, sz, fg);
else
{
if(!left)
DrawFrame(w, sz, bg, fg, fg, fg);
else
DrawFrame(w, sz, fg, fg, bg, fg);
}
if(!IsPush())
w.DrawImage((sz.cx - isz.cx) / 2, (sz.cy - isz.cy) / 2, img);
else
{
if(!left)
w.DrawImage((sz.cx - isz.cx) / 2 + 1, (sz.cy - isz.cy) / 2 + 1, img);
else
w.DrawImage((sz.cx - isz.cx) / 2 - 1, (sz.cy - isz.cy) / 2 + 1, img);
}
}

View file

@ -0,0 +1,171 @@
#ifndef _DateTimeCtrl_DateTimeCtrl_h_
#define _DateTimeCtrl_DateTimeCtrl_h_
#include <CtrlLib/CtrlLib.h>
class FlatButton : public Pusher
{
public:
Image img;
Color fg, bg, hl;
bool left;
bool drawedge;
FlatButton();
void DrawFrame(Draw &w, const Rect &r, Color lc, Color tc, Color rc, Color bc);
virtual void Paint(Draw &w);
virtual void MouseEnter(Point p, dword kflags)
{
Refresh();
Pusher::MouseEnter(p, kflags);
}
virtual void MouseLeave()
{
Refresh();
Pusher::MouseLeave();
}
FlatButton& SetImage(const Image &_img)
{
img = _img;
Refresh();
return *this;
}
FlatButton& SetLeft() {left = true; return *this;}
FlatButton& SetRight() {left = false; return *this;}
FlatButton& DrawEdge(bool b) {drawedge = b; return *this;}
};
class DateTimePopUp : public Ctrl
{
public:
typedef DateTimePopUp CLASSNAME;
FlatButton mleft;
FlatButton mright;
FlatButton yleft;
FlatButton yright;
static const int cols = 7;
static const int rows = 6;
static const Point nullday;
int bs; //border size
int ls; //line space
int lx; //horizontal line distance from left edge
int ly; //vertical line distance from bottom edge of header
int hs; //header vertical size
int ts; //today vertical size
int colw;
int rowh;
int col;
int row;
int lastrow;
bool selall;
Color colHeader;
Color colBg;
Color colFg;
Color colCurDayBg;
Color colCurDayFg;
Color colCurDayBr;
Color colSelDayBg;
Color colSelDayFg;
Color colSelDayBr;
Color colGrayDay;
Color colCurDate;
Color colToday;
Color colSelToday;
Color colSelDay;
Color colHLine;
Color colVLine;
Color colDayNames;
Color colWeek;
int days[rows][cols];
Point newday;
Point oldday;
String today;
Size sztoday;
bool istoday;
bool wastoday;
EditDate *date;
int day, month, year;
int tday, tmonth, tyear;
int cday, cmonth, cyear;
int selday;
int selmonth;
bool userdate;
bool open;
bool clickall;
DateTimePopUp();
void Reset();
void OnMonthLeft();
void OnMonthRight();
void OnYearLeft();
void OnYearRight();
bool IsLeapYear(int year) { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); }
int DayOfWeek(int day, int month, int year, int zelleroffset = 2);
int WeekOfYear(int day, int month, int year);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
virtual Image CursorImage(Point p, dword keyflags);
bool MouseOnToday(Point p);
Point GetDay(Point p);
virtual void Paint(Draw &w);
virtual void Deactivate();
virtual bool Key(dword key, int count);
void PopUp(Ctrl *owner, Rect &rt);
int& Day(int x, int y) { return days[y][x]; }
int& Day(Point p) { return days[p.y][p.x]; }
void RefreshDay(Point p);
};
class DateTimeCtrl : public EditDate
{
FrameRight<Button> drop;
DateTimePopUp calendar;
void OnDrop();
int width, height;
static const int defWidth = 215;
static const int defHeight = 150;
public:
typedef DateTimeCtrl CLASSNAME;
DateTimeCtrl();
DateTimeCtrl& SetDate(int d, int m, int y);
DateTimeCtrl& SetSize(int w = defWidth, int h = defHeight);
DateTimeCtrl& SetBorderSize(int size) { calendar.bs = size; return *this; }
DateTimeCtrl& SelectAll(bool b) { calendar.selall = b; return *this; }
};
#endif

View file

@ -0,0 +1,36 @@
IMAGE_BEGIN(ImgLeft)
IMAGE_SCAN("Â\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Á‚\0\0\0")
IMAGE_SCAN("\0\0\0")
IMAGE_SCAN("Á‚\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Â\0\0\0")
IMAGE_PACKED(ImgLeft, "\2\5\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
IMAGE_BEGIN(ImgLeft2)
IMAGE_SCAN("Ã\1\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Áƒ\0\0\0")
IMAGE_SCAN("„\0\0\0")
IMAGE_SCAN("Áƒ\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Ã\1\0\0\0")
IMAGE_PACKED(ImgLeft2, "\2\4\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
IMAGE_BEGIN(ImgRight2)
IMAGE_SCAN("\1\0\0\0")
IMAGE_SCAN("\0\0\0")
IMAGE_SCAN("ƒ\0\0\0")
IMAGE_SCAN("„\0\0\0")
IMAGE_SCAN("ƒ\0\0\0")
IMAGE_SCAN("\0\0\0")
IMAGE_SCAN("\1\0\0\0")
IMAGE_PACKED(ImgRight2, "\2\4\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
IMAGE_BEGIN(ImgRight)
IMAGE_SCAN("\0\0\0")
IMAGE_SCAN("Á‚\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Â\0\0\0")
IMAGE_SCAN("‚\0\0\0")
IMAGE_SCAN("Á‚\0\0\0")
IMAGE_SCAN("\0\0\0")
IMAGE_PACKED(ImgRight, "\2\5\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")

View file

@ -0,0 +1,73 @@
// main.cpp
T_("Monday")
plPL("Poniedziałek")
T_("Tuesday")
plPL("Wtorek")
T_("Wednesday")
plPL("Środa")
T_("Thursday")
plPL("Czwartek")
T_("Friday")
plPL("Piątek")
T_("Saturday")
plPL("Sobota")
T_("Sunday")
plPL("Niedziela")
T_("Mo")
plPL("Pn")
T_("Tu")
plPL("Wt")
T_("We")
plPL("Śr")
T_("Th")
plPL("Cz")
T_("Fr")
plPL("Pt")
T_("Sa")
plPL("So")
T_("Su")
plPL("Nd")
T_("January")
plPL("Styczeń")
T_("February")
plPL("Luty")
T_("March")
plPL("Marzec")
T_("April")
plPL("Kwiecień")
T_("May")
plPL("Maj")
T_("June")
plPL("Czerwiec")
T_("July")
plPL("Lipiec")
T_("August")
plPL("Sierpień")
T_("September")
plPL("Wrzesień")
T_("October")
plPL("Październik")
T_("November")
plPL("Listopad")
T_("December")
plPL("Grudzień")
T_("Week")
plPL("Tydzień")
T_("Wk")
plPL("Ty.")
T_("Today")
plPL("Dziś")
T_("Next month")
plPL("Następny miesiąc")
T_("Previous month")
plPL("Poprzedni miesiąc")
T_("Next year")
plPL("Następny rok")
T_("Previous year")
plPL("Poprzedni rok")

View file

@ -0,0 +1,14 @@
uses
CtrlLib;
file
DateTimeCtrl.t charset "UTF-8",
DateTimeCtrl.cpp,
DateTimeCtrl.h,
DateTimeCtrl.iml,
main.lay,
main.cpp,
changelog.txt;
mainconfig
"" = "GUI";

View file

@ -0,0 +1,39 @@
DateTimeCtrl Changelog
[+] new
[-] fixed
[*] changed
---------------------------------
v 1.00 (initial version)
v 1.01
- when gray day was selected 255 was returned as a day after left click
+ more compatability with XP style;
+ method SelectAll(bool b) - if b is true you can select days form one month
before or one month after the current month
v.1.02
+ escape key closes the calendar
+ tooltips for buttons for changing month and year
v.1.03
+ WhenSelect replaced by default WhenAction
v.1.04
+ fixed main.cpp to be able to compile
+ added ignoring mouse click when calendar is close
(it prevents opening any other popup control)
ToDo:
- usc file
- time in return value
- popup month list
- automatic font size changing (according to window size)
- gripper

View file

@ -0,0 +1,68 @@
#ifdef flagMAIN
#include <CtrlLib/CtrlLib.h>
#include "DateTimeCtrl.h"
#define LAYOUTFILE "main.lay"
#include <CtrlCore/lay.h>
struct App : public WithAppLayout<TopWindow>
{
typedef App CLASSNAME;
App()
{
CtrlLayout(*this, "DateTimeCtrl test");
datesmall <<= GetSysDate();
datebig <<= GetSysDate();
datebig.SetSize(400,300);
lang.Add("English");
lang.Add("Polish");
lang.SetIndex(0);
lang <<= THISBACK(ChangeLang);
datesmall <<= THISBACK(OnSelect);
repaint = 0;
selall = 0;
exit <<= THISBACK(Close);
repaint <<= THISBACK(Repaint);
selall <<= THISBACK(SelectAll);
}
void ChangeLang()
{
int i = lang.GetIndex();
if(i == 1)
SetLanguage(LNGC_('P','L','P','L', CHARSET_WIN1250));
else
SetLanguage(LNGC_('E','N','E','N', CHARSET_UTF8));
}
void Repaint()
{
Ctrl::ShowRepaint = repaint * 20;
}
void SelectAll()
{
datesmall.SelectAll(selall);
datebig.SelectAll(selall);
}
void OnSelect()
{
PromptOK("Date was selected");
}
};
GUI_APP_MAIN
{
App().Run();
}
#endif

View file

@ -0,0 +1,11 @@
LAYOUT(AppLayout, 360, 200)
ITEM(DateTimeCtrl, datesmall, LeftPosZ(12, 100).TopPosZ(24, 19))
ITEM(DateTimeCtrl, datebig, LeftPosZ(180, 108).TopPosZ(24, 19))
ITEM(Label, dv___2, SetLabel(t_("Standard calendar")).LeftPosZ(12, 96).TopPosZ(8, 13))
ITEM(Label, dv___3, SetLabel(t_("Big calendar")).LeftPosZ(180, 76).TopPosZ(8, 13))
ITEM(DropList, lang, LeftPosZ(96, 124).TopPosZ(84, 19))
ITEM(Label, dv___5, SetLabel(t_("Language")).LeftPosZ(96, 88).TopPosZ(70, 13))
ITEM(Option, repaint, SetLabel(t_("Show repaint")).LeftPosZ(4, 84).BottomPosZ(5, 15))
ITEM(Option, selall, SetLabel(t_("Select All")).LeftPosZ(104, 68).BottomPosZ(5, 15))
ITEM(Button, exit, SetLabel(t_("Exit")).RightPosZ(4, 68).BottomPosZ(4, 24))
END_LAYOUT

135
uppbox/MakeInstall/Main.cpp Normal file
View file

@ -0,0 +1,135 @@
#include <Core/Core.h>
#include <plugin/bz2/bz2.h>
void Put(StringStream& ss, const String& data)
{
ss.PutL(data.GetLength());
ss.Put(data);
}
String GetFile(const char *s)
{
return LoadFile(s);
}
void GatherFile(StringStream& ss, const char *dir, const char *name)
{
String data = LoadFile(AppendFileName(dir, name));
if(!data.IsVoid()) {
ss.Put(1);
Put(ss, name);
Put(ss, data);
}
}
void GatherFiles(StringStream& ss, const char *dir, String path)
{
String p1 = AppendFileName(dir, path);
FindFile ff(p1 + "/*.*");
while(ff) {
String name = ff.GetName();
if(ff.IsFile()) {
printf("gathering %s\n", name);
GatherFile(ss, p1, name);
}
else
if(ff.IsFolder()) {
ss.Put(0);
Put(ss, name);
GatherFiles(ss, dir, AppendFileName(path, name));
}
ff.Next();
}
ss.Put(2);
}
void CompressFolder(const char *archive, const char *dir)
{
StringStream ss;
GatherFiles(ss, dir, "");
SaveFile(archive, BZ2Compress(ss));
}
void CopyFolder(const char *src, const char *dst)
{
RealizeDirectory(dst);
FindFile ff(String(src) + "/*.*");
while(ff) {
String s = AppendFileName(src, ff.GetName());
String d = AppendFileName(dst, ff.GetName());
if(ff.IsFile()) {
printf("copying %s\n", s);
String q = LoadFile(s);
String ext = ToLower(GetFileExt(s));
if(ext != ".aux" && ext != ".$old") {
if(q != LoadFile(d)) {
SaveFile(d, q);
FileSetTime(d, ff.GetLastWriteTime());
}
}
}
else
if(ff.IsFolder())
CopyFolder(s, d);
ff.Next();
}
}
void CopyFolders(const char *src, const char *dst, const char *folders)
{
Vector<String> folder = Split(folders, ';');
for(int i = 0; i < folder.GetCount(); i++)
CopyFolder(AppendFileName(src, folder[i]), AppendFileName(dst, folder[i]));
}
CONSOLE_APP_MAIN
{
for(int q = 0; q < 3; q++) {
DeleteFolderDeep("d:/u");
CopyFolders("D:/uppsrc", "d:/u/uppsrc",
"ide;Topic;CtrlLib;Web;HexView;Esc;CodeEditor;Core;RichEdit;RichText;Image;"
"Draw;coff;CppBase;CtrlCore;Report;"
"Geom;MySql;Ole;OleDB;Oracle;Sql;SqlCommander;SqlCtrl;TCore;TCtrlLib;TDraw;TSql;Updater;"
"PdfDraw;GLCtrl;VectorDes;CbGen;Crypto;"
"plugin"
);
CopyFolder("d:/examples", "d:/u/examples");
CopyFolder("d:/reference", "d:/u/reference");
CopyFolder("d:/uppsrc/Common", "d:/u/Common");
if(q < 2) {
CopyFolder("d:/theide/SDL-1.2.9", "d:/u/SDL-1.2.9");
SaveFile("d:/u/theide.exe", LoadFile("d:/theide/theide_.exe"));
SaveFile("d:/u/dbghelp.dll", LoadFile("d:/theide/dbghelp.dll"));
SaveFile("d:/u/install.upp", LoadFile("d:/uppsrc/install.upp"));
SaveFile("d:/u/license.chk", "1");
SaveFile("d:/u/en-us.scd", LoadFile("d:/theide/en-us.scd"));
SaveFile("d:/u/en-gb.scd", LoadFile("d:/theide/en-gb.scd"));
FindFile ff("d:/theide/*.upt");
while(ff) {
SaveFile(AppendFileName("d:/u", ff.GetName()), LoadFile(AppendFileName("d:/theide", ff.GetName())));
ff.Next();
}
}
if(q == 1)
CopyFolder("c:/mingw32", "d:/u/mingw");
printf("Compressing!\n");
switch(q) {
case 0:
CompressFolder("d:/upp.b2a", "d:/u");
break;
case 1:
CompressFolder("d:/uppmingw.b2a", "d:/u");
break;
case 2:
DeleteFile("d:\\src.zip");
SetCurrentDirectory("d:\\u");
system("zip -r d:\\src.zip *");
break;
}
}
}

View file

@ -0,0 +1,9 @@
uses
plugin\bz2,
Core;
file
Main.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,2 @@
file
e:\out\upp/MakeInstall/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\MakeInstall.log;

View file

@ -0,0 +1,243 @@
#include <CtrlLib/CtrlLib.h>
#include <plugin/bz2/bz2.h>
#include <plugin/ftp/ftp.h>
using namespace Upp;
#define LAYOUTFILE <MakeInstall2/install.lay>
#include <CtrlCore/lay.h>
#include <Wincon.h>
String version = "708dev2a";
String outdir = "d:\\";
String uppdir = "d:\\";
String idedir = "c:\\upp";
String mingw = "c:\\mingwi";
String vdir;
void Sys(const char *s)
{
Cout() << s << '\n';
if(system(s)) {
Cout() << "Failed!";
throw Exc();
}
}
void CopyFolder(const char *src, const char *dst, bool deep = true)
{
Cout() << Sprintf("Directory %s\n", src);
RealizeDirectory(dst);
FindFile ff(String(src) + "/*.*");
while(ff) {
String s = AppendFileName(src, ff.GetName());
String d = AppendFileName(dst, ff.GetName());
if(ff.IsFile()) {
String q = LoadFile(s);
String ext = ToLower(GetFileExt(s));
if(ext != ".aux" && ext != ".$old")
SaveFile(d, q);
}
else
if(ff.IsFolder()) {
if(deep || *GetFileExt(s))
CopyFolder(s, d, deep);
}
ff.Next();
}
}
void CopyUppFolder(const char *src, const char *dst, bool deep = true)
{
CopyFolder(AppendFileName(uppdir, src), AppendFileName(outdir, dst), deep);
}
void CopyUppFolders(const char *src, const char *dst, const char *folders, bool deep = true)
{
Vector<String> folder = Split(folders, ';');
for(int i = 0; i < folder.GetCount(); i++)
CopyUppFolder(AppendFileName(src, folder[i]), AppendFileName(dst, folder[i]), deep);
}
void CopyIdeFile(const char *src, const char *dst)
{
SaveFile(AppendFileName(outdir, dst), LoadFile(AppendFileName(idedir, src)));
}
bool ShowFtpProgress(int a, int b)
{
if((a & 65535) == 0)
Cout() << Sprintf("%d %%, %d bytes (%d total)\n", a * 100 / b, a, b);
return false;
}
void Error(const char *s)
{
Cout() << "\n## ERROR " << s << '\n';
throw Exc();
}
void SfSave(const char *fn)
{
FtpClient ftp;
Cout() << Sprintf("connecting to sf.net...");
if(!ftp.Connect("upload.sourceforge.net", "anonymous", "", true))
Error("Unable to connect to sf.net: " + ftp.GetError());
Cout() << Sprintf("connected\n");
if(!ftp.Cd("incoming"))
Error("FTP error (cd incoming): " + ftp.GetError());
Cout() << Sprintf("uploading %s\n", fn);
if(!ftp.Save(GetFileName(fn), LoadFile(fn), callback(ShowFtpProgress)))
Error("FTP error (file upload): " + ftp.GetError());
Cout() << Sprintf("OK: %s uploaded\n", fn);
}
void MakeInstall(const String& ifn)
{
SetCurrentDirectory(AppendFileName(outdir, "u"));
DeleteFile("c:\\upp.7z");
Sys("7z a c:\\upp.7z * -r -mx -m0fb=255 -mf=off");
SetCurrentDirectory("C:\\");
Sys("umk uppbox WinInstaller2 MSC8 -ar " + ifn);
DeleteFile("c:\\upp.7z");
}
GUI_APP_MAIN
{
WithInstallLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, "MakeInstall");
dlg.version <<= "603alfa3";
dlg.outdir <<= "d:\\";
dlg.uppdir <<= "d:\\";
dlg.idedir <<= "d:\\theide";
dlg.mingw <<= "c:\\mingwi";
LoadFromFile(dlg);
int c = dlg.Execute();
StoreToFile(dlg);
if(c != IDOK)
return;
version = ~dlg.version;
outdir = ~dlg.outdir;
uppdir = ~dlg.uppdir;
idedir = ~dlg.idedir;
mingw = ~dlg.mingw;
String version_h = AppendFileName(uppdir, "uppsrc/ide/version.h");
String version_bak = AppendFileName(uppdir, "uppsrc/ide/version.bak");
MoveFile(version_h, version_bak);
SaveFile(version_h, "#define IDE_VERSION \"" + version + "\"");
try {
AllocConsole();
vdir = AppendFileName(outdir, version);
// if(DirectoryExists(vdir))
// Error("version already exists");
RealizeDirectory(vdir);
DeleteFolderDeep(AppendFileName(outdir, "u"));
CopyUppFolders("uppsrc", "u/uppsrc",
"BuildAll;CbGen;CodeEditor;"
"coff;Core;CppBase;Crypto;CtrlCore;"
"CtrlLib;Draw;DropGrid;Esc;Geom;"
"GLCtrl;GridCtrl;HexView;IconDes;ide;"
"MySql;Ole;OleDB;Oracle;PdfDraw;"
"plugin;PostgreSQL;Report;RichEdit;RichText;"
"Sql;SqlCommander;SqlCtrl;umk;Updater"
);
CopyUppFolders("uppsrc", "u/uppsrc", "Web;Web/TServ;Web/SSL", false);
CopyUppFolder("examples", "u/examples");
CopyUppFolder("reference", "u/reference");
CopyUppFolder("tutorial", "u/tutorial");
CopyUppFolder("uppsrc/Common", "u/Common");
CopyFolder(AppendFileName(idedir, "sdl"), AppendFileName(outdir, "u/sdl"));
if(dlg.make_mingw || dlg.make_win) {
Sys("umk uppsrc ide MSC71cdb -arm " + AppendFileName(outdir, "u/theide.exe"));
Sys("umk uppsrc umk MSC71cdb -arm " + AppendFileName(outdir, "u/umk.exe"));
}
MoveFile(AppendFileName(outdir, "u/theide.map"), AppendFileName(vdir, "theide.map"));
MoveFile(AppendFileName(outdir, "u/umk.map"), AppendFileName(vdir, "umk.map"));
CopyIdeFile("dbghelp.dll", "u/dbghelp.dll");
SaveFile(AppendFileName(outdir, "u/install.upp"),
LoadFile(AppendFileName(uppdir, "uppsrc/install.upp")));
CopyIdeFile("en-us.scd", "u/en-us.scd");
CopyIdeFile("en-gb.scd", "u/en-gb.scd");
SaveFile(AppendFileName(outdir, "u/license.chk"), "1");
FindFile ff(AppendFileName(idedir, "*.upt"));
while(ff) {
SaveFile(AppendFileName(outdir, String("u/") + ff.GetName()),
LoadFile(AppendFileName(idedir, ff.GetName())));
ff.Next();
}
String mw = AppendFileName(outdir, "u/mingw");
CopyFolder(mingw, mw);
DeleteFolderDeep(vdir);
RealizeDirectory(vdir);
String uppmingw = AppendFileName(vdir, "upp-mingw-" + version + ".exe");
if(dlg.make_mingw)
MakeInstall(uppmingw);
String uppwin = AppendFileName(vdir, "upp-win-" + version + ".exe");
DeleteFolderDeep(mw);
if(dlg.make_win)
MakeInstall(uppwin);
String uppsrc = AppendFileName(vdir, "upp-src-" + version + ".zip");
if(dlg.make_src)
{
FindFile ff(AppendFileName(outdir, "u/*.*"));
while(ff) {
String name = ff.GetName();
String p = AppendFileName(outdir, "u/" + name);
if(ff.IsFile())
DeleteFile(p);
ff.Next();
}
SetCurrentDirectory(AppendFileName(outdir, "u"));
Sys("zip -r " + uppsrc + " *");
}
if(dlg.upload) {
if(!IsNull(dlg.hour)) {
Time tm = GetSysTime();
Time tmu = tm;
tmu.hour = (int)~dlg.hour;
if(tmu < tm)
tmu += 86400;
int ws = int(tmu - tm);
Cout() << "Waiting " << ws << " second until " << tmu << '\n';
Sleep(ws * 1000);
}
Cout() << "*** Uploading started at " << GetSysTime() << '\n';
if(dlg.make_mingw)
SfSave(uppmingw);
if(dlg.make_win)
SfSave(uppwin);
if(dlg.make_src)
SfSave(uppsrc);
Cout() << "*** Uploading finished at " << GetSysTime() << '\n';
}
Cout() << Sprintf("*** OK\n");
PromptOK("Release successfull");
}
catch(...) {
Exclamation("Error!");
}
DeleteFile(version_h);
MoveFile(version_bak, version_h);
}

View file

@ -0,0 +1,12 @@
uses
plugin\bz2,
Core,
plugin\ftp,
CtrlLib;
file
install.lay,
Main.cpp;
mainconfig
"" = "GUI";

View file

@ -0,0 +1,21 @@
LAYOUT(InstallLayout, 292, 308)
ITEM(Label, dv___0, SetLabel(t_("Upp directory")).LeftPosZ(8, 88).TopPosZ(8, 19))
ITEM(EditString, uppdir, LeftPosZ(100, 184).TopPosZ(8, 19))
ITEM(Label, dv___2, SetLabel(t_("Output directory")).LeftPosZ(8, 88).TopPosZ(32, 19))
ITEM(EditString, outdir, LeftPosZ(100, 184).TopPosZ(32, 19))
ITEM(Label, dv___4, SetLabel(t_("TheIDE directory")).LeftPosZ(8, 88).TopPosZ(56, 19))
ITEM(EditString, idedir, LeftPosZ(100, 184).TopPosZ(56, 19))
ITEM(Label, dv___6, SetLabel(t_("MinGWI directory")).LeftPosZ(8, 88).TopPosZ(80, 19))
ITEM(EditString, mingw, LeftPosZ(100, 184).TopPosZ(80, 19))
ITEM(Label, dv___8, SetLabel(t_("U++ VERSION")).SetFont(StdFont(11).Bold()).LeftPosZ(8, 88).TopPosZ(120, 19))
ITEM(EditString, version, LeftPosZ(100, 184).TopPosZ(120, 19))
ITEM(Option, make_mingw, SetLabel(t_("Create upp-mingw")).LeftPosZ(12, 216).TopPosZ(164, 15))
ITEM(Option, make_win, SetLabel(t_("Create upp-win")).LeftPosZ(12, 216).TopPosZ(184, 15))
ITEM(Option, make_src, SetLabel(t_("Create upp-src")).LeftPosZ(12, 216).TopPosZ(204, 15))
ITEM(Option, upload, SetLabel(t_("Upload at")).LeftPosZ(12, 100).TopPosZ(240, 20))
ITEM(EditInt, hour, Min(1).Max(24).LeftPosZ(116, 36).TopPosZ(240, 19))
ITEM(Label, dv___15, SetLabel(t_(":00")).LeftPosZ(156, 25).TopPosZ(240, 19))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(8, 96).TopPosZ(276, 24))
ITEM(Button, ok, SetLabel(t_("MakeInstall!")).LeftPosZ(188, 96).TopPosZ(276, 24))
END_LAYOUT

View file

@ -0,0 +1,2 @@
file
e:\out\upp/MakeInstall/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\MakeInstall.log;

View file

@ -0,0 +1,587 @@
#include <CtrlLib/CtrlLib.h>
#include <plugin/bz2/bz2.h>
#include <plugin/ftp/ftp.h>
using namespace Upp;
class EditDir : public EditString
{
public:
typedef EditDir CLASSNAME;
EditDir()
{
AddFrame(btn);
btn.SetImage(CtrlImg::smallright()).NoWantFocus();
btn <<= THISBACK(SelectDir);
}
private:
FrameRight<Button> btn;
void SelectDir()
{
FileSel fs;
fs.ActiveDir(GetData());
if(fs.ExecuteSelectDir())
SetData(fs.Get());
}
};
#define LAYOUTFILE <MakeInstall3/install.lay>
#include <CtrlCore/lay.h>
#define AFN AppendFileName
#define CHECKPOINT(x) SaveCheckpoint(x); checkpoint_##x
#include <Wincon.h>
String version = "801-dev1";
String outdir = "c:\\Dev\\upp.install.final";
String uppdir = "c:\\Dev\\upp.uvs";
String uppsrc = "c:\\Dev\\upp.uvs\\uppsrc.uc";
String examples = "c:\\Dev\\upp.uvs\\examples.uc";
String reference = "c:\\Dev\\upp.uvs\\reference.uc";
String tutorial = "c:\\Dev\\upp.uvs\\tutorial.uc";
String bazaar = "c:\\Dev\\upp.svn\\bazaar";
String theide = "c:\\Dev\\upp";
String mingw = "c:\\Dev\\upp.install\\mingw";
String sdl = "c:\\Dev\\upp.install\\sdl";
String wi = "c:\\Dev\\upp.uvs\\uppbox.uc\\WinInstaller2";
String wipackage = "myapps";
String builder = "MSC80";
String builder_gcc = "MINGW430";
String sevenzipdir = "c:\\Program Files\\7-Zip";
int rebuildall = 1;
bool iserror = false;
FtpClient ftp;
String vdir;
Vector<String> upt;
void Sys(const char *s)
{
Cout() << s << '\n';
if(system(s))
{
Cout() << "Failed!";
throw Exc(s);
}
}
void SysPass(const char *s)
{
Cout() << s << '\n';
if(system(s))
{
RLOG(s);
iserror = true;
Cout() << "Failed!";
}
}
void SaveCheckpoint(int cp)
{
SaveFile(AFN(outdir, "checkpoint.tmp"), AsString(cp));
}
int GetCheckpoint()
{
String s = LoadFile(AFN(outdir, "checkpoint.tmp"));
int cp = StrInt(s);
return IsNull(cp) ? 0 : cp;
}
void CopyFolder(const char *src, const char *dst, bool deep = true)
{
Cout() << Sprintf("Copying %s\n", src);
RealizeDirectory(dst);
FindFile ff(String(src) + "/*.*");
while(ff)
{
String name = ff.GetName();
String s = AFN(src, name);
String d = AFN(dst, name);
if(ff.IsFile())
{
String q = LoadFile(s);
String ext = ToLower(GetFileExt(s));
if(ext != ".aux" && ext != ".$old" && ext != ".upt" && ext != ".dat")
SaveFile(d, q);
}
else if(ff.IsFolder())
{
if(name != ".svn" && (deep || *GetFileExt(s)))
CopyFolder(s, d, deep);
}
ff.Next();
}
}
void ScanUpp(const char *src, Vector<String> &upps)
{
FindFile ff(String(src) + "/*.*");
while(ff)
{
String s = AFN(src, ff.GetName());
if(ff.IsFile())
{
String ext = ToLower(GetFileExt(s));
if(ext == ".upp")
if(LoadFile(s).Find("mainconfig") >= 0)
upps.Add(GetFileTitle(s));
}
else if(ff.IsFolder())
ScanUpp(s, upps);
ff.Next();
}
}
void ScanUpt(const char *src, Vector<String> &upts)
{
FindFile ff(String(src) + "/*.*");
while(ff)
{
String s = AFN(src, ff.GetName());
if(ff.IsFile())
{
String ext = ToLower(GetFileExt(s));
if(ext == ".upt")
upts.Add(GetFileName(s));
}
else if(ff.IsFolder())
ScanUpt(s, upts);
ff.Next();
}
}
void CopyUpt(const char *src, const char *dst)
{
FindFile ff(String(src) + "/*.*");
while(ff)
{
String s = AFN(src, ff.GetName());
String d = AFN(dst, ff.GetName());
if(ff.IsFile())
{
String ext = ToLower(GetFileExt(s));
if(ext == ".upt")
{
SaveFile(d, LoadFile(s));
upt.Add(GetFileName(s));
Cout() << Sprintf("Copying %s\n", s);
}
}
else if(ff.IsFolder())
CopyUpt(s, dst);
ff.Next();
}
}
void UpdateList(String &list, const Vector<String> &files)
{
for(int i = 0; i < files.GetCount(); i++)
list += " " + files[i];
}
void CopyFolders(const char *src, const char *dst, const char *folders, bool deep = true)
{
Vector<String> folder = Split(folders, ';');
for(int i = 0; i < folder.GetCount(); i++)
CopyFolder(AFN(src, folder[i]), AFN(outdir, AFN(dst, folder[i])), deep);
}
bool ShowFtpProgress()
{
int a = ftp.GetSavePos();
int b = ftp.GetSaveTotal();
Cout() << Sprintf("%d %%, %d bytes (%d total) \r", a * 100 / b, a, b);
return false;
}
void Error(const char *s)
{
Cout() << "\n## ERROR " << s << '\n';
throw Exc();
}
void SfSave(const char *fn)
{
ftp.WhenProgress = callback(ShowFtpProgress);
Cout() << Sprintf("connecting to sf.net...");
if(!ftp.Connect("upload.sourceforge.net", "anonymous", "", true))
Error("Unable to connect to sf.net: " + ftp.GetError());
Cout() << Sprintf("connected\n");
if(!ftp.Cd("incoming"))
Error("FTP error (cd incoming): " + ftp.GetError());
Cout() << Sprintf("uploading %s\n", fn);
if(!ftp.Save(GetFileName(fn), LoadFile(fn)))
Error("FTP error (file upload): " + ftp.GetError());
Cout() << Sprintf("OK: %s uploaded\n", fn);
}
String OutDir(const char *fn)
{
return AFN(outdir, fn);
}
void CopyFile(const char *src, const char *dst)
{
SaveFile(dst, LoadFile(src));
}
String Quote(const String& s)
{
String t;
for(int i = 0; i < s.GetLength(); i++)
if(s[i] == '\\')
t += "\\\\";
else
t += s[i];
return t;
}
void SaveVar(const String &path, const String &var = Null)
{
String upp = IsNull(var) ? "UPP = \"" + Quote(OutDir("u\\uppsrc")) + "\";\n"
: "UPP = \"" + Quote(OutDir(var)) + ';' + Quote(OutDir("u\\uppsrc")) + "\";\n";
SaveFile(path, upp + "COMMON = \"" + Quote(OutDir("u\\common")) + "\";\n" +
"OUTPUT = \"" + Quote(OutDir("out")) + "\";\n");
}
GUI_APP_MAIN
{
try
{
WithInstallLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, "MakeInstall");
for(int i = 0; i <= 5; ++i)
dlg.checkpoint.Add(i , AsString(i));
dlg.checkpoint = GetCheckpoint();
dlg.builder <<= builder;
dlg.builder_gcc <<= builder_gcc;
dlg.version <<= version;
dlg.outdir <<= outdir;
dlg.uppdir <<= uppdir;
dlg.uppsrc <<= uppsrc;
dlg.examples <<= examples;
dlg.reference <<= reference;
dlg.tutorial <<= tutorial;
dlg.bazaar <<= bazaar;
dlg.outdir <<= outdir;
dlg.uppdir <<= uppdir;
dlg.theide <<= theide;
dlg.mingw <<= mingw;
dlg.sdl <<= sdl;
dlg.wi <<= wi;
dlg.wipackage <<= wipackage;
dlg.sevenzipdir <<= sevenzipdir;
dlg.rebuild_all = rebuildall;
LoadFromFile(dlg);
int c = dlg.Execute();
StoreToFile(dlg);
if(c != IDOK)
return;
AllocConsole();
builder = ~dlg.builder;
builder_gcc = ~dlg.builder_gcc;
version = ~dlg.version;
outdir = ~dlg.outdir;
uppdir = ~dlg.uppdir;
uppsrc = ~dlg.uppsrc;
examples = ~dlg.examples;
reference = ~dlg.reference;
tutorial = ~dlg.tutorial;
bazaar = ~dlg.bazaar;
mingw = ~dlg.mingw;
sdl = ~dlg.sdl;
theide = ~dlg.theide;
wi = ~dlg.wi;
wipackage = ~dlg.wipackage;
rebuildall = dlg.rebuild_all;
sevenzipdir = ~dlg.sevenzipdir;
String sevenzipfile = sevenzipdir;
if(sevenzipfile != "")
{
sevenzipfile = "\"" + sevenzipfile + "\\7z\"";
} else {
sevenzipfile = "7z";
}
vdir = AFN(outdir, version);
String packages =
" common"
" examples"
" reference"
" tutorial"
" bazaar"
" uppsrc";
String libs =
" sdl";
String compiler_mingw =
" mingw";
String idefiles =
" theide.exe"
" umk.exe"
" dbghelp.dll"
" install.upp"
" en-us.scd"
" en-gb.scd"
" license.chk";
String uppmingw = AFN(vdir, "upp-mingw-" + version + ".exe");
String uppwin = AFN(vdir, "upp-win-" + version + ".exe");
String uppsource = AFN(vdir, "upp-src-" + version + ".zip");
Vector<String> upp_examples;
Vector<String> upp_reference;
Vector<String> upp_tutorial;
if(dlg.use_checkpoint)
{
if(upt.IsEmpty())
{
ScanUpt(uppsrc, upt);
UpdateList(idefiles, upt);
if(upt.IsEmpty())
{
Exclamation("Upt files not found");
return;
}
}
switch((int)~dlg.checkpoint)
{
case 1: goto checkpoint_1;
case 2: goto checkpoint_2;
case 3: goto checkpoint_3;
case 4: goto checkpoint_4;
case 5: goto checkpoint_5;
}
}
SaveCheckpoint(Null);
DeleteFolderDeep(vdir);
RealizeDirectory(vdir);
Cout() << "Removing files...\n";
DeleteFolderDeep(OutDir("u"));
DeleteFolderDeep(OutDir("out"));
DeleteFile(AFN(outdir, "checkpoint.tmp"));
DeleteFile(AFN(outdir, "upp-win.7z"));
DeleteFile(AFN(outdir, "upp-mingw.7z"));
Cout() << "Copying uppsrc...\n";
CopyFolders(uppsrc, "u/uppsrc",
"ide;IconDes;Topic;CtrlLib;HexView;Esc;CodeEditor;Core;RichEdit;RichText;"
"Draw;coff;CppBase;CtrlCore;Report;"
"MySql;Ole;OleDB;Oracle;Sql;SqlCommander;SqlCtrl;Updater;"
"PdfDraw;PostgreSQL;GLCtrl;DropGrid;CbGen;Crypto;"
"plugin;BuildAll;"
"Geom;umk;GridCtrl;AllForI18n;art"
);
CopyFolders(uppsrc, "u/uppsrc", "Web;Web/TServ;Web/SSL", false);
Cout() << "Copying upt's...\n";
CopyUpt(uppsrc, AFN(outdir, "u"));
UpdateList(idefiles, upt);
Cout() << idefiles << '\n';
SaveFile(AFN(outdir, "u/uppsrc/ide/version.h"), "#define IDE_VERSION \"" + version + "\"\n");
Cout() << "Copying examples...\n";
CopyFolder(examples, OutDir("u/examples"));
Cout() << "Copying reference...\n";
CopyFolder(reference, OutDir("u/reference"));
Cout() << "Copying tutorial...\n";
CopyFolder(tutorial, OutDir("u/tutorial"));
Cout() << "Copying bazaar...\n";
CopyFolder(bazaar, OutDir("u/bazaar"));
Cout() << "Copying common...\n";
CopyFolder(AFN(uppsrc, "Common"), OutDir("u/Common"));
if(dlg.make_mingw || dlg.make_win)
{
Cout() << "Copying sdl...\n";
CopyFolder(sdl, OutDir("u/sdl"));
}
if(dlg.make_mingw)
{
Cout() << "Copying mingw...\n";
CopyFolder(mingw, OutDir("u/mingw"));
}
CHECKPOINT(1):
if(dlg.test_mingw)
{
ScanUpp(OutDir("u\\examples"), upp_examples);
ScanUpp(OutDir("u\\reference"), upp_reference);
ScanUpp(OutDir("u\\tutorial"), upp_tutorial);
DUMPC(upp_examples);
DUMPC(upp_reference);
DUMPC(upp_tutorial);
if(upp_examples.IsEmpty() ||
upp_reference.IsEmpty() ||
upp_tutorial.IsEmpty())
throw Exc("Upp not found");
String opt = dlg.test_mingw_blitz == 1 ? " -b " : "";
String bgcc = " " + builder_gcc + " ";
if(dlg.test_mingw_ide)
{
SaveVar(AFN(theide, "upptmp.var"));
Sys(theide + "\\umk upptmp ide" + bgcc + opt);
}
if(dlg.test_mingw_examples)
{
SaveVar(AFN(theide, "upptmp.var"), "u\\examples");
for(int i = 0; i < upp_examples.GetCount(); i++)
SysPass(theide + "\\umk upptmp " + upp_examples[i] + bgcc + opt);
}
if(dlg.test_mingw_reference)
{
SaveVar(AFN(theide, "upptmp.var"), "u\\reference");
for(int i = 0; i < upp_reference.GetCount(); i++)
SysPass(theide + "\\umk upptmp " + upp_reference[i] + bgcc + opt);
}
if(dlg.test_mingw_tutorial)
{
SaveVar(AFN(theide, "upptmp.var"), "u\\tutorial");
for(int i = 0; i < upp_tutorial.GetCount(); i++)
SysPass(theide + "\\umk upptmp " + upp_tutorial[i] + bgcc + opt);
}
if(iserror)
throw Exc("MinGW error");
}
if(dlg.make_mingw || dlg.make_win)
{
SaveVar(AFN(theide, "upptmp.var"));
String opt = rebuildall ? "-arm " : "-rm ";
Sys(theide + "\\umk upptmp ide " + builder + " " + opt + " " + OutDir("u/theide.exe"));
Sys(theide + "\\umk upptmp umk " + builder + " -arm " + OutDir("u/umk.exe"));
MoveFile(AFN(outdir, "u/theide.map"), AFN(vdir, "theide.map"));
MoveFile(AFN(outdir, "u/umk.map"), AFN(vdir, "umk.map"));
CopyFile(AFN(theide, "dbghelp.dll"), AFN(outdir, "u/dbghelp.dll"));
SaveFile(AFN(outdir, "u/install.upp"), LoadFile(AFN(uppsrc, "install.upp")));
CopyFile(AFN(theide, "en-us.scd"), AFN(outdir, "u/en-us.scd"));
CopyFile(AFN(theide, "en-gb.scd"), AFN(outdir, "u/en-gb.scd"));
SaveFile(AFN(outdir, "u/license.chk"), "1");
}
CHECKPOINT(2):
DeleteFolderDeep(vdir);
RealizeDirectory(vdir);
if(dlg.make_mingw)
{
String outfile = AFN(outdir, "upp-mingw.7z");
if(!FileExists(outfile))
{
SetCurrentDirectory(AFN(outdir, "u"));
Sys(sevenzipfile + " a -r -mx -m0fb=255 -mf=off " + outfile + packages + libs + compiler_mingw + idefiles);
}
SaveFile(AFN(wi, "data.rc"), "1112 RCDATA MOVEABLE PURE \"" + Quote(outfile) + "\"");
SetCurrentDirectory(theide);
Sys(theide + "\\umk " + wipackage + " WinInstaller2 " + builder + " -ar " + uppmingw);
}
CHECKPOINT(3):
if(dlg.make_win)
{
String outfile = AFN(outdir, "upp-win.7z");
if(!FileExists(outfile))
{
SetCurrentDirectory(AFN(outdir, "u"));
Sys(sevenzipfile + " a -r -mx -m0fb=255 -mf=off " + outfile + packages + libs + idefiles);
}
SaveFile(AFN(wi, "data.rc"), "1112 RCDATA MOVEABLE PURE \"" + Quote(outfile) + "\"");
SetCurrentDirectory(theide);
Sys(theide + "\\umk " + wipackage + " WinInstaller2 " + builder + " -ar " + uppwin);
}
CHECKPOINT(4):
if(dlg.make_src)
{
SetCurrentDirectory(AFN(outdir, "u"));
Sys(sevenzipfile + " a -tzip -r " + uppsource + packages);
}
CHECKPOINT(5):
if(dlg.upload)
{
if(!IsNull(dlg.hour))
{
Time tm = GetSysTime();
Time tmu = tm;
tmu.hour = (int)~dlg.hour;
if(tmu < tm)
tmu += 86400;
int ws = int(tmu - tm);
Cout() << "Waiting " << ws << " second until " << tmu << '\n';
Sleep(ws * 1000);
}
Cout() << "*** Uploading started at " << GetSysTime() << '\n';
if(dlg.make_mingw)
SfSave(uppmingw);
if(dlg.make_win)
SfSave(uppwin);
if(dlg.make_src)
SfSave(uppsource);
Cout() << "*** Uploading finished at " << GetSysTime() << '\n';
}
Cout() << Sprintf("*** OK\n");
PromptOK("Release successfull");
}
catch(Exc &e)
{
Exclamation(DeQtfLf(e));
}
catch(...)
{
Exclamation("Error!");
}
}

View file

@ -0,0 +1,14 @@
description "Install creator v.3";
uses
plugin\bz2,
Core,
plugin\ftp,
CtrlLib;
file
install.lay,
Main.cpp;
mainconfig
"" = "GUI";

View file

@ -0,0 +1,57 @@
LAYOUT(InstallLayout, 596, 356)
ITEM(Label, dv___0, SetLabel(t_("upp root")).LeftPosZ(12, 88).TopPosZ(16, 19))
ITEM(EditDir, uppdir, LeftPosZ(104, 184).TopPosZ(16, 19))
ITEM(Label, dv___2, SetLabel(t_("uppsrc")).LeftPosZ(12, 88).TopPosZ(40, 19))
ITEM(EditDir, uppsrc, LeftPosZ(104, 184).TopPosZ(40, 19))
ITEM(Label, dv___4, SetLabel(t_("examples")).LeftPosZ(12, 88).TopPosZ(64, 19))
ITEM(EditDir, examples, LeftPosZ(104, 184).TopPosZ(64, 19))
ITEM(Label, dv___6, SetLabel(t_("reference")).LeftPosZ(12, 88).TopPosZ(88, 19))
ITEM(EditDir, reference, LeftPosZ(104, 184).TopPosZ(88, 19))
ITEM(Label, dv___8, SetLabel(t_("tutorial")).LeftPosZ(12, 88).TopPosZ(112, 19))
ITEM(EditDir, tutorial, LeftPosZ(104, 184).TopPosZ(112, 19))
ITEM(Label, dv___10, SetLabel(t_("bazaar")).LeftPosZ(12, 88).TopPosZ(136, 19))
ITEM(EditDir, bazaar, LeftPosZ(104, 184).TopPosZ(136, 19))
ITEM(Label, dv___12, SetLabel(t_("MinGW")).LeftPosZ(12, 88).TopPosZ(160, 19))
ITEM(EditDir, mingw, LeftPosZ(104, 184).TopPosZ(160, 19))
ITEM(Label, dv___14, SetLabel(t_("SDL")).LeftPosZ(12, 88).TopPosZ(184, 19))
ITEM(EditDir, sdl, LeftPosZ(104, 184).TopPosZ(184, 19))
ITEM(Label, dv___16, SetLabel(t_("7-Zip folder")).LeftPosZ(12, 88).TopPosZ(208, 19))
ITEM(EditDir, sevenzipdir, LeftPosZ(104, 184).TopPosZ(208, 19))
ITEM(Label, dv___18, SetLabel(t_("TheIDE, umk")).LeftPosZ(308, 88).TopPosZ(40, 19))
ITEM(EditDir, theide, LeftPosZ(400, 184).TopPosZ(40, 19))
ITEM(Label, dv___20, SetLabel(t_("U++ VERSION")).SetFont(StdFontZ(11).Bold()).LeftPosZ(308, 88).TopPosZ(64, 19))
ITEM(EditString, version, LeftPosZ(400, 184).TopPosZ(64, 19))
ITEM(Label, dv___22, SetLabel(t_("Main builder")).SetFont(StdFontZ(11)).LeftPosZ(308, 88).TopPosZ(88, 19))
ITEM(EditString, builder, LeftPosZ(400, 184).TopPosZ(88, 19))
ITEM(Label, dv___24, SetLabel(t_("GCC builder")).SetFont(StdFontZ(11)).LeftPosZ(308, 88).TopPosZ(112, 19))
ITEM(EditString, builder_gcc, LeftPosZ(400, 184).TopPosZ(112, 19))
ITEM(LabelBox, dv___26, SetLabel(t_("Sources")).LeftPosZ(4, 292).TopPosZ(0, 232))
ITEM(EditDir, wi, LeftPosZ(400, 184).TopPosZ(248, 19))
ITEM(Label, dv___28, SetLabel(t_("Package")).LeftPosZ(308, 88).TopPosZ(272, 19))
ITEM(EditString, wipackage, LeftPosZ(400, 184).TopPosZ(272, 19))
ITEM(Label, dv___30, SetLabel(t_("Sources")).LeftPosZ(308, 88).TopPosZ(248, 19))
ITEM(Option, make_mingw, SetLabel(t_("Create upp-mingw")).LeftPosZ(12, 116).TopPosZ(252, 15))
ITEM(Option, make_win, SetLabel(t_("Create upp-win")).LeftPosZ(12, 116).TopPosZ(272, 15))
ITEM(Option, make_src, SetLabel(t_("Create upp-src")).LeftPosZ(140, 116).TopPosZ(252, 15))
ITEM(Option, use_checkpoint, SetLabel(t_("Start from last checkpoint")).LeftPosZ(308, 144).TopPosZ(304, 19))
ITEM(DropList, checkpoint, LeftPosZ(456, 60).TopPosZ(304, 19))
ITEM(Option, test_mingw, SetLabel(t_("Test mingw")).HSizePosZ(308, 200).TopPosZ(180, 15))
ITEM(Option, test_mingw_blitz, SetLabel(t_("Blitz")).HSizePosZ(400, 156).TopPosZ(180, 15))
ITEM(Option, test_mingw_compile_only, SetLabel(t_("Compile only")).HSizePosZ(496, 20).TopPosZ(180, 15))
ITEM(Option, test_mingw_ide, SetLabel(t_("TheIDE")).HSizePosZ(308, 208).TopPosZ(196, 15))
ITEM(Option, test_mingw_examples, SetLabel(t_("Examples")).HSizePosZ(308, 208).TopPosZ(212, 15))
ITEM(Option, test_mingw_reference, SetLabel(t_("Reference")).HSizePosZ(400, 116).TopPosZ(196, 15))
ITEM(Option, test_mingw_tutorial, SetLabel(t_("Tutorial")).HSizePosZ(400, 116).TopPosZ(212, 15))
ITEM(Option, rebuild_all, SetLabel(t_("Rebuild all (TheIde)")).LeftPosZ(400, 184).TopPosZ(136, 15))
ITEM(Option, upload, SetLabel(t_("Upload at")).LeftPosZ(12, 72).TopPosZ(304, 20))
ITEM(EditInt, hour, Min(1).Max(24).LeftPosZ(84, 36).TopPosZ(304, 19))
ITEM(Label, dv___46, SetLabel(t_(":00")).LeftPosZ(124, 25).TopPosZ(304, 19))
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(4, 96).BottomPosZ(4, 24))
ITEM(Button, ok, SetLabel(t_("MakeInstall!")).RightPosZ(104, 96).BottomPosZ(4, 24))
ITEM(LabelBox, dv___49, SetLabel(t_("Create")).LeftPosZ(4, 292).TopPosZ(236, 60))
ITEM(LabelBox, dv___50, SetLabel(t_("Test")).HSizePosZ(300, 4).TopPosZ(164, 68))
ITEM(LabelBox, dv___51, SetLabel(t_("Build")).LeftPosZ(300, 292).TopPosZ(0, 156))
ITEM(LabelBox, dv___52, SetLabel(t_("WinInstaller")).LeftPosZ(300, 292).TopPosZ(236, 60))
ITEM(Label, dv___53, SetLabel(t_("Output")).LeftPosZ(308, 88).TopPosZ(16, 19))
ITEM(EditDir, outdir, LeftPosZ(400, 184).TopPosZ(16, 19))
END_LAYOUT

8
uppbox/Pcre/Pcre.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef _plugin_pcre_pcre_h_
#define _plugin_pcre_pcre_h_
#include <Core/Core.h>
#include "lib/pcre.h"
#include "RegExp.h"
#endif

32
uppbox/Pcre/Pcre.upp Normal file
View file

@ -0,0 +1,32 @@
options
"-DSUPPORT_UTF8 -DSUPPORT_UCP";
file
Pcre.h,
RegExp.h,
RegExp.cpp,
PCRE readonly separator,
lib/config.h,
lib/pcre.h,
lib/pcre_chartables.c,
lib/pcre_compile.c,
lib/pcre_config.c,
lib/pcre_dfa_exec.c,
lib/pcre_exec.c,
lib/pcre_fullinfo.c,
lib/pcre_get.c,
lib/pcre_globals.c,
lib/pcre_info.c,
lib/pcre_internal.h,
lib/pcre_maketables.c,
lib/pcre_ord2utf8.c,
lib/pcre_refcount.c,
lib/pcre_study.c,
lib/pcre_tables.c,
lib/pcre_try_flipped.c,
lib/pcre_ucp_searchfuncs.c,
lib/pcre_valid_utf8.c,
lib/pcre_version.c,
lib/pcre_xclass.c,
lib/ucp.h,
lib/ucpinternal.h;

142
uppbox/Pcre/RegExp.cpp Normal file
View file

@ -0,0 +1,142 @@
#include "pcre.h"
RegExp::RegExp(int options)
{
Clear();
SetOptions(options);
}
RegExp::RegExp(const char * p, int options)
{
Clear();
SetOptions(options);
SetPattern(p);
}
RegExp::RegExp(const String &p, int options)
{
Clear();
SetOptions(options);
SetPattern(p);
}
RegExp::~RegExp()
{
Clear(true);
}
void RegExp::Clear(bool freemem)
{
if(freemem && cpattern)
pcre_free(cpattern);
first = false;
cpattern = NULL;
rc = 0;
compile_options = 0;
execute_options = 0;
error_code = 0;
}
void RegExp::SetOptions(int options)
{
if(options & UNICODE)
compile_options |= UNICODE;
if(options & CASELESS)
compile_options |= CASELESS;
if(options & UNGREEDY)
compile_options |= UNGREEDY;
if(options & MULTILINE)
compile_options |= MULTILINE;
if(options & PARTIAL)
execute_options = PARTIAL;
}
void RegExp::SetPattern(const char * p)
{
pattern = p;
}
void RegExp::SetPattern(const String &p)
{
pattern = p;
}
bool RegExp::Compile(bool recompile)
{
if(cpattern)
{
if(recompile)
pcre_free(cpattern);
else
return true;
}
cpattern = pcre_compile2(pattern, compile_options, &error_code, &error_string, &error_offset, NULL);
return error_code == 0;
}
int RegExp::Execute(const String &t, int offset)
{
rc = pcre_exec(cpattern, NULL, t, t.GetLength(), offset, execute_options, pos, 30);
if(rc <= 0)
first = false;
return rc;
}
bool RegExp::Match(const String &t, bool copy)
{
if(copy)
text = t;
if(!Compile())
return false;
return Execute(t) > 0;
}
bool RegExp::FastMatch(const String &t)
{
return Match(t, false);
}
bool RegExp::GlobalMatch(const String &t)
{
if(!first)
{
first = true;
return Match(t);
}
int offset = pos[1];
if(pos[0] == pos[1])
{
if(pos[0] == t.GetLength())
{
first = false;
return false;
}
execute_options |= PCRE_NOTEMPTY | PCRE_ANCHORED;
}
return Execute(t, offset) > 0;
}
String RegExp::operator[](const int i)
{
return GetString(i);
}
int RegExp::GetCount()
{
return rc - 1;
}
Vector<String> RegExp::GetStrings()
{
Vector<String> subs;
for(int i = 0; i < GetCount(); i++)
subs.Add(GetString(i));
return subs;
}
String RegExp::GetString(int i)
{
i = 2 * (i + 1);
return text.Mid(pos[i], pos[i + 1] - pos[i]);
}

56
uppbox/Pcre/RegExp.h Normal file
View file

@ -0,0 +1,56 @@
#ifndef _PcreTest_RegExp_h_
#define _PcreTest_RegExp_h_
//#include <Core/Core.h>
class RegExp : public Moveable<RegExp> {
public:
enum
{
PARTIAL = PCRE_PARTIAL,
/* compile options */
UNICODE = PCRE_UTF8,
CASELESS = PCRE_CASELESS,
MULTILINE = PCRE_MULTILINE,
UNGREEDY = PCRE_UNGREEDY
};
private:
String pattern;
String text;
pcre * cpattern;
const char * error_string;
int error_offset;
int error_code;
int pos[30];
int rc;
bool first;
int compile_options;
int execute_options;
public:
RegExp(int options = UNICODE);
RegExp(const char * p, int options = UNICODE);
RegExp(const String &p, int options = UNICODE);
~RegExp();
void Clear(bool freemem = false);
void SetOptions(int options);
void SetPattern(const char * p);
void SetPattern(const String &p);
bool Compile(bool recompile = false);
int Execute(const String &t, int offset = 0);
bool Match(const String &t, bool copy = true);
bool FastMatch(const String &t);
bool GlobalMatch(const String &t);
String operator[](const int i);
int GetCount();
Vector<String> GetStrings();
String GetString(int i);
bool IsError() { return error_code != 0; }
const char * GetError() { return error_string; }
int GetErrorCode() { return error_code; }
};
#endif

127
uppbox/Pcre/lib/config.h Normal file
View file

@ -0,0 +1,127 @@
/* On Unix-like systems config.in is converted by "configure" into config.h.
Some other environments also support the use of "configure". PCRE is written in
Standard C, but there are a few non-standard things it can cope with, allowing
it to run on SunOS4 and other "close to standard" systems.
On a non-Unix-like system you should just copy this file into config.h, and set
up the macros the way you need them. You should normally change the definitions
of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way
autoconf works, these cannot be made the defaults. If your system has bcopy()
and not memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE.
If your system has neither bcopy() nor memmove(), leave them both as 0; an
emulation function will be used. */
/* If you are compiling for a system that uses EBCDIC instead of ASCII
character codes, define this macro as 1. On systems that can use "configure",
this can be done via --enable-ebcdic. */
#ifndef EBCDIC
#define EBCDIC 0
#endif
/* If you are compiling for a system other than a Unix-like system or Win32,
and it needs some magic to be inserted before the definition of a function that
is exported by the library, define this macro to contain the relevant magic. If
you do not define this macro, it defaults to "extern" for a C compiler and
"extern C" for a C++ compiler on non-Win32 systems. This macro apears at the
start of every exported function that is part of the external API. It does not
appear on functions that are "external" in the C sense, but which are internal
to the library. */
/* #define PCRE_DATA_SCOPE */
/* Define the following macro to empty if the "const" keyword does not work. */
#undef const
/* Define the following macro to "unsigned" if <stddef.h> does not define
size_t. */
#undef size_t
/* The following two definitions are mainly for the benefit of SunOS4, which
does not have the strerror() or memmove() functions that should be present in
all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should
normally be defined with the value 1 for other systems, but unfortunately we
cannot make this the default because "configure" files generated by autoconf
will only change 0 to 1; they won't change 1 to 0 if the functions are not
found. */
#define HAVE_STRERROR 1
#define HAVE_MEMMOVE 1
/* There are some non-Unix-like systems that don't even have bcopy(). If this
macro is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of
HAVE_BCOPY is not relevant. */
#define HAVE_BCOPY 0
/* The value of NEWLINE determines the newline character. The default is to
leave it up to the compiler, but some sites want to force a particular value.
On Unix-like systems, "configure" can be used to override this default. */
#ifndef NEWLINE
#define NEWLINE '\n'
#endif
/* The value of LINK_SIZE determines the number of bytes used to store links as
offsets within the compiled regex. The default is 2, which allows for compiled
patterns up to 64K long. This covers the vast majority of cases. However, PCRE
can also be compiled to use 3 or 4 bytes instead. This allows for longer
patterns in extreme cases. On systems that support it, "configure" can be used
to override this default. */
#ifndef LINK_SIZE
#define LINK_SIZE 2
#endif
/* When calling PCRE via the POSIX interface, additional working storage is
required for holding the pointers to capturing substrings because PCRE requires
three integers per substring, whereas the POSIX interface provides only two. If
the number of expected substrings is small, the wrapper function uses space on
the stack, because this is faster than using malloc() for each call. The
threshold above which the stack is no longer used is defined by POSIX_MALLOC_
THRESHOLD. On systems that support it, "configure" can be used to override this
default. */
#ifndef POSIX_MALLOC_THRESHOLD
#define POSIX_MALLOC_THRESHOLD 10
#endif
/* PCRE uses recursive function calls to handle backtracking while matching.
This can sometimes be a problem on systems that have stacks of limited size.
Define NO_RECURSE to get a version that doesn't use recursion in the match()
function; instead it creates its own stack by steam using pcre_recurse_malloc()
to obtain memory from the heap. For more detail, see the comments and other
stuff just above the match() function. On systems that support it, "configure"
can be used to set this in the Makefile (use --disable-stack-for-recursion). */
/* #define NO_RECURSE */
/* The value of MATCH_LIMIT determines the default number of times the internal
match() function can be called during a single execution of pcre_exec(). There
is a runtime interface for setting a different limit. The limit exists in order
to catch runaway regular expressions that take for ever to determine that they
do not match. The default is set very large so that it does not accidentally
catch legitimate cases. On systems that support it, "configure" can be used to
override this default default. */
#ifndef MATCH_LIMIT
#define MATCH_LIMIT 10000000
#endif
/* The above limit applies to all calls of match(), whether or not they
increase the recursion depth. In some environments it is desirable to limit the
depth of recursive calls of match() more strictly, in order to restrict the
maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The
value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To
have any useful effect, it must be less than the value of MATCH_LIMIT. There is
a runtime method for setting a different limit. On systems that support it,
"configure" can be used to override this default default. */
#ifndef MATCH_LIMIT_RECURSION
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
#endif
/* End */

284
uppbox/Pcre/lib/pcre.h Normal file
View file

@ -0,0 +1,284 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.
Copyright (c) 1997-2005 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
#ifndef _PCRE_H
#define _PCRE_H
/* The current PCRE version information. */
/* NOTES FOR FUTURE MAINTAINERS: Do not use numbers with leading zeros, because
they may be treated as octal constants. The PCRE_PRERELEASE feature is for
identifying release candidates. It might be defined as -RC2, for example. In
real releases, it should be defined empty. Do not change the alignment of these
statments. The code in ./configure greps out the version numbers by using "cut"
to get values from column 29 onwards. These are substituted into pcre-config
and libpcre.pc. The values are not put into configure.ac and substituted here
(which would simplify this issue) because that makes life harder for those who
cannot run ./configure. As it now stands, this file need not be edited in that
circumstance. */
#define PCRE_MAJOR 6
#define PCRE_MINOR 6
#define PCRE_PRERELEASE
#define PCRE_DATE 06-Feb-2006
/* Pcre is linked statically on any OS. */
/*
#ifdef _WIN32
# ifdef PCRE_DEFINITION
# ifdef DLL_EXPORT
# define PCRE_DATA_SCOPE __declspec(dllexport)
# endif
# else
# ifndef PCRE_STATIC
# define PCRE_DATA_SCOPE extern __declspec(dllimport)
# endif
# endif
#endif
*/
/* Otherwise, we use the standard "extern". */
#ifndef PCRE_DATA_SCOPE
# ifdef __cplusplus
# define PCRE_DATA_SCOPE extern "C"
# else
# define PCRE_DATA_SCOPE extern
# endif
#endif
/* Have to include stdlib.h in order to ensure that size_t is defined;
it is needed here for malloc. */
#include <stdlib.h>
/* Allow for C++ users */
#ifdef __cplusplus
extern "C" {
#endif
/* Options */
#define PCRE_CASELESS 0x00000001
#define PCRE_MULTILINE 0x00000002
#define PCRE_DOTALL 0x00000004
#define PCRE_EXTENDED 0x00000008
#define PCRE_ANCHORED 0x00000010
#define PCRE_DOLLAR_ENDONLY 0x00000020
#define PCRE_EXTRA 0x00000040
#define PCRE_NOTBOL 0x00000080
#define PCRE_NOTEOL 0x00000100
#define PCRE_UNGREEDY 0x00000200
#define PCRE_NOTEMPTY 0x00000400
#define PCRE_UTF8 0x00000800
#define PCRE_NO_AUTO_CAPTURE 0x00001000
#define PCRE_NO_UTF8_CHECK 0x00002000
#define PCRE_AUTO_CALLOUT 0x00004000
#define PCRE_PARTIAL 0x00008000
#define PCRE_DFA_SHORTEST 0x00010000
#define PCRE_DFA_RESTART 0x00020000
#define PCRE_FIRSTLINE 0x00040000
/* Exec-time and get/set-time error codes */
#define PCRE_ERROR_NOMATCH (-1)
#define PCRE_ERROR_NULL (-2)
#define PCRE_ERROR_BADOPTION (-3)
#define PCRE_ERROR_BADMAGIC (-4)
#define PCRE_ERROR_UNKNOWN_NODE (-5)
#define PCRE_ERROR_NOMEMORY (-6)
#define PCRE_ERROR_NOSUBSTRING (-7)
#define PCRE_ERROR_MATCHLIMIT (-8)
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
#define PCRE_ERROR_BADUTF8 (-10)
#define PCRE_ERROR_BADUTF8_OFFSET (-11)
#define PCRE_ERROR_PARTIAL (-12)
#define PCRE_ERROR_BADPARTIAL (-13)
#define PCRE_ERROR_INTERNAL (-14)
#define PCRE_ERROR_BADCOUNT (-15)
#define PCRE_ERROR_DFA_UITEM (-16)
#define PCRE_ERROR_DFA_UCOND (-17)
#define PCRE_ERROR_DFA_UMLIMIT (-18)
#define PCRE_ERROR_DFA_WSSIZE (-19)
#define PCRE_ERROR_DFA_RECURSE (-20)
#define PCRE_ERROR_RECURSIONLIMIT (-21)
/* Request types for pcre_fullinfo() */
#define PCRE_INFO_OPTIONS 0
#define PCRE_INFO_SIZE 1
#define PCRE_INFO_CAPTURECOUNT 2
#define PCRE_INFO_BACKREFMAX 3
#define PCRE_INFO_FIRSTBYTE 4
#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
#define PCRE_INFO_FIRSTTABLE 5
#define PCRE_INFO_LASTLITERAL 6
#define PCRE_INFO_NAMEENTRYSIZE 7
#define PCRE_INFO_NAMECOUNT 8
#define PCRE_INFO_NAMETABLE 9
#define PCRE_INFO_STUDYSIZE 10
#define PCRE_INFO_DEFAULT_TABLES 11
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
#define PCRE_CONFIG_UTF8 0
#define PCRE_CONFIG_NEWLINE 1
#define PCRE_CONFIG_LINK_SIZE 2
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
#define PCRE_CONFIG_MATCH_LIMIT 4
#define PCRE_CONFIG_STACKRECURSE 5
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
these bits, just add new ones on the end, in order to remain compatible. */
#define PCRE_EXTRA_STUDY_DATA 0x0001
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
#define PCRE_EXTRA_TABLES 0x0008
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
/* Types */
struct real_pcre; /* declaration; the definition is private */
typedef struct real_pcre pcre;
/* When PCRE is compiled as a C++ library, the subject pointer type can be
replaced with a custom type. For conventional use, the public interface is a
const char *. */
#ifndef PCRE_SPTR
#define PCRE_SPTR const char *
#endif
/* The structure for passing additional data to pcre_exec(). This is defined in
such as way as to be extensible. Always add new fields at the end, in order to
remain compatible. */
typedef struct pcre_extra {
unsigned long int flags; /* Bits for which fields are set */
void *study_data; /* Opaque data from pcre_study() */
unsigned long int match_limit; /* Maximum number of calls to match() */
void *callout_data; /* Data passed back in callouts */
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
} pcre_extra;
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
without modification. */
typedef struct pcre_callout_block {
int version; /* Identifies version of block */
/* ------------------------ Version 0 ------------------------------- */
int callout_number; /* Number compiled into pattern */
int *offset_vector; /* The offset vector */
PCRE_SPTR subject; /* The subject being matched */
int subject_length; /* The length of the subject */
int start_match; /* Offset to start of this match attempt */
int current_position; /* Where we currently are in the subject */
int capture_top; /* Max current capture */
int capture_last; /* Most recently closed capture */
void *callout_data; /* Data passed in with the call */
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
/* ------------------------------------------------------------------ */
} pcre_callout_block;
/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. Special ones are used in the
non-recursive case for "frames". There is also an optional callout function
that is triggered by the (?) regex item. For Virtual Pascal, these definitions
have to take another form. */
#ifndef VPCOMPAT
PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);
PCRE_DATA_SCOPE void (*pcre_free)(void *);
PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t);
PCRE_DATA_SCOPE void (*pcre_stack_free)(void *);
PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);
#else /* VPCOMPAT */
PCRE_DATA_SCOPE void *pcre_malloc(size_t);
PCRE_DATA_SCOPE void pcre_free(void *);
PCRE_DATA_SCOPE void *pcre_stack_malloc(size_t);
PCRE_DATA_SCOPE void pcre_stack_free(void *);
PCRE_DATA_SCOPE int pcre_callout(pcre_callout_block *);
#endif /* VPCOMPAT */
/* Exported PCRE functions */
PCRE_DATA_SCOPE pcre *pcre_compile(const char *, int, const char **, int *,
const unsigned char *);
PCRE_DATA_SCOPE pcre *pcre_compile2(const char *, int, int *, const char **,
int *, const unsigned char *);
PCRE_DATA_SCOPE int pcre_config(int, void *);
PCRE_DATA_SCOPE int pcre_copy_named_substring(const pcre *, const char *,
int *, int, const char *, char *, int);
PCRE_DATA_SCOPE int pcre_copy_substring(const char *, int *, int, int, char *,
int);
PCRE_DATA_SCOPE int pcre_dfa_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int , int *, int);
PCRE_DATA_SCOPE int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
int, int, int, int *, int);
PCRE_DATA_SCOPE void pcre_free_substring(const char *);
PCRE_DATA_SCOPE void pcre_free_substring_list(const char **);
PCRE_DATA_SCOPE int pcre_fullinfo(const pcre *, const pcre_extra *, int,
void *);
PCRE_DATA_SCOPE int pcre_get_named_substring(const pcre *, const char *,
int *, int, const char *, const char **);
PCRE_DATA_SCOPE int pcre_get_stringnumber(const pcre *, const char *);
PCRE_DATA_SCOPE int pcre_get_substring(const char *, int *, int, int,
const char **);
PCRE_DATA_SCOPE int pcre_get_substring_list(const char *, int *, int,
const char ***);
PCRE_DATA_SCOPE int pcre_info(const pcre *, int *, int *);
PCRE_DATA_SCOPE const unsigned char *pcre_maketables(void);
PCRE_DATA_SCOPE int pcre_refcount(pcre *, int);
PCRE_DATA_SCOPE pcre_extra *pcre_study(const pcre *, int, const char **);
PCRE_DATA_SCOPE const char *pcre_version(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* End of pcre.h */

View file

@ -0,0 +1,183 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* This file is automatically written by the dftables auxiliary
program. If you edit it by hand, you might like to edit the Makefile to
prevent its ever being regenerated.
This file contains the default tables for characters with codes less than
128 (ASCII characters). These tables are used when no external tables are
passed to PCRE. */
const unsigned char _pcre_default_tables[] = {
/* This table is a lower casing table. */
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,
120,121,122, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,
136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,
152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,
168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,
184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,
200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,
232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,
248,249,250,251,252,253,254,255,
/* This table is a case flipping table. */
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,
120,121,122, 91, 92, 93, 94, 95,
96, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90,123,124,125,126,127,
128,129,130,131,132,133,134,135,
136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,
152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,
168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,
184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,
200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,
232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,
248,249,250,251,252,253,254,255,
/* This table contains bit maps for various character classes.
Each map is 32 bytes long and the bits run from the least
significant end of each byte. The classes that have their own
maps are: space, xdigit, digit, upper, lower, word, graph
print, punct, and cntrl. Other classes are built from combinations. */
0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* This table identifies various classes of character by individual bits:
0x01 white space character
0x02 letter
0x04 decimal digit
0x08 hexadecimal digit
0x10 alphanumeric or '_'
0x80 regular expression metacharacter or binary zero
*/
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /* X - _ */
0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
/* End of chartables.c */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
/* This module contains the external function pcre_config(). */
#include "pcre_internal.h"
/*************************************************
* Return info about what features are configured *
*************************************************/
/* This function has an extensible interface so that additional items can be
added compatibly.
Arguments:
what what information is required
where where to put the information
Returns: 0 if data returned, negative on error
*/
PCRE_DATA_SCOPE int
pcre_config(int what, void *where)
{
switch (what)
{
case PCRE_CONFIG_UTF8:
#ifdef SUPPORT_UTF8
*((int *)where) = 1;
#else
*((int *)where) = 0;
#endif
break;
case PCRE_CONFIG_UNICODE_PROPERTIES:
#ifdef SUPPORT_UCP
*((int *)where) = 1;
#else
*((int *)where) = 0;
#endif
break;
case PCRE_CONFIG_NEWLINE:
*((int *)where) = NEWLINE;
break;
case PCRE_CONFIG_LINK_SIZE:
*((int *)where) = LINK_SIZE;
break;
case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
*((int *)where) = POSIX_MALLOC_THRESHOLD;
break;
case PCRE_CONFIG_MATCH_LIMIT:
*((unsigned int *)where) = MATCH_LIMIT;
break;
case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
*((unsigned int *)where) = MATCH_LIMIT_RECURSION;
break;
case PCRE_CONFIG_STACKRECURSE:
#ifdef NO_RECURSE
*((int *)where) = 0;
#else
*((int *)where) = 1;
#endif
break;
default: return PCRE_ERROR_BADOPTION;
}
return 0;
}
/* End of pcre_config.c */

Some files were not shown because too many files have changed in this diff Show more