mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 06:05:58 -06:00
git-svn-id: svn://ultimatepp.org/upp/trunk@332 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6842990fa9
commit
2667dfc1d5
385 changed files with 188873 additions and 2 deletions
110
benchmarks/AllocMT/AllocMT.cpp
Normal file
110
benchmarks/AllocMT/AllocMT.cpp
Normal 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()));
|
||||
}
|
||||
23
benchmarks/AllocMT/AllocMT.upp
Normal file
23
benchmarks/AllocMT/AllocMT.upp
Normal 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";
|
||||
|
||||
938
benchmarks/AllocMT/Chris.cpp
Normal file
938
benchmarks/AllocMT/Chris.cpp
Normal 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
|
||||
315
benchmarks/AllocMT/Chris2.cpp
Normal file
315
benchmarks/AllocMT/Chris2.cpp
Normal 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
5
benchmarks/AllocMT/init
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _AllocMT_icpp_init_stub
|
||||
#define _AllocMT_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#include "CppBase/init"
|
||||
#endif
|
||||
50
benchmarks/AllocMT/result.txt
Normal file
50
benchmarks/AllocMT/result.txt
Normal 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
|
||||
|
||||
71
benchmarks/BiVector/BiVector.cpp
Normal file
71
benchmarks/BiVector/BiVector.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
12
benchmarks/BiVector/BiVector.upp
Normal file
12
benchmarks/BiVector/BiVector.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
optimize_speed;
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
BiVector.cpp,
|
||||
results.txt;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
4
benchmarks/BiVector/init
Normal file
4
benchmarks/BiVector/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _BiVector_icpp_init_stub
|
||||
#define _BiVector_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
9
benchmarks/BiVector/results.txt
Normal file
9
benchmarks/BiVector/results.txt
Normal 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
|
||||
|
||||
=============================
|
||||
54
benchmarks/Bloat/Bloat.cpp
Normal file
54
benchmarks/Bloat/Bloat.cpp
Normal 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
|
||||
}
|
||||
}
|
||||
10
benchmarks/Bloat/Bloat.upp
Normal file
10
benchmarks/Bloat/Bloat.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
data.txt,
|
||||
Bloat.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
8
benchmarks/Bloat/data.txt
Normal file
8
benchmarks/Bloat/data.txt
Normal 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
4
benchmarks/Bloat/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _Bloat_icpp_init_stub
|
||||
#define _Bloat_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
20
benchmarks/NewDelete/NewDelete.cpp
Normal file
20
benchmarks/NewDelete/NewDelete.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
10
benchmarks/NewDelete/NewDelete.upp
Normal file
10
benchmarks/NewDelete/NewDelete.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
NewDelete.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "",
|
||||
"" = "USEMALLOC";
|
||||
|
||||
4
benchmarks/NewDelete/init
Normal file
4
benchmarks/NewDelete/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _NewDelete_icpp_init_stub
|
||||
#define _NewDelete_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
34
benchmarks/NewDeleteTree/NewDeleteTree.cpp
Normal file
34
benchmarks/NewDeleteTree/NewDeleteTree.cpp
Normal 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));
|
||||
}
|
||||
9
benchmarks/NewDeleteTree/NewDeleteTree.upp
Normal file
9
benchmarks/NewDeleteTree/NewDeleteTree.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
NewDeleteTree.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
69
benchmarks/Sort/Sort.cpp
Normal file
69
benchmarks/Sort/Sort.cpp
Normal 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
9
benchmarks/Sort/Sort.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
Sort.cpp optimize_speed;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
4
benchmarks/Sort/init
Normal file
4
benchmarks/Sort/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _Sort_icpp_init_stub
|
||||
#define _Sort_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
33
benchmarks/StringFindOf/StringFindOf.cpp
Normal file
33
benchmarks/StringFindOf/StringFindOf.cpp
Normal 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);
|
||||
}
|
||||
12
benchmarks/StringFindOf/StringFindOf.upp
Normal file
12
benchmarks/StringFindOf/StringFindOf.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
optimize_speed;
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
StringFindOf.cpp,
|
||||
numbers.txt;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
4
benchmarks/StringFindOf/init
Normal file
4
benchmarks/StringFindOf/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _StringFindOf_icpp_init_stub
|
||||
#define _StringFindOf_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
17
benchmarks/StringFindOf/numbers.txt
Normal file
17
benchmarks/StringFindOf/numbers.txt
Normal 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
|
||||
20
benchmarks/benchSBuffer/benchSBuffer.cpp
Normal file
20
benchmarks/benchSBuffer/benchSBuffer.cpp
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
benchmarks/benchSBuffer/benchSBuffer.upp
Normal file
11
benchmarks/benchSBuffer/benchSBuffer.upp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
bsb.h,
|
||||
bsb.cpp,
|
||||
benchSBuffer.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
17
benchmarks/benchSBuffer/bsb.cpp
Normal file
17
benchmarks/benchSBuffer/bsb.cpp
Normal 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;
|
||||
}
|
||||
11
benchmarks/benchSBuffer/bsb.h
Normal file
11
benchmarks/benchSBuffer/bsb.h
Normal 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
|
||||
4
benchmarks/benchSBuffer/init
Normal file
4
benchmarks/benchSBuffer/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _benchSBuffer_icpp_init_stub
|
||||
#define _benchSBuffer_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
57
benchmarks/chris/chris.cpp
Normal file
57
benchmarks/chris/chris.cpp
Normal 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();
|
||||
}
|
||||
10
benchmarks/chris/chris.upp
Normal file
10
benchmarks/chris/chris.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
chris.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "MT",
|
||||
"" = "MT USEMALLOC";
|
||||
|
||||
4
benchmarks/chris/init
Normal file
4
benchmarks/chris/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _chris_icpp_init_stub
|
||||
#define _chris_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
17
benchmarks/idmapBench/idmapBench.upp
Normal file
17
benchmarks/idmapBench/idmapBench.upp
Normal 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";
|
||||
|
||||
4
benchmarks/idmapBench/init
Normal file
4
benchmarks/idmapBench/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _idmapBench_icpp_init_stub
|
||||
#define _idmapBench_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
207
benchmarks/idmapBench/main.cpp
Normal file
207
benchmarks/idmapBench/main.cpp
Normal 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
4
benchmarks/sizeof/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _sizeof_icpp_init_stub
|
||||
#define _sizeof_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
41
benchmarks/sizeof/main.cpp
Normal file
41
benchmarks/sizeof/main.cpp
Normal 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));
|
||||
}
|
||||
6
benchmarks/sizeof/prj.aux
Normal file
6
benchmarks/sizeof/prj.aux
Normal 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;
|
||||
10
benchmarks/sizeof/sizeof.upp
Normal file
10
benchmarks/sizeof/sizeof.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
main.cpp
|
||||
depends() test.h;
|
||||
|
||||
mainconfig
|
||||
"" = "CONSOLE MT";
|
||||
|
||||
15
examples/BlueBar/BlueBar.upp
Normal file
15
examples/BlueBar/BlueBar.upp
Normal 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
275
examples/BlueBar/UWord.cpp
Normal 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));
|
||||
}
|
||||
18
examples/BlueBar/UWord.iml
Normal file
18
examples/BlueBar/UWord.iml
Normal 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
7
examples/BlueBar/init
Normal 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
5
examples/DbfView/init
Normal 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
6
examples/OleCalc/init
Normal 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
4
examples/idmapBench/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _idmapBench_icpp_init_stub
|
||||
#define _idmapBench_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
15
reference/SqlArray/SqlArray.upp
Normal file
15
reference/SqlArray/SqlArray.upp
Normal 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";
|
||||
|
||||
9
reference/SqlArray/app.lay
Normal file
9
reference/SqlArray/app.lay
Normal 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
13
reference/SqlArray/db.sch
Normal 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
6
reference/SqlArray/init
Normal 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
|
||||
70
reference/SqlArray/main.cpp
Normal file
70
reference/SqlArray/main.cpp
Normal 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
141
reference/SqlExp/SqlExp.cpp
Normal 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
|
||||
}
|
||||
14
reference/SqlExp/SqlExp.upp
Normal file
14
reference/SqlExp/SqlExp.upp
Normal 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
6
reference/SqlExp/init
Normal 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
|
||||
129
uppbox/CodeMetric/Analyse.cpp
Normal file
129
uppbox/CodeMetric/Analyse.cpp
Normal 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;
|
||||
}
|
||||
41
uppbox/CodeMetric/Analyse.h
Normal file
41
uppbox/CodeMetric/Analyse.h
Normal 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
|
||||
34
uppbox/CodeMetric/AnalyseGui.h
Normal file
34
uppbox/CodeMetric/AnalyseGui.h
Normal 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
|
||||
18
uppbox/CodeMetric/AnalyseGui.iml
Normal file
18
uppbox/CodeMetric/AnalyseGui.iml
Normal 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")
|
||||
13
uppbox/CodeMetric/CodeMetric.upp
Normal file
13
uppbox/CodeMetric/CodeMetric.upp
Normal 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
153
uppbox/CodeMetric/main.cpp
Normal 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
2
uppbox/CppBase2/AUTHORS
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Mirek Fidler <cxl@ntllib.org>
|
||||
Tomas Rylek <rylek@volny.cz>
|
||||
397
uppbox/CppBase2/Base.cpp
Normal file
397
uppbox/CppBase2/Base.cpp
Normal 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
30
uppbox/CppBase2/COPYING
Normal 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.
|
||||
33
uppbox/CppBase2/COPYING-PLAIN
Normal file
33
uppbox/CppBase2/COPYING-PLAIN
Normal 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
478
uppbox/CppBase2/CppBase.h
Normal 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
|
||||
20
uppbox/CppBase2/CppBase.upp
Normal file
20
uppbox/CppBase2/CppBase.upp
Normal 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
1432
uppbox/CppBase2/Parser.cpp
Normal file
File diff suppressed because it is too large
Load diff
176
uppbox/CppBase2/Pre.cpp
Normal file
176
uppbox/CppBase2/Pre.cpp
Normal 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
421
uppbox/CppBase2/cpplex.cpp
Normal 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
81
uppbox/CppBase2/keyword.i
Normal 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
9
uppbox/CppBase2/perf.txt
Normal 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)
|
||||
723
uppbox/DateTimeCtrl/DateTimeCtrl.cpp
Normal file
723
uppbox/DateTimeCtrl/DateTimeCtrl.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
171
uppbox/DateTimeCtrl/DateTimeCtrl.h
Normal file
171
uppbox/DateTimeCtrl/DateTimeCtrl.h
Normal 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
|
||||
36
uppbox/DateTimeCtrl/DateTimeCtrl.iml
Normal file
36
uppbox/DateTimeCtrl/DateTimeCtrl.iml
Normal 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")
|
||||
73
uppbox/DateTimeCtrl/DateTimeCtrl.t
Normal file
73
uppbox/DateTimeCtrl/DateTimeCtrl.t
Normal 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")
|
||||
14
uppbox/DateTimeCtrl/DateTimeCtrl.upp
Normal file
14
uppbox/DateTimeCtrl/DateTimeCtrl.upp
Normal 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";
|
||||
39
uppbox/DateTimeCtrl/changelog.txt
Normal file
39
uppbox/DateTimeCtrl/changelog.txt
Normal 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
|
||||
68
uppbox/DateTimeCtrl/main.cpp
Normal file
68
uppbox/DateTimeCtrl/main.cpp
Normal 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
|
||||
11
uppbox/DateTimeCtrl/main.lay
Normal file
11
uppbox/DateTimeCtrl/main.lay
Normal 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
135
uppbox/MakeInstall/Main.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
uppbox/MakeInstall/MakeInstall.upp
Normal file
9
uppbox/MakeInstall/MakeInstall.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
plugin\bz2,
|
||||
Core;
|
||||
|
||||
file
|
||||
Main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
2
uppbox/MakeInstall/prj.aux
Normal file
2
uppbox/MakeInstall/prj.aux
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
file
|
||||
e:\out\upp/MakeInstall/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\MakeInstall.log;
|
||||
243
uppbox/MakeInstall2/Main.cpp
Normal file
243
uppbox/MakeInstall2/Main.cpp
Normal 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);
|
||||
}
|
||||
12
uppbox/MakeInstall2/MakeInstall2.upp
Normal file
12
uppbox/MakeInstall2/MakeInstall2.upp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
uses
|
||||
plugin\bz2,
|
||||
Core,
|
||||
plugin\ftp,
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
install.lay,
|
||||
Main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
21
uppbox/MakeInstall2/install.lay
Normal file
21
uppbox/MakeInstall2/install.lay
Normal 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
|
||||
|
||||
2
uppbox/MakeInstall2/prj.aux
Normal file
2
uppbox/MakeInstall2/prj.aux
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
file
|
||||
e:\out\upp/MakeInstall/CONSOLE-DEBUG-IA32-MAIN-MSC-ST-STATIC-WIN32\MakeInstall.log;
|
||||
587
uppbox/MakeInstall3/Main.cpp
Normal file
587
uppbox/MakeInstall3/Main.cpp
Normal 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!");
|
||||
}
|
||||
}
|
||||
14
uppbox/MakeInstall3/MakeInstall3.upp
Normal file
14
uppbox/MakeInstall3/MakeInstall3.upp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
description "Install creator v.3";
|
||||
|
||||
uses
|
||||
plugin\bz2,
|
||||
Core,
|
||||
plugin\ftp,
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
install.lay,
|
||||
Main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
57
uppbox/MakeInstall3/install.lay
Normal file
57
uppbox/MakeInstall3/install.lay
Normal 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
8
uppbox/Pcre/Pcre.h
Normal 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
32
uppbox/Pcre/Pcre.upp
Normal 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
142
uppbox/Pcre/RegExp.cpp
Normal 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
56
uppbox/Pcre/RegExp.h
Normal 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
127
uppbox/Pcre/lib/config.h
Normal 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
284
uppbox/Pcre/lib/pcre.h
Normal 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 */
|
||||
183
uppbox/Pcre/lib/pcre_chartables.c
Normal file
183
uppbox/Pcre/lib/pcre_chartables.c
Normal 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 */
|
||||
5124
uppbox/Pcre/lib/pcre_compile.c
Normal file
5124
uppbox/Pcre/lib/pcre_compile.c
Normal file
File diff suppressed because it is too large
Load diff
116
uppbox/Pcre/lib/pcre_config.c
Normal file
116
uppbox/Pcre/lib/pcre_config.c
Normal 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
Loading…
Add table
Add a link
Reference in a new issue