/*! @file
* @brief
* misc stuff that is needed at startup
*/
//
// performing some sanity checks
//
#if defined(__GNUG__) && __GNUC__ < 3
#error "Please compile again with a newer version of GCC (version >= 3.2.x, better >=3.4.x)"
#endif
#if #cpu (x86_64)
#ifndef ASM_X86_64
#warning "inline assembler for X86_64 is disabled!"
#warning "you may want to optimize your makefile settings!"
#else
#warning "there is rudimentary inline assembler support for X86_64, but sieving is still faster using X86_32 mode..."
#warning "however, server + ecm is faster for X86_64"
#endif
#else
#ifdef ASM_X86_64
#warning "please review the makefile!"
#error "X86_64-inline assembler code for non-X86_64 compatible cpu/mode?"
#endif
#endif
#if #cpu (i386)
#ifndef ASM_386
#warning "inline assembler for i386 is disabled!"
#warning "you may want to optimize your makefile settings!"
#endif
#if defined(ASM_ATHLON)
#ifndef ASM_CMOV
#warning "using athlon-inline assembler, but ASM_CMOV not enabled!"
#warning "you may want to activate CMOV in the makefile, because ATHLON supports it!"
#endif
#endif
#else
#ifdef ASM_386
#warning "please review the makefile!"
#error "i386-inline assembler code for non-i386 compatible cpu?"
#endif
#endif
#if !defined (unix) && defined(USE_NETWORK)
#error "network support only for Unix-systems"
#endif
#include <cstring> // for strdup and friends...
#include <string>
#include <iostream>
#include <iomanip>
#include "utils.H"
using namespace std;
#ifndef USE_NETWORK
#ifdef IS_SERVER
#error "Illegal configuration: SERVER and no USE_NETWORK"
#endif
#else
#ifndef IS_STANDALONE
#ifdef IS_SERVER
#include <map>
#endif
#include "unix_buffer.H"
#endif
#endif
#ifndef IS_SERVER
#ifndef IS_CLIENT
#undef IS_STANDALONE
#define IS_STANDALONE
#endif
#endif
#ifdef IS_SERVER
#ifdef IS_CLIENT
#error "Illegal Configuration SERVER-CLIENT"
#else
#ifdef IS_STANDALONE
#error "Illegal Configuration SERVER-STANDALONE"
#endif
#endif
#endif
#ifdef IS_CLIENT
#ifdef IS_STANDALONE
#error "Illegal Configuration CLIENT-STANDALONE"
#endif
#endif
#if defined(USE_FIBHEAP) && defined(USE_FAKEHEAP)
#error "defines USE_FIBHEAP and USE_FAKEHEAP exclude each other!"
#endif
#ifdef REACT_ON_SIGUSR
// a little class that catches signal SIGUSR1 and SIGUSR2
// and stores these flags...
// can be useful to abort some long-running algorithms
// without aborting the program or altering configuration parameters.
#include "usr_signals.cc"
Cusr_signal_proxy USRSignalHandler;
#endif
// propagate IS_STANDALONE-condition from compiletime to runtime,
// so that certain modules can be compiled independently of it.
bool compiled_IS_STANDALONE()
{
#ifdef IS_STANDALONE
return true;
#else
return false;
#endif
}
// output to screen/terminal can optionally be handled by a ncurses based
// wrapper, but on default all windows will be merged into cout.
#ifdef USE_NCURSES
#include <my_ncurses.H>
#endif
ostream cout_titel(cout.rdbuf());
ostream cout_network(cout.rdbuf());
ostream cout_status(cout.rdbuf());
#ifdef USE_NCURSES
class Cncursed : private ForbidAssignment
{
private:
static Cncursed* myself;
static void suicide() { delete myself; }
typedef streambuf* Pstreambuf;
typedef Cwin* Pwin;
Pstreambuf cout_titel_buf, cout_network_buf, cout_status_buf,
cerr_buf, clog_buf, cout_buf;
Pwin window1, window2, window3;
public:
Cncursed()
{
if (myself)
{
MARK;
cerr << "You may not call me twice, I'm unique!" << endl;
exit(93);
}
myself=this; // I am myself, really!
init_my_ncurses();
window1 = new Cwin(8,0,0,0);
window2 = new Cwin(8,0,8,0);
window3 = new Cwin(0,0,16,0);
cout_titel_buf=cout_titel.rdbuf(window1->rdbuf());
cout_network_buf=cout_network.rdbuf(window1->rdbuf());
cout_status_buf=cout_status.rdbuf(window2->rdbuf());
cerr_buf=cerr.rdbuf(window2->rdbuf());
clog_buf=clog.rdbuf(window2->rdbuf());
cout_buf=cout.rdbuf(window3->rdbuf());
atexit(suicide);
}
~Cncursed()
{
cout_titel.rdbuf(cout_titel_buf);
cout_network.rdbuf(cout_network_buf);
cout_status.rdbuf(cout_status_buf);
cerr.rdbuf(cerr_buf);
clog.rdbuf(clog_buf);
cout.rdbuf(cout_buf);
delete window1; delete window2; delete window3;
exit_my_ncurses();
#if 0
// print statistical information before exiting,
// since screen should be cleared now!
display_StatusLegend();
StatusReport(true);
#endif
}
};
Cncursed* Cncursed::myself = NULL;
#endif
inline void PrintHeader(string name)
{
#if defined(VERSION)
name=name+" "+VERSION;
#endif
string author = "(C) 1998 - 2007 Thorsten Reinecke";
string email = "(qsieve@thorstenreinecke.de)";
const int L = 5+MAX(name.length(),MAX(author.length(),email.length()));
const string sep(L,'-');
int f;
f=(L-name.length())>>1; name=string(f,' ')+name+string(f+1,' '); name.resize(L);
f=(L-author.length())>>1; author=string(f,' ')+author+string(f+1,' '); author.resize(L);
f=(L-email.length())>>1; email=string(f,' ')+email+string(f+1,' '); email.resize(L);
cout_titel << " -" << sep << "-" << endl;
cout_titel << "- " << name << " -" << endl;
cout_titel << "- " << author << " -" << endl;
cout_titel << "- " << email << " -" << endl;
cout_titel << " -" << sep << "-" << endl;
#ifdef __GNUG__
{
const string s=__VERSION__;
cout << "(" << __DATE__ << ", " << __TIME__ << " using ";
if (s[0]<='9') cout << "gcc ";
cout << __VERSION__ << ")" << endl;
}
#endif
cout << endl;
cout << "This is free software; see the source for copying conditions. There is NO" << endl
<< "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << endl
<< endl;
}