<commit_before>#include "writer.h"

int main(int argc, char **argv)
{
	// required for argument parsing
	int fflag = 0;
	int c;
	const char * def_filename = "device-file";
	char * filename;
	extern char *optarg;
	extern int optind;
	//static char usage[] = "usage: %s -f filename\n";
	const int def_num_threads = 2;
	int num_threads;

	// permanent values
	int num_records;
	int fd;

	while ((c = getopt(argc, argv, "w:f:d")) != -1)
	{
		switch (c)
		{
			case 'f':
				filename = optarg;
				fflag = 1;
				break;
			case 'w':
				num_threads = atoi(optarg);
				break;
			case 'd':
				dflag = true;
				break;
			default:
				// implement other options, such as help, etc.
				break;
		}
	}

	if (fflag == 0)
	{
		// need to implement default filename
		filename = strdup(def_filename);
	}

	if (!num_threads)
		num_threads = def_num_threads;

	fd = open_file(filename);

	file_size = (int) get_file_size(fd);
	num_records = file_size / RECORD_SIZE;
	first_record = 0;
	last_record = num_records;

	std::cout << "File range is 0 to " << file_size << "." << std::endl;

	std::cout << "Number of possible records: " << num_records << std::endl;

	pthread_mutex_init(&f_lock, NULL);

	int rc;
	pthread_t threads[num_threads];
	thread_info thread_data[num_threads];
	for (int t = 0; t < num_threads; t++)
	{
		thread_data[t].thread_id = t;
		thread_data[t].record_num = 1;
		thread_data[t].fd = fd;
		rc = pthread_create(&threads[t], NULL, worker_thread_init, (void *) &thread_data[t]);
		if (rc)
		{
			printf("ERROR; return code from pthread_create() is %d\n", rc);
			exit(-1);
		}
	}

	pthread_mutex_destroy(&f_lock);
	pthread_exit(NULL);
	if (dflag)
		std::cout << "before close(fd)" << std::endl;
	close(fd);
	if (dflag)
		std::cout << "after close(fd)" << std::endl;
	return 0;
}

void * worker_thread_init(void * thread_arg)
{
	thread_info * thread_data;
	thread_data = (thread_info *) thread_arg;
	if (dflag)
		for (int i = 0; i < 10; i++)
			create_record(thread_data);
	else
		while (true)
			create_record(thread_data);
	pthread_exit(NULL);
}

void create_record(thread_info * record_data)
{
	// record the time this record is started
	auto since_epoch = std::chrono::high_resolution_clock::now().time_since_epoch();
	auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(since_epoch).count();
	long record_size = RECORD_SIZE / sizeof(long);
	long size = record_size * sizeof(long);
	long * record = (long *) malloc(size);
	long address = intRand();
	long checksum;

	record[IND_THREAD_ID] = record_data->thread_id;
	record[IND_RECORD_NUM] = record_data->record_num;
	record[IND_RECORD_ADDRESS] = address;
	record[IND_TIMESTAMP] = (long) nanos;
	for (int i = FIRST_RANDOM_RECORD; i < record_size - 1; i++)
	{
		record[i] = record[i-1] + record[0] * record[1] * i + record[2];
	}

	checksum = Fletcher64(record, record_size - 1);
	record[record_size - 1] = Fletcher64(record, record_size - 1);

	if (dflag)
		std::cout << "Record: " << record[IND_THREAD_ID] << " " << record[IND_RECORD_NUM] << " " << record[IND_RECORD_ADDRESS] << " " << record[IND_TIMESTAMP] << " " << checksum << std::endl;
	size_t msg = write_record(record_data, record, size);
	if (dflag)
		std::cout << "msg " << msg << std::endl;
	record_data->record_num += 1;
	free(record);
}

size_t write_record(thread_info * record_data, long * record, long size)
{
	size_t nbyte = size;
	off_t offset = record[IND_RECORD_ADDRESS] * RECORD_SIZE;
	int fd = record_data->fd;

	if (dflag)
		std::cout << "fd " << fd << " nbyte " << nbyte << " offset " << offset << std::endl;
	//pthread_mutex_lock(&f_lock);
	size_t msg = pwrite(fd, record, nbyte, offset);
	//pthread_mutex_unlock(&f_lock);
	return msg;
}

int intRand(void)
{
	static thread_local std::mt19937* generator;
	if (!generator) generator = new std::mt19937(clock());
	std::uniform_int_distribution<int> distribution(first_record, last_record);
	return distribution(*generator);
}<commit_msg>For sanity’s sake<commit_after>#include "writer.h"

int main(int argc, char **argv)
{
	// required for argument parsing
	int fflag = 0;
	int c;
	const char * def_filename = "device-file";
	char * filename;
	extern char *optarg;
	extern int optind;
	//static char usage[] = "usage: %s -f filename\n";
	const int def_num_threads = 2;
	int num_threads;

	// permanent values
	int num_records;
	int fd;

	while ((c = getopt(argc, argv, "w:f:d")) != -1)
	{
		switch (c)
		{
			case 'f':
				filename = optarg;
				fflag = 1;
				break;
			case 'w':
				num_threads = atoi(optarg);
				break;
			case 'd':
				dflag = true;
				break;
			default:
				// implement other options, such as help, etc.
				break;
		}
	}

	if (fflag == 0)
	{
		// need to implement default filename
		filename = strdup(def_filename);
	}

	if (!num_threads)
		num_threads = def_num_threads;

	fd = open_file(filename);

	file_size = (int) get_file_size(fd);
	num_records = file_size / RECORD_SIZE;
	first_record = 0;
	last_record = num_records;

	std::cout << "File range is 0 to " << file_size << "." << std::endl;

	std::cout << "Number of possible records: " << num_records << std::endl;

	pthread_mutex_init(&f_lock, NULL);

	int rc;
	pthread_t threads[num_threads];
	thread_info thread_data[num_threads];
	for (int t = 0; t < num_threads; t++)
	{
		thread_data[t].thread_id = t;
		thread_data[t].record_num = 1;
		thread_data[t].fd = fd;
		rc = pthread_create(&threads[t], NULL, worker_thread_init, (void *) &thread_data[t]);
		if (rc)
		{
			printf("ERROR; return code from pthread_create() is %d\n", rc);
			exit(-1);
		}
	}

	for (int t = 0; t < num_threads; t++)
		pthread_join(threads[t], NULL);

	pthread_mutex_destroy(&f_lock);
	pthread_exit(NULL);
	if (dflag)
		std::cout << "before close(fd)" << std::endl;
	close(fd);
	if (dflag)
		std::cout << "after close(fd)" << std::endl;
	return 0;
}

void * worker_thread_init(void * thread_arg)
{
	thread_info * thread_data;
	thread_data = (thread_info *) thread_arg;
	if (dflag)
		for (int i = 0; i < 10; i++)
			create_record(thread_data);
	else
		while (true)
			create_record(thread_data);
	pthread_exit(NULL);
}

void create_record(thread_info * record_data)
{
	// record the time this record is started
	auto since_epoch = std::chrono::high_resolution_clock::now().time_since_epoch();
	auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(since_epoch).count();
	long record_size = RECORD_SIZE / sizeof(long);
	long size = record_size * sizeof(long);
	long * record = (long *) malloc(size);
	long address = intRand();
	long checksum;

	record[IND_THREAD_ID] = record_data->thread_id;
	record[IND_RECORD_NUM] = record_data->record_num;
	record[IND_RECORD_ADDRESS] = address;
	record[IND_TIMESTAMP] = (long) nanos;
	for (int i = FIRST_RANDOM_RECORD; i < record_size - 1; i++)
	{
		record[i] = record[i-1] + record[0] * record[1] * i + record[2];
	}

	checksum = Fletcher64(record, record_size - 1);
	record[record_size - 1] = Fletcher64(record, record_size - 1);

	if (dflag)
		std::cout << "Record: " << record[IND_THREAD_ID] << " " << record[IND_RECORD_NUM] << " " << record[IND_RECORD_ADDRESS] << " " << record[IND_TIMESTAMP] << " " << checksum << std::endl;
	size_t msg = write_record(record_data, record, size);
	if (dflag)
		std::cout << "msg " << msg << std::endl;
	record_data->record_num += 1;
	free(record);
}

size_t write_record(thread_info * record_data, long * record, long size)
{
	size_t nbyte = size;
	off_t offset = record[IND_RECORD_ADDRESS] * RECORD_SIZE;
	int fd = record_data->fd;

	if (dflag)
		std::cout << "fd " << fd << " nbyte " << nbyte << " offset " << offset << std::endl;
	//pthread_mutex_lock(&f_lock);
	size_t msg = pwrite(fd, record, nbyte, offset);
	//pthread_mutex_unlock(&f_lock);
	return msg;
}

int intRand(void)
{
	static thread_local std::mt19937* generator;
	if (!generator) generator = new std::mt19937(clock());
	std::uniform_int_distribution<int> distribution(first_record, last_record);
	return distribution(*generator);
}<|endoftext|>


<commit_before>#include "config.h"

#include "ypixmap.h"
#include "yxapp.h"

#include <stdlib.h>

static Pixmap createPixmap(int w, int h, int depth) {
    return XCreatePixmap(xapp->display(), desktop->handle(), w, h, depth);
}

static Pixmap createPixmap(int w, int h) {
    return createPixmap(w, h, xapp->depth());
}

static Pixmap createMask(int w, int h) {
    return XCreatePixmap(xapp->display(), desktop->handle(), w, h, 1);
}

void YPixmap::replicate(bool horiz, bool copyMask) {
    if (pixmap() == None || (fMask == None && copyMask))
	return;

    int dim(horiz ? width() : height());
    if (dim >= 128) return;
    dim = 128 + dim - 128 % dim;

    Pixmap nPixmap(horiz ? createPixmap(dim, height())
    			 : createPixmap(width(), dim));
    Pixmap nMask(copyMask ? (horiz ? createMask(dim, height())
				   : createMask(width(), dim)) : None);

    if (horiz)
	Graphics(nPixmap, dim, height()).repHorz(fPixmap, width(), height(), 0, 0, dim);
    else
	Graphics(nPixmap, width(), dim).repVert(fPixmap, width(), height(), 0, 0, dim);

    if (nMask != None) {
	if (horiz)
	    Graphics(nMask, dim, height()).repHorz(fMask, width(), height(), 0, 0, dim);
	else
            Graphics(nMask, width(), dim).repVert(fMask, width(), height(), 0, 0, dim);
    }

    if (
#if 1
        true
#else
        fOwned
#endif
       )
    {
        if (fPixmap != None)
            XFreePixmap(xapp->display(), fPixmap);
        if (fMask != None)
            XFreePixmap(xapp->display(), fMask);
    }

    fPixmap = nPixmap;
    fMask = nMask;

    (horiz ? fWidth : fHeight) = dim;
}

YPixmap::~YPixmap() {
    if (fPixmap != None) {
        if (xapp != 0)
            XFreePixmap(xapp->display(), fPixmap);
        fPixmap = 0;
    }
    if (fMask != None) {
        if (xapp != 0)
            XFreePixmap(xapp->display(), fMask);
        fMask = 0;
    }
}

#if 0
ref<YPixmap> YPixmap::scale(ref<YPixmap> source, int const w, int const h) {
    ref<YPixmap> scaled;
    scaled = source;
    return scaled;
}
#endif

ref<YPixmap> YPixmap::scale(int const w, int const h) {
    ref<YPixmap> pixmap;
    pixmap.init(this);
    ref<YImage> image = YImage::createFromPixmap(pixmap);
    if (image != null) {
        image = image->scale(w, h);
        if (image != null)
            pixmap = YPixmap::createFromImage(image);
    }
    return pixmap;
}

ref<YPixmap> YPixmap::create(int w, int h, bool useMask) {
    ref<YPixmap> n;

    Pixmap pixmap = createPixmap(w, h);
    Pixmap mask = useMask ? createMask(w, h) : None;
    if (pixmap != None && (!useMask || mask != None))

        n.init(new YPixmap(pixmap, mask, w, h));
    return n;
}

ref<YPixmap> YPixmap::createFromImage(ref<YImage> image) {
    return image->renderToPixmap();
}

ref<YPixmap> YPixmap::createFromPixmapAndMask(Pixmap /*pixmap*/,
                                              Pixmap /*mask*/,
                                              int /*w*/,
                                              int /*h*/)
{
    die(2, "YPixmap::createFromPixmapAndMask");
    return null;
}

ref<YPixmap> YPixmap::createFromPixmapAndMaskScaled(Pixmap pix, Pixmap mask,
                                                    int width, int height,
                                                    int nw, int nh)
{
    if (pix != None) {
        ref<YImage> image =
            YImage::createFromPixmapAndMaskScaled(pix, mask,
                                                  width, height, nw, nh);
        if (image != null) {
            ref<YPixmap> pixmap =
                YPixmap::createFromImage(image);
            return pixmap;
        }
    }
    return null;
}

ref<YPixmap> YPixmap::load(upath filename) {
    ref<YImage> image = YImage::load(filename);
    ref<YPixmap> pixmap;
    if (image != null) {
        pixmap = YPixmap::createFromImage(image);
    }
    return pixmap;
}
<commit_msg>Reduce clutter and clarify.<commit_after>#include "config.h"

#include "ypixmap.h"
#include "yxapp.h"

static Pixmap createPixmap(int w, int h, int depth) {
    return XCreatePixmap(xapp->display(), desktop->handle(), w, h, depth);
}

static Pixmap createPixmap(int w, int h) {
    return createPixmap(w, h, xapp->depth());
}

static Pixmap createMask(int w, int h) {
    return XCreatePixmap(xapp->display(), desktop->handle(), w, h, 1);
}

void YPixmap::replicate(bool horiz, bool copyMask) {
    if (pixmap() == None || (fMask == None && copyMask))
	return;

    int dim(horiz ? width() : height());
    if (dim >= 128) return;
    dim = 128 + dim - 128 % dim;

    Pixmap nPixmap(horiz ? createPixmap(dim, height())
    			 : createPixmap(width(), dim));
    Pixmap nMask(copyMask ? (horiz ? createMask(dim, height())
				   : createMask(width(), dim)) : None);

    if (horiz)
	Graphics(nPixmap, dim, height()).repHorz(fPixmap, width(), height(), 0, 0, dim);
    else
	Graphics(nPixmap, width(), dim).repVert(fPixmap, width(), height(), 0, 0, dim);

    if (nMask != None) {
	if (horiz)
	    Graphics(nMask, dim, height()).repHorz(fMask, width(), height(), 0, 0, dim);
	else
            Graphics(nMask, width(), dim).repVert(fMask, width(), height(), 0, 0, dim);
    }

    if (fPixmap != None)
        XFreePixmap(xapp->display(), fPixmap);
    if (fMask != None)
        XFreePixmap(xapp->display(), fMask);

    fPixmap = nPixmap;
    fMask = nMask;

    (horiz ? fWidth : fHeight) = dim;
}

YPixmap::~YPixmap() {
    if (fPixmap != None) {
        if (xapp != 0)
            XFreePixmap(xapp->display(), fPixmap);
        fPixmap = 0;
    }
    if (fMask != None) {
        if (xapp != 0)
            XFreePixmap(xapp->display(), fMask);
        fMask = 0;
    }
}

ref<YPixmap> YPixmap::scale(int const w, int const h) {
    ref<YPixmap> pixmap;
    pixmap.init(this);
    ref<YImage> image = YImage::createFromPixmap(pixmap);
    if (image != null) {
        image = image->scale(w, h);
        if (image != null)
            pixmap = YPixmap::createFromImage(image);
    }
    return pixmap;
}

ref<YPixmap> YPixmap::create(int w, int h, bool useMask) {
    ref<YPixmap> n;

    Pixmap pixmap = createPixmap(w, h);
    Pixmap mask = useMask ? createMask(w, h) : None;
    if (pixmap != None && (!useMask || mask != None)) {
        n.init(new YPixmap(pixmap, mask, w, h));
    }
    return n;
}

ref<YPixmap> YPixmap::createFromImage(ref<YImage> image) {
    return image->renderToPixmap();
}

ref<YPixmap> YPixmap::createFromPixmapAndMask(Pixmap /*pixmap*/,
                                              Pixmap /*mask*/,
                                              int /*w*/,
                                              int /*h*/)
{
    die(2, "YPixmap::createFromPixmapAndMask");
    return null;
}

ref<YPixmap> YPixmap::createFromPixmapAndMaskScaled(Pixmap pix, Pixmap mask,
                                                    int width, int height,
                                                    int nw, int nh)
{
    if (pix != None) {
        ref<YImage> image =
            YImage::createFromPixmapAndMaskScaled(pix, mask,
                                                  width, height, nw, nh);
        if (image != null) {
            ref<YPixmap> pixmap =
                YPixmap::createFromImage(image);
            return pixmap;
        }
    }
    return null;
}

ref<YPixmap> YPixmap::load(upath filename) {
    ref<YImage> image = YImage::load(filename);
    ref<YPixmap> pixmap;
    if (image != null) {
        pixmap = YPixmap::createFromImage(image);
    }
    return pixmap;
}
<|endoftext|>


<commit_before>#include "config.h"
#include "base.h"
#include "ysocket.h"
#include "yapp.h"
#include "debug.h"

#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdio.h>

YSocket::YSocket() {
    fPrev = fNext = 0;
    fListener = 0;
    sockfd = -1;
    rdbuf = 0;
    rdbuflen = 0;
    connecting = false;
    reading = false;
    registered = false;
}

YSocket::~YSocket() {
    if (sockfd != -1)
        ::close(sockfd);
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
}

int YSocket::connect(struct sockaddr *server_addr, int addrlen) {
    int fd;

    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd == -1)
        return -errno;

    if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
        ::close(fd);
        return -errno;
    }

    if (fcntl(fd, F_SETFD, 1) == -1) {
        ::close(fd);
        return -errno;
    }

    MSG(("connecting."));
    if (::connect(fd, server_addr, addrlen) == -1) {
        if (errno == EINPROGRESS) {
            MSG(("in progress"));
            connecting = true;
            sockfd = fd;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
            return 0;
        }
        MSG(("error"));
        ::close(fd);
        return -errno;
    }
    sockfd = fd;

    if (fListener)
        fListener->socketConnected();

    return 0;
}

int YSocket::close() {
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    if (sockfd == -1)
        return -EINVAL;
    if (::close(sockfd) == -1)
        return -errno;
    sockfd = -1;
    return 0;
}

int YSocket::read(char *buf, int len) {
#if 0
    int rc;

    rc = ::read(sockfd, (void *)buf, len);

    if (rc == 0) {
        if (fListener)
            fListener->socketError(0);
        return 0;
    } else if (rc == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
#endif
            rdbuf = buf;
            rdbuflen = len;
            reading = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
#if 0
        } else {
            return -errno;
        }
    }
    if (fListener)
        fListener->socketDataRead(buf, rc);
    return rc;
#endif
#if 1
    return 0;
#endif
}

int YSocket::write(const char *buf, int len) {
    int rc;

    // must loop !!!

    rc = ::write(sockfd, (const void *)buf, len);
    if (rc == -1)
        return -errno;
    else
        return rc;
}

void YSocket::can_read() {
    reading = false;
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    int rc;

    rc = ::read(sockfd, rdbuf, rdbuflen);

    if (rc == 0) {
        if (fListener)
            fListener->socketError(0);
        return ;
    } else if (rc == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            reading = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
        } else {
            if (fListener)
                fListener->socketError(-errno);
        }
        return ;
    }
    if (fListener)
        fListener->socketDataRead(rdbuf, rc);
}

void YSocket::connected() {
    int err = 0;
    char x[1];
    connecting = false;
    MSG(("connected"));
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    if (::recv(sockfd, x, 0, 0) == -1) { // ???!!!
        MSG(("after connect check"));
        if (errno == EWOULDBLOCK || errno == EAGAIN) {
        } else if (errno == ENOTCONN) {
            connecting = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
            return ;
        } else {
            err = errno;
            MSG(("here"));
            if (fListener)
                fListener->socketError(err);
            return ;
        }
    }
    if (fListener)
        fListener->socketConnected();
}
<commit_msg>FD_CLOEXEC<commit_after>#include "config.h"
#include "base.h"
#include "ysocket.h"
#include "yapp.h"
#include "debug.h"

#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdio.h>

YSocket::YSocket() {
    fPrev = fNext = 0;
    fListener = 0;
    sockfd = -1;
    rdbuf = 0;
    rdbuflen = 0;
    connecting = false;
    reading = false;
    registered = false;
}

YSocket::~YSocket() {
    if (sockfd != -1)
        ::close(sockfd);
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
}

int YSocket::connect(struct sockaddr *server_addr, int addrlen) {
    int fd;

    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd == -1)
        return -errno;

    if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
        ::close(fd);
        return -errno;
    }

    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
        ::close(fd);
        return -errno;
    }

    MSG(("connecting."));
    if (::connect(fd, server_addr, addrlen) == -1) {
        if (errno == EINPROGRESS) {
            MSG(("in progress"));
            connecting = true;
            sockfd = fd;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
            return 0;
        }
        MSG(("error"));
        ::close(fd);
        return -errno;
    }
    sockfd = fd;

    if (fListener)
        fListener->socketConnected();

    return 0;
}

int YSocket::close() {
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    if (sockfd == -1)
        return -EINVAL;
    if (::close(sockfd) == -1)
        return -errno;
    sockfd = -1;
    return 0;
}

int YSocket::read(char *buf, int len) {
#if 0
    int rc;

    rc = ::read(sockfd, (void *)buf, len);

    if (rc == 0) {
        if (fListener)
            fListener->socketError(0);
        return 0;
    } else if (rc == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
#endif
            rdbuf = buf;
            rdbuflen = len;
            reading = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
#if 0
        } else {
            return -errno;
        }
    }
    if (fListener)
        fListener->socketDataRead(buf, rc);
    return rc;
#endif
#if 1
    return 0;
#endif
}

int YSocket::write(const char *buf, int len) {
    int rc;

    // must loop !!!

    rc = ::write(sockfd, (const void *)buf, len);
    if (rc == -1)
        return -errno;
    else
        return rc;
}

void YSocket::can_read() {
    reading = false;
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    int rc;

    rc = ::read(sockfd, rdbuf, rdbuflen);

    if (rc == 0) {
        if (fListener)
            fListener->socketError(0);
        return ;
    } else if (rc == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            reading = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
        } else {
            if (fListener)
                fListener->socketError(-errno);
        }
        return ;
    }
    if (fListener)
        fListener->socketDataRead(rdbuf, rc);
}

void YSocket::connected() {
    int err = 0;
    char x[1];
    connecting = false;
    MSG(("connected"));
    if (registered) {
        registered = false;
        app->unregisterSocket(this);
    }
    if (::recv(sockfd, x, 0, 0) == -1) { // ???!!!
        MSG(("after connect check"));
        if (errno == EWOULDBLOCK || errno == EAGAIN) {
        } else if (errno == ENOTCONN) {
            connecting = true;
            if (!registered) {
                registered = true;
                app->registerSocket(this);
            }
            return ;
        } else {
            err = errno;
            MSG(("here"));
            if (fListener)
                fListener->socketError(err);
            return ;
        }
    }
    if (fListener)
        fListener->socketConnected();
}
<|endoftext|>


<commit_before>#include "data.h"
#include <iostream>

void yaNC::io::SnapshotAOS::write(std::ostream&o, int i, int f)const{
  o << number <<
}
<commit_msg>Skeleton of read function<commit_after>#include "data.h"
#include <iostream>

void yaNC::Snapshot::write(std::ostream&o, int i, int f)const{
  o << number <<
}

void yaNC::Snapshot::read(std::istream&o, int i, int f) {

}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "java/sql/Timestamp.hxx"
#include "java/tools.hxx"
#include <comphelper/types.hxx>
#include "connectivity/dbconversion.hxx"

using namespace ::comphelper;
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Date
//**************************************************************
const double fMilliSecondsPerDay = 86400000.0;
jclass java_sql_Date::theClass = 0;
java_sql_Date::java_sql_Date( const ::com::sun::star::util::Date& _rOut ) : java_util_Date( NULL, (jobject)NULL )
{
    SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    sDateStr = ::dbtools::DBTypeConversion::toDateString(_rOut);
    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn of Java-Call for the constructor
    // initialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Date;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}

java_sql_Date::~java_sql_Date()
{}

jclass java_sql_Date::getMyClass() const
{
    return st_getMyClass();
}
jclass java_sql_Date::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Date");
    return theClass;
}
// -----------------------------------------------------------------------------

java_sql_Date::operator ::com::sun::star::util::Date()
{
    return ::dbtools::DBTypeConversion::toDate(toString());
}

//**************************************************************
//************ Class: java.sql.Time
//**************************************************************

jclass java_sql_Time::theClass = 0;

java_sql_Time::~java_sql_Time()
{}

jclass java_sql_Time::getMyClass() const
{
    return st_getMyClass();
}
jclass java_sql_Time::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Time");
    return theClass;
}
java_sql_Time::java_sql_Time( const ::com::sun::star::util::Time& _rOut ): java_util_Date( NULL, (jobject)NULL )
{
    SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    sDateStr = ::dbtools::DBTypeConversion::toTimeString(_rOut);
    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn off Java-Call for the constructor
    // intialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Time;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
    t.pEnv->DeleteLocalRef((jstring)args[0].l);
    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}
// -----------------------------------------------------------------------------
java_sql_Time::operator ::com::sun::star::util::Time()
{
    return ::dbtools::DBTypeConversion::toTime(toString());
}
//**************************************************************
//************ Class: java.sql.Timestamp
//**************************************************************

jclass java_sql_Timestamp::theClass = 0;

java_sql_Timestamp::~java_sql_Timestamp()
{}

jclass java_sql_Timestamp::getMyClass() const
{
    return st_getMyClass();
}

jclass java_sql_Timestamp::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Timestamp");
    return theClass;
}

java_sql_Timestamp::java_sql_Timestamp(const ::com::sun::star::util::DateTime& _rOut)
                   :java_util_Date( NULL, (jobject)NULL )
{
        SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    sDateStr = ::dbtools::DBTypeConversion::toDateTimeString(_rOut);

    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn off Java-Call for the constructor
    // initialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Timestamp;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );

    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}

// -----------------------------------------------------------------------------
java_sql_Timestamp::operator ::com::sun::star::util::DateTime()
{
    return ::dbtools::DBTypeConversion::toDateTime(toString());
}
// -----------------------------------------------------------------------------

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fdo#66216 JDBC no fractional second in time format<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "java/sql/Timestamp.hxx"
#include "java/tools.hxx"
#include <comphelper/types.hxx>
#include "connectivity/dbconversion.hxx"

using namespace ::comphelper;
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Date
//**************************************************************
const double fMilliSecondsPerDay = 86400000.0;
jclass java_sql_Date::theClass = 0;
java_sql_Date::java_sql_Date( const ::com::sun::star::util::Date& _rOut ) : java_util_Date( NULL, (jobject)NULL )
{
    SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    sDateStr = ::dbtools::DBTypeConversion::toDateString(_rOut);
    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn of Java-Call for the constructor
    // initialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Date;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}

java_sql_Date::~java_sql_Date()
{}

jclass java_sql_Date::getMyClass() const
{
    return st_getMyClass();
}
jclass java_sql_Date::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Date");
    return theClass;
}
// -----------------------------------------------------------------------------

java_sql_Date::operator ::com::sun::star::util::Date()
{
    return ::dbtools::DBTypeConversion::toDate(toString());
}

//**************************************************************
//************ Class: java.sql.Time
//**************************************************************

jclass java_sql_Time::theClass = 0;

java_sql_Time::~java_sql_Time()
{}

jclass java_sql_Time::getMyClass() const
{
    return st_getMyClass();
}
jclass java_sql_Time::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Time");
    return theClass;
}
java_sql_Time::java_sql_Time( const ::com::sun::star::util::Time& _rOut ): java_util_Date( NULL, (jobject)NULL )
{
    SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    // java.sql.Time supports only whole seconds...
    sDateStr = ::dbtools::DBTypeConversion::toTimeString(_rOut).copy(0, 8);
    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn off Java-Call for the constructor
    // intialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Time;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
    t.pEnv->DeleteLocalRef((jstring)args[0].l);
    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}
// -----------------------------------------------------------------------------
java_sql_Time::operator ::com::sun::star::util::Time()
{
    return ::dbtools::DBTypeConversion::toTime(toString());
}
//**************************************************************
//************ Class: java.sql.Timestamp
//**************************************************************

jclass java_sql_Timestamp::theClass = 0;

java_sql_Timestamp::~java_sql_Timestamp()
{}

jclass java_sql_Timestamp::getMyClass() const
{
    return st_getMyClass();
}

jclass java_sql_Timestamp::st_getMyClass()
{
    // the class needs only be fetched once, that is why it is static
    if( !theClass )
        theClass = findMyClass("java/sql/Timestamp");
    return theClass;
}

java_sql_Timestamp::java_sql_Timestamp(const ::com::sun::star::util::DateTime& _rOut)
                   :java_util_Date( NULL, (jobject)NULL )
{
        SDBThreadAttach t;
    if( !t.pEnv )
        return;
    jvalue args[1];
    // Convert parameters
    OUString sDateStr;
    sDateStr = ::dbtools::DBTypeConversion::toDateTimeString(_rOut);

    args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);

    // Turn off Java-Call for the constructor
    // initialise temporary variables
    static const char * cSignature = "(Ljava/lang/String;)Ljava/sql/Timestamp;";
    jobject tempObj;
    static jmethodID mID(NULL);
    if ( !mID  )
        mID  = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
    OSL_ENSURE(mID,"Unknown method id!");
    tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );

    saveRef( t.pEnv, tempObj );
    t.pEnv->DeleteLocalRef( tempObj );
    // and clean
}

// -----------------------------------------------------------------------------
java_sql_Timestamp::operator ::com::sun::star::util::DateTime()
{
    return ::dbtools::DBTypeConversion::toDateTime(toString());
}
// -----------------------------------------------------------------------------

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: Property.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: oj $ $Date: 2001-05-11 09:25:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CONNECTIVITY_java_util_Properties
#define CONNECTIVITY_java_util_Properties

#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#include "java/lang/Object.hxx"
#endif

namespace connectivity
{
    class java_util_Properties : public java_lang_Object
    {
    protected:
    // statische Daten fuer die Klasse
        static jclass theClass;
        // der Destruktor um den Object-Counter zu aktualisieren
        static void saveClassRef( jclass pClass );
    public:
        static jclass getMyClass();
        virtual ~java_util_Properties();
        // ein Konstruktor, der fuer das Returnen des Objektes benoetigt wird:
        java_util_Properties( JNIEnv * pEnv, jobject myObj ) : java_lang_Object( pEnv, myObj ){}
        java_util_Properties( );
        void setProperty(const ::rtl::OUString key, const ::rtl::OUString& value);
    };
}

#endif // CONNECTIVITY_java_util_Properties
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.352); FILE MERGED 2005/09/05 17:25:37 rt 1.3.352.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Property.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:27:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CONNECTIVITY_java_util_Properties
#define CONNECTIVITY_java_util_Properties

#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#include "java/lang/Object.hxx"
#endif

namespace connectivity
{
    class java_util_Properties : public java_lang_Object
    {
    protected:
    // statische Daten fuer die Klasse
        static jclass theClass;
        // der Destruktor um den Object-Counter zu aktualisieren
        static void saveClassRef( jclass pClass );
    public:
        static jclass getMyClass();
        virtual ~java_util_Properties();
        // ein Konstruktor, der fuer das Returnen des Objektes benoetigt wird:
        java_util_Properties( JNIEnv * pEnv, jobject myObj ) : java_lang_Object( pEnv, myObj ){}
        java_util_Properties( );
        void setProperty(const ::rtl::OUString key, const ::rtl::OUString& value);
    };
}

#endif // CONNECTIVITY_java_util_Properties
<|endoftext|>


<commit_before>/*
 * This file is part of the chess-at-nite project.
 *
 * Copyright (c) 2009 by
 *   Franziskus Domig
 *   Panayiotis Lipiridis
 *   Radoslav Petrik
 *   Thai Gia Tuong
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "CLI.h"
#include "../model/Game.h"
#include "../model/Board.h"
#include "../player/ComputerPlayer.h"
#include "../player/HumanPlayer.h"

CLI::CLI() {
    fen = DEFAULT_FEN;
    user_option = -1;
    show_about();
    start();
}

CLI::CLI(int option) {
    fen = DEFAULT_FEN;
    show_about();
    apply_option(option);
}

CLI::~CLI() {

}

void CLI::start() {
    while (user_option != QUIT) {
        show_options();
        user_option = get_user_option();
        apply_option(user_option);
    }
}

void CLI::init_game(int game_type) {
    switch (game_type) {
    case HUMAN_VS_CPU:
        white_player = new HumanPlayer();
        black_player = new ComputerPlayer();
        break;
    case CPU_VS_HUMAN:
        white_player = new ComputerPlayer();
        black_player = new HumanPlayer();
        break;
    case HUMAN_VS_HUMAN:
        white_player = new HumanPlayer();
        black_player = new HumanPlayer();
        break;
    case CPU_VS_CPU:
        white_player = new ComputerPlayer();
        black_player = new ComputerPlayer();
        break;
    }
}

void CLI::apply_option(int option) {
    switch (option) {
    case HUMAN_VS_CPU:
    case CPU_VS_HUMAN:
    case HUMAN_VS_HUMAN:
    case CPU_VS_CPU:
        init_game(option);
        start_game();
        end_game();
        break;
    case SELECT_FEN:
        select_fen();
        break;
    case SHOW_HELP:
        print_help();
        break;
    case BENCHMARK:
        run_benchmark();
        break;
    case WAC:
        run_wac_test();
        break;
    case QUIT:
        cout << "Thanks for playing...!! Have fun.." << endl;
        break;
    }
}

void CLI::show_options() {
    cout << "-----------------------------------" << endl;

    cout << "   1. Human vs Computer" << endl;
    cout << "   2. Computer vs Human" << endl;
    cout << "   3. Human vs Human" << endl;
    cout << "   4. Computer vs Computer" << endl;
    cout << "   5. Load fen" << endl;
    cout << "   6. Help (Moves/Commands)" << endl;
    cout << "   7. Run Benchmark" << endl;
    cout << "   8. Win At Chess Test" << endl;
    cout << "-----------------------------------" << endl;
    cout << "   0. Quit" << endl;
    cout << "-----------------------------------" << endl;
}

string CLI::get_line() {
    string text;
    cin >> text;
    return text;
}

int CLI::get_user_option() {
    int result = -1;
    string temp;
    cout << "Select something: ";
    cin >> temp;

    if (temp.size() > 0 && temp[0] >= '0' && temp[0] <= '9') {
        result = temp[0] - '0';
    }
    return result;
}

void CLI::start_game() {
    board = new Board(fen);
    game = new Game(board, white_player, black_player);
    game->start_game();
}

void CLI::end_game() {
    delete board;
    delete game;
    delete white_player;
    delete black_player;
    fen = DEFAULT_FEN;
}

void CLI::show_about() {
    cout << " Welcome to ChessAtNite, v" << VERSION << " written by:" << endl;
    cout << "  - Franziskus Domig" << endl;
    cout << "  - Panayiotis Lipiridis" << endl;
    cout << "  - Radoslav Petrik" << endl;
    cout << "  - Thai Gia Tuong" << endl;
}

void CLI::select_fen() {
    fen = "3r2k1/R4p2/p2n3p/2pP2pP/2P2KP1/3B3r/P2R4/8 w - - 0 44";// en passant can escape from check, but it doesn't
    fen = DEFAULT_FEN;
    fen = "2rr3k/pp3pp1/1nnqbN1p/3pN3/2pP4/2P3Q1/PPB4P/R4RK1 w - - 0 1";
    Board b = Board(fen);
    cout << b << endl;
}

/* bench: This is a little benchmark code that calculates how many
 nodes per second TSCP searches.
 It sets the position to move 17 of Bobby Fischer vs. J. Sherwin,
 New Jersey State Open Championship, 9/2/1957.
 Then it searches five ply three times. It calculates nodes per
 second from the best time. */
void CLI::run_benchmark() {
    string fen = "rq3rk1/4bppp/p1Rp1n2/8/4p3/1B2BP2/PP4PP/3Q1RK1 w - - 0 17";
    Board* b = new Board(fen);
    Player* p = new ComputerPlayer();
    p->set_board(b);

    int t[3];
    int n[3];
    for (int i = 0; i < 3; i++) {
        int start = get_ms();
        p->get_move();
        t[i] = get_ms() - start;
        n[i] = b->checked_nodes;
    }
    cout << "-----------------------------------" << endl;
    cout << "Benchmark Results:" << endl;
    double total = 0;
    for (int i = 0; i < 3; i++) {
        double nps = (n[i] / (double) t[i]) * 1000;
        total += nps;
        cout << i + 1 << ": nodes/second: " << (int) nps << endl;
    }

    cout << "average: " << (int) (total / 3) << " nodes/second" << endl;
    delete p;
    delete b;
}

/*
 * Testsuite "Win at Chess"
 *
 * 300 Board positions which should be found a path to checkmate.
 *
 */
void CLI::run_wac_test() {
    ifstream file;
    file.open(WAC_FILE);
    if (!file) {
        cout << "Can not run Win At Chess test: Test file '" << WAC_FILE;
        cout << "' is missing." << endl;
        return;
    }

    vector<string> found;
    vector<string> should;

    string line = "";
    while (!file.eof()) {

        getline(file, line);
        if (line.size() < 4)
            continue;

        string cmd = "";
        cmd = line.substr(0, 4);

        if (cmd.compare("noop") == 0) {
            continue;
        } else if (cmd.compare("echo") == 0) {
            printf("%s\n", line.substr(5, line.length() - 5).c_str());
        } else if (cmd.compare("svfe") == 0) {
            string fen = "";
            fen = line.substr(5, line.length() - 5);
            Board b = Board(fen);
            Player* p = new ComputerPlayer();
            p->set_board(&b);
            move m = p->get_move();
            cout << "Found: " << move_to_string_simple(m) << endl;
            found.push_back(move_to_string_simple(m));
            delete p;
        } else if (cmd.compare("srch") == 0) {
            cout << "Should be: " << line.substr(5, line.length() - 5) << endl;
            should.push_back(line.substr(5, line.length() - 5));
        }
    }

    file.close();

    cout << "Test Results:" << endl;
    cout << "Found     Should" << endl;
    for (unsigned i = 0; i < should.size() && found.size(); i++) {
        cout << found[i] << "    " << should[i] << endl;
    }
}

<commit_msg>written by removed from the CLI modified benchmark print out<commit_after>/*
 * This file is part of the chess-at-nite project.
 *
 * Copyright (c) 2009 by
 *   Franziskus Domig
 *   Panayiotis Lipiridis
 *   Radoslav Petrik
 *   Thai Gia Tuong
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "CLI.h"
#include "../model/Game.h"
#include "../model/Board.h"
#include "../player/ComputerPlayer.h"
#include "../player/HumanPlayer.h"

CLI::CLI() {
    fen = DEFAULT_FEN;
    user_option = -1;
    show_about();
    start();
}

CLI::CLI(int option) {
    fen = DEFAULT_FEN;
    show_about();
    apply_option(option);
}

CLI::~CLI() {

}

void CLI::start() {
    while (user_option != QUIT) {
        show_options();
        user_option = get_user_option();
        apply_option(user_option);
    }
}

void CLI::init_game(int game_type) {
    switch (game_type) {
    case HUMAN_VS_CPU:
        white_player = new HumanPlayer();
        black_player = new ComputerPlayer();
        break;
    case CPU_VS_HUMAN:
        white_player = new ComputerPlayer();
        black_player = new HumanPlayer();
        break;
    case HUMAN_VS_HUMAN:
        white_player = new HumanPlayer();
        black_player = new HumanPlayer();
        break;
    case CPU_VS_CPU:
        white_player = new ComputerPlayer();
        black_player = new ComputerPlayer();
        break;
    }
}

void CLI::apply_option(int option) {
    switch (option) {
    case HUMAN_VS_CPU:
    case CPU_VS_HUMAN:
    case HUMAN_VS_HUMAN:
    case CPU_VS_CPU:
        init_game(option);
        start_game();
        end_game();
        break;
    case SELECT_FEN:
        select_fen();
        break;
    case SHOW_HELP:
        print_help();
        break;
    case BENCHMARK:
        run_benchmark();
        break;
    case WAC:
        run_wac_test();
        break;
    case QUIT:
        cout << "Thanks for playing...!! Have fun.." << endl;
        break;
    }
}

void CLI::show_options() {
    cout << "-----------------------------------" << endl;

    cout << "   1. Human vs Computer" << endl;
    cout << "   2. Computer vs Human" << endl;
    cout << "   3. Human vs Human" << endl;
    cout << "   4. Computer vs Computer" << endl;
    cout << "   5. Load fen" << endl;
    cout << "   6. Help (Moves/Commands)" << endl;
    cout << "   7. Run Benchmark" << endl;
    cout << "   8. Win At Chess Test" << endl;
    cout << "-----------------------------------" << endl;
    cout << "   0. Quit" << endl;
    cout << "-----------------------------------" << endl;
}

string CLI::get_line() {
    string text;
    cin >> text;
    return text;
}

int CLI::get_user_option() {
    int result = -1;
    string temp;
    cout << "Select something: ";
    cin >> temp;

    if (temp.size() > 0 && temp[0] >= '0' && temp[0] <= '9') {
        result = temp[0] - '0';
    }
    return result;
}

void CLI::start_game() {
    board = new Board(fen);
    game = new Game(board, white_player, black_player);
    game->start_game();
}

void CLI::end_game() {
    delete board;
    delete game;
    delete white_player;
    delete black_player;
    fen = DEFAULT_FEN;
}

void CLI::show_about() {
    cout << " Welcome to chess-at-nite, v" << VERSION << " (c) 2009-2010" << endl;
    cout << "     http://chess-at-nite.googlecode.com" << endl;
}

void CLI::select_fen() {
    fen = "3r2k1/R4p2/p2n3p/2pP2pP/2P2KP1/3B3r/P2R4/8 w - - 0 44";// en passant can escape from check, but it doesn't
    fen = DEFAULT_FEN;
    fen = "2rr3k/pp3pp1/1nnqbN1p/3pN3/2pP4/2P3Q1/PPB4P/R4RK1 w - - 0 1";
    Board b = Board(fen);
    cout << b << endl;
}

/* bench: This is a little benchmark code that calculates how many
 nodes per second TSCP searches.
 It sets the position to move 17 of Bobby Fischer vs. J. Sherwin,
 New Jersey State Open Championship, 9/2/1957.
 Then it searches five ply three times. It calculates nodes per
 second from the best time. */
void CLI::run_benchmark() {
    string fen = "rq3rk1/4bppp/p1Rp1n2/8/4p3/1B2BP2/PP4PP/3Q1RK1 w - - 0 17";
    Board* b = new Board(fen);
    Player* p = new ComputerPlayer();
    p->set_board(b);
    cout << *b;
    int t[3];
    int n[3];
    for (int i = 0; i < 3; i++) {
        int start = get_ms();
        p->get_move();
        t[i] = get_ms() - start;
        n[i] = b->checked_nodes;
    }
    cout << "-------- Benchmark Results --------" << endl;
    double total = 0;
    for (int i = 0; i < 3; i++) {
        double nps = (n[i] / (double) t[i]) * 1000;
        total += nps;
        cout << "     Run "<< i + 1 << ": " << (int) nps << " nodes/sec" << endl;
    }
    cout << endl;
    cout << "   Average: " << (int) (total / 3) << " nodes/sec" << endl;
    delete p;
    delete b;
}

/*
 * Testsuite "Win at Chess"
 *
 * 300 Board positions which should be found a path to checkmate.
 *
 */
void CLI::run_wac_test() {
    ifstream file;
    file.open(WAC_FILE);
    if (!file) {
        cerr << "Can not run Win At Chess test: Test file '" << WAC_FILE;
        cerr << "' is missing." << endl;
        return;
    }

    vector<string> found;
    vector<string> should;

    string line = "";
    while (!file.eof()) {

        getline(file, line);
        if (line.size() < 4)
            continue;

        string cmd = "";
        cmd = line.substr(0, 4);

        if (cmd.compare("noop") == 0) {
            continue;
        } else if (cmd.compare("echo") == 0) {
            printf("%s\n", line.substr(5, line.length() - 5).c_str());
        } else if (cmd.compare("svfe") == 0) {
            string fen = "";
            fen = line.substr(5, line.length() - 5);
            Board b = Board(fen);
            Player* p = new ComputerPlayer();
            p->set_board(&b);
            move m = p->get_move();
            cout << "Found: " << move_to_string_simple(m) << endl;
            found.push_back(move_to_string_simple(m));
            delete p;
        } else if (cmd.compare("srch") == 0) {
            cout << "Should be: " << line.substr(5, line.length() - 5) << endl;
            should.push_back(line.substr(5, line.length() - 5));
        }
    }

    file.close();

    cout << "Test Results:" << endl;
    cout << "Found     Should" << endl;
    for (unsigned i = 0; i < should.size() && found.size(); i++) {
        cout << found[i] << "    " << should[i] << endl;
    }
}

<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * 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.
 *
 * 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 HOLDER 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.
 *
 * \file mbed_usbserial.cpp
 * This file implements an USB-Serial driver on top of the mbed
 * library. Currently it is tested on the LPC23xx processors.
 *
 * @author Balazs Racz
 * @date 4 May 2013
 */

#include "mbed.h"
#include "USBSerial.h"
#include "Serial.hxx"
#include "os/os.h"
#include "utils/macros.h"
#include "portmacro.h"

#ifdef TARGET_LPC2368
#endif

#define TX_DATA_SIZE 64
#define RX_DATA_SIZE 64

#include <stdlib.h>

void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* ptr);
void operator delete[](void* ptr);

__extension__ typedef int __guard __attribute__((mode(__DI__)));

extern "C" int __cxa_guard_acquire(__guard*);
extern "C" void __cxa_guard_release(__guard*);
extern "C" void __cxa_guard_abort(__guard*);

extern "C" void __cxa_pure_virtual(void);

/** This class is an empty wrapper around MBed's USB CDC class. The difference
    between this and mbed::USBSerial is that this class does not have any
    buffering and no interaction with stdio, whereas mbed::USBSerial has the
    following buffering:
    * it has a 128-byte receive buffer.
    * it has an fd
    * it has a FILE* with a default-sized send/receive buffer
    * it requires mbed's custom glue code in the open(2) method, without which
      it crashes.
 */
class MbedRawUSBSerial : public USBCDC, public Serial
{
public:
    MbedRawUSBSerial(const char* name, uint16_t vendor_id = 0x1f00,
                     uint16_t product_id = 0x2012,
                     uint16_t product_release = 0x0001)
        : USBCDC(vendor_id, product_id, product_release),
          Serial(name),
          serialPriv(serialPriv),
          txPending(false)
    {
        os_sem_init(&rxSem, 0);
        os_thread_t thread;
        os_thread_create(&thread, "usbserial.rx", 1, 1024, &_RxThread, this);
    }

    ~MbedRawUSBSerial()
    {
        os_sem_destroy(&rxSem);
    }

protected:
    virtual bool EP2_OUT_callback()
    {
        HASSERT(IsEpPending());
        // and wake up the RX thread.
        os_sem_post_from_isr(&rxSem);
        return false;
    }

    virtual bool EP2_IN_callback()
    {
        int count;
        int woken = 0;
        configASSERT(txPending);
        for (count = 0; count < MAX_TX_PACKET_LENGTH; count++)
        {
            if (os_mq_receive_from_isr(serialPriv->txQ, &txData[count],
                                       &woken) != OS_MQ_NONE)
            {
                /* no more data left to transmit */
                break;
            }
        }
        TxHelper(count);
        if (woken)
        {
#ifdef TARGET_LPC1768
            portYIELD();
#elif defined(TARGET_LPC2368)
/** @todo(balazs.racz): need to find a way to yield on ARM7. The builtin
 * portYIELD_FROM_ISR assumes that we have entered the ISR with context
 * saving, which we didn't. */
#else
#error define how to yield on your CPU.
#endif
        }
        return true;
    }

private:
    void enable()
    {
    } /**< function to enable device */
    void disable()
    {
    } /**< function to disable device */

    /** function to try and transmit a character */
    void tx_char()
    {
        // Without this critical section there were cases when we deadlocked
        // with txPending == true but no interrupt coming in to clear it.
        taskENTER_CRITICAL();
        if (txPending)
        {
            taskEXIT_CRITICAL();
            return;
        }
        txPending = true;
        int count;
        for (count = 0; count < TX_DATA_SIZE; count++)
        {
            if (os_mq_timedreceive(serialPriv->txQ, txData + count, 0) !=
                OS_MQ_NONE)
            {
                /* no more data left to transmit */
                break;
            }
        }
        TxHelper(count);
        taskEXIT_CRITICAL();
    }

    static const int MAX_TX_PACKET_LENGTH = 64;
    static const int MAX_RX_PACKET_LENGTH = 64;

    /** Transmits count bytes from the txData buffer. Sets txPending and
        bytesLost as needed. */
    void TxHelper(int count)
    {
        if (!count)
        {
            txPending = false;
            return;
        }
        if ((!configured()) || (!terminal_connected))
        {
            // An error occured, data was lost.
            txPending = false;
            serialPriv->overrunCount += count;
            return;
        }
        txPending = true;
        sendNB(txData, count);
    }

    void RxThread()
    {
        while (1)
        {
            os_sem_wait(&rxSem);
            portENTER_CRITICAL();
            // we read the packet received to our assembly buffer
            bool result = readEP_NB(rxData, &rxSize);
            portEXIT_CRITICAL();
            if (!result)
            {
                diewith(0x80000CCC);
            }
            for (uint32_t i = 0; i < rxSize; i++)
            {
                os_mq_send(serialPriv->rxQ, rxData + i);
            }
            rxSize = 0;
            // We reactivate the endpoint to receive next characters
            // readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
        }
    }

    static void* _RxThread(void* arg)
    {
        ((MbedRawUSBSerial*)arg)->RxThread();
        return NULL;
    }

    uint8_t txData[MAX_TX_PACKET_LENGTH]; /**< packet assemby buffer to host */
    uint32_t rxSize; /**< number of valid characters in rxData */
    uint8_t rxData
        [MAX_RX_PACKET_LENGTH]; /**< packet assembly buffer from host */
    bool txPending;             /**< transmission currently pending */
    os_sem_t rxSem;
};

/** Private data for this implementation of Serial port
 */
class MbedSerialPriv
{
public:
    MbedSerialPriv() : serial(NULL)
    {
    }
    SerialPriv serialPriv;    /**< common private data */
    MbedRawUSBSerial* serial; /*< USB implementation object */
};

/** private data for the can device */
static MbedSerialPriv serial_private[1];

static int mbed_usbserial_init(devtab_t* dev);
static void ignore_dev_function(devtab_t* dev);
static void mbed_usbserial_tx_msg(devtab_t* dev);

void* operator new(size_t size)
{
    return malloc(size);
}

void* operator new [](size_t size)
{ return malloc(size); } void
operator delete(void* ptr)
{
    free(ptr);
}

void operator delete [](void* ptr)
{ free(ptr); } int __cxa_guard_acquire(__guard* g)
{
    return !*(char*)(g);
};
void __cxa_guard_release(__guard* g)
{
    *(char*)g = 1;
};
void __cxa_guard_abort(__guard*) {};

void __cxa_pure_virtual(void) {};

/** initialize the device
 * @param dev device to initialize
 * @return 0 upon success
 */
static int mbed_usbserial_init(devtab_t* dev)
{
    MbedSerialPriv* priv = (MbedSerialPriv*)dev->priv;
    int r = serial_init(dev);
    if (r)
        return r;
    priv->serial = new MbedRawUSBSerial(&priv->serialPriv);
    priv->serialPriv.enable = ignore_dev_function;
    priv->serialPriv.disable = ignore_dev_function;
    priv->serialPriv.tx_char = mbed_usbserial_tx_msg;
    // priv->serial->attach(priv, &MbedSerialPriv::RxCallback);
    // priv->serial->txattach(priv, &MbedSerialPriv::TxCallback);
    return r;
}

/** Empty device function. Does nothing.
 * @param dev device
 */
static void ignore_dev_function(devtab_t* dev)
{
}

/** Try and transmit a message. Does nothing if there is no message to transmit
 *  or no write buffers to transmit via.
 * @param dev device to transmit message on
 */
static void mbed_usbserial_tx_msg(devtab_t* dev)
{
    MbedSerialPriv* priv = (MbedSerialPriv*)dev->priv;
    priv->serial->Transmit();
}

/** Device table entry for serial device */
static SERIAL_DEVTAB_ENTRY(serUSB0, "/dev/serUSB0", mbed_usbserial_init,
                           &serial_private[0]);
<commit_msg>Finalizes port of mbed usbserial to the c++ api.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * 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.
 *
 * 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 HOLDER 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.
 *
 * \file mbed_usbserial.cpp
 * This file implements an USB-Serial driver on top of the mbed
 * library. Currently it is tested on the LPC23xx processors.
 *
 * @author Balazs Racz
 * @date 4 May 2013
 */

#include "mbed.h"
#include "USBSerial.h"
#include "Serial.hxx"
#include "os/os.h"
#include "utils/macros.h"
#include "portmacro.h"

#ifdef TARGET_LPC2368
#endif

#define TX_DATA_SIZE 64
#define RX_DATA_SIZE 64

#include <stdlib.h>

void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* ptr);
void operator delete[](void* ptr);

__extension__ typedef int __guard __attribute__((mode(__DI__)));

extern "C" int __cxa_guard_acquire(__guard*);
extern "C" void __cxa_guard_release(__guard*);
extern "C" void __cxa_guard_abort(__guard*);

extern "C" void __cxa_pure_virtual(void);

/** This class is an empty wrapper around MBed's USB CDC class. The difference
    between this and mbed::USBSerial is that this class does not have any
    buffering and no interaction with stdio, whereas mbed::USBSerial has the
    following buffering:
    * it has a 128-byte receive buffer.
    * it has an fd
    * it has a FILE* with a default-sized send/receive buffer
    * it requires mbed's custom glue code in the open(2) method, without which
      it crashes.
 */
class MbedRawUSBSerial : public USBCDC, public ::Serial
{
public:
    MbedRawUSBSerial(const char* name, uint16_t vendor_id = 0x1f00,
                     uint16_t product_id = 0x2012,
                     uint16_t product_release = 0x0001)
        : USBCDC(vendor_id, product_id, product_release),
          Serial(name),
          txPending(false)
    {
        os_sem_init(&rxSem, 0);
        os_thread_t thread;
        os_thread_create(&thread, "usbserial.rx", 1, 1024, &_RxThread, this);
    }

    ~MbedRawUSBSerial()
    {
        os_sem_destroy(&rxSem);
    }

protected:
    virtual bool EP2_OUT_callback()
    {
        //HASSERT(IsEpPending());
        // and wake up the RX thread.
        os_sem_post_from_isr(&rxSem);
        return false;
    }

    virtual bool EP2_IN_callback()
    {
        int count;
        int woken = 0;
        configASSERT(txPending);
        for (count = 0; count < MAX_TX_PACKET_LENGTH; count++)
        {
            if (os_mq_receive_from_isr(txQ, &txData[count],
                                       &woken) != OS_MQ_NONE)
            {
                /* no more data left to transmit */
                break;
            }
        }
        TxHelper(count);
        if (woken)
        {
#ifdef TARGET_LPC1768
            portYIELD();
#elif defined(TARGET_LPC2368)
/** @todo(balazs.racz): need to find a way to yield on ARM7. The builtin
 * portYIELD_FROM_ISR assumes that we have entered the ISR with context
 * saving, which we didn't. */
#else
#error define how to yield on your CPU.
#endif
        }
        return true;
    }

private:
    void enable()
    {
    } /**< function to enable device */
    void disable()
    {
    } /**< function to disable device */

    /** function to try and transmit a character */
    void tx_char()
    {
        // Without this critical section there were cases when we deadlocked
        // with txPending == true but no interrupt coming in to clear it.
        taskENTER_CRITICAL();
        if (txPending)
        {
            taskEXIT_CRITICAL();
            return;
        }
        txPending = true;
        int count;
        for (count = 0; count < TX_DATA_SIZE; count++)
        {
            if (os_mq_timedreceive(txQ, txData + count, 0) !=
                OS_MQ_NONE)
            {
                /* no more data left to transmit */
                break;
            }
        }
        TxHelper(count);
        taskEXIT_CRITICAL();
    }

    static const int MAX_TX_PACKET_LENGTH = 64;
    static const int MAX_RX_PACKET_LENGTH = 64;

    /** Transmits count bytes from the txData buffer. Sets txPending and
        bytesLost as needed. */
    void TxHelper(int count)
    {
        if (!count)
        {
            txPending = false;
            return;
        }
        if ((!configured()) || (!terminal_connected))
        {
            // An error occured, data was lost.
            txPending = false;
            overrunCount += count;
            return;
        }
        txPending = true;
        sendNB(txData, count);
    }

    void RxThread()
    {
        while (1)
        {
            os_sem_wait(&rxSem);
            portENTER_CRITICAL();
            // we read the packet received to our assembly buffer
            bool result = readEP_NB(rxData, &rxSize);
            portEXIT_CRITICAL();
            if (!result)
            {
                diewith(0x80000CCC);
            }
            for (uint32_t i = 0; i < rxSize; i++)
            {
                os_mq_send(rxQ, rxData + i);
            }
            rxSize = 0;
            // We reactivate the endpoint to receive next characters
            // readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
        }
    }

    static void* _RxThread(void* arg)
    {
        ((MbedRawUSBSerial*)arg)->RxThread();
        return NULL;
    }

    uint8_t txData[MAX_TX_PACKET_LENGTH]; /**< packet assemby buffer to host */
    uint32_t rxSize; /**< number of valid characters in rxData */
    uint8_t rxData
        [MAX_RX_PACKET_LENGTH]; /**< packet assembly buffer from host */
    bool txPending;             /**< transmission currently pending */
    os_sem_t rxSem;
};

void* operator new(size_t size)
{
    return malloc(size);
}

void* operator new [](size_t size)
{ return malloc(size); } void
operator delete(void* ptr)
{
    free(ptr);
}

void operator delete [](void* ptr)
{ free(ptr); } int __cxa_guard_acquire(__guard* g)
{
    return !*(char*)(g);
};
void __cxa_guard_release(__guard* g)
{
    *(char*)g = 1;
};
void __cxa_guard_abort(__guard*) {};

void __cxa_pure_virtual(void) {};

MbedRawUSBSerial g_mbed_usb_serial("/dev/serUSB0");

<|endoftext|>


<commit_before>/** @file
 *  @brief Implementation of interface to the core framework
 *  @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#include "Allpix.hpp"

#include <chrono>
#include <climits>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <thread>
#include <utility>

#include <TROOT.h>
#include <TRandom.h>
#include <TStyle.h>
#include <TSystem.h>

#include "core/config/exceptions.h"
#include "core/utils/file.h"
#include "core/utils/log.h"
#include "core/utils/unit.h"

using namespace allpix;

/**
 * This class will own the managers for the lifetime of the simulation. Will do early initialization:
 * - Configure the special header sections.
 * - Set the log level and log format as requested.
 * - Load the detector configuration and parse it
 */
Allpix::Allpix(std::string config_file_name,
               const std::vector<std::string>& module_options,
               const std::vector<std::string>& detector_options)
    : terminate_(false), has_run_(false), msg_(std::make_unique<Messenger>()), mod_mgr_(std::make_unique<ModuleManager>()),
      geo_mgr_(std::make_unique<GeometryManager>()) {
    // Load the global configuration
    conf_mgr_ = std::make_unique<ConfigManager>(std::move(config_file_name),
                                                std::initializer_list<std::string>({"Allpix", ""}),
                                                std::initializer_list<std::string>({"Ignore"}));

    // Load and apply the provided module options
    conf_mgr_->loadModuleOptions(module_options);

    // Load and apply the provided detector options
    conf_mgr_->loadDetectorOptions(detector_options);

    // Fetch the global configuration
    Configuration& global_config = conf_mgr_->getGlobalConfiguration();

    // Set the log level from config if not specified earlier
    std::string log_level_string;
    if(Log::getReportingLevel() == LogLevel::NONE) {
        log_level_string = global_config.get<std::string>("log_level", "INFO");
        std::transform(log_level_string.begin(), log_level_string.end(), log_level_string.begin(), ::toupper);
        try {
            LogLevel log_level = Log::getLevelFromString(log_level_string);
            Log::setReportingLevel(log_level);
        } catch(std::invalid_argument& e) {
            LOG(ERROR) << "Log level \"" << log_level_string
                       << "\" specified in the configuration is invalid, defaulting to INFO instead";
            Log::setReportingLevel(LogLevel::INFO);
        }
    } else {
        log_level_string = Log::getStringFromLevel(Log::getReportingLevel());
    }

    // Set the log format from config
    std::string log_format_string = global_config.get<std::string>("log_format", "DEFAULT");
    std::transform(log_format_string.begin(), log_format_string.end(), log_format_string.begin(), ::toupper);
    try {
        LogFormat log_format = Log::getFormatFromString(log_format_string);
        Log::setFormat(log_format);
    } catch(std::invalid_argument& e) {
        LOG(ERROR) << "Log format \"" << log_format_string
                   << "\" specified in the configuration is invalid, using DEFAULT instead";
        Log::setFormat(LogFormat::DEFAULT);
    }

    // Open log file to write output to
    if(global_config.has("log_file")) {
        // NOTE: this stream should be available for the duration of the logging
        log_file_.open(global_config.getPath("log_file"), std::ios_base::out | std::ios_base::trunc);
        LOG(TRACE) << "Added log stream to file " << global_config.getPath("log_file");
        Log::addStream(log_file_);
    }

    // Wait for the first detailed messages until level and format are properly set
    LOG(TRACE) << "Global log level is set to " << log_level_string;
    LOG(TRACE) << "Global log format is set to " << log_format_string;
}

/**
 * Performs the initialization, including:
 * - Initialize the random seeder
 * - Determine and create the output directory
 * - Include all the defined units
 * - Load the modules from the configuration
 */
void Allpix::load() {
    LOG(TRACE) << "Loading Allpix";

    // Fetch the global configuration
    Configuration& global_config = conf_mgr_->getGlobalConfiguration();

    // Put welcome message and set version
    LOG(STATUS) << "Welcome to Allpix^2 " << ALLPIX_PROJECT_VERSION;
    global_config.set<std::string>("version", ALLPIX_PROJECT_VERSION);

    // Initialize the random seeders, one for modules, one for core components
    std::mt19937_64 seeder_modules;
    std::mt19937_64 seeder_core;

    uint64_t seed = 0;
    if(global_config.has("random_seed")) {
        // Use provided random seed
        seed = global_config.get<uint64_t>("random_seed");
        seeder_modules.seed(seed);
        LOG(STATUS) << "Initialized PRNG with configured seed " << seed;
    } else {
        // Compute random entropy seed
        // Use the clock
        auto clock_seed = static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
        // Use memory location local variable
        auto mem_seed = reinterpret_cast<uint64_t>(&seed); // NOLINT
        // Use thread id
        std::hash<std::thread::id> thrd_hasher;
        auto thread_seed = thrd_hasher(std::this_thread::get_id());
        seed = (clock_seed ^ mem_seed ^ thread_seed);
        seeder_modules.seed(seed);
        LOG(STATUS) << "Initialized PRNG with system entropy seed " << seed;
        global_config.set<uint64_t>("random_seed", seed);
    }

    if(global_config.has("random_seed_core")) {
        // Use provided random seed
        seed = global_config.get<uint64_t>("random_seed_core");
        seeder_core.seed(seed);
        LOG(STATUS) << "Initialized core PRNG with configured seed " << seed;
    } else {
        // Use module seeder + 1
        seeder_core.seed(seed + 1);
        global_config.set<uint64_t>("random_seed_core", seed + 1);
    }

    // Initialize ROOT random generator
    gRandom->SetSeed(seeder_modules());

    // Get output directory
    std::string directory = gSystem->pwd();
    directory += "/output";
    if(global_config.has("output_directory")) {
        // Use config specified one if available
        directory = global_config.getPath("output_directory");
    }

    // Use existing output directory if it exists
    bool create_output_dir = true;
    if(allpix::path_is_directory(directory)) {
        if(global_config.get<bool>("purge_output_directory", false)) {
            LOG(DEBUG) << "Deleting previous output directory " << directory;
            allpix::remove_path(directory);
        } else {
            LOG(DEBUG) << "Output directory " << directory << " already exists";
            create_output_dir = false;
        }
    }
    // Create the output directory
    try {
        if(create_output_dir) {
            LOG(DEBUG) << "Creating output directory " << directory;
            allpix::create_directories(directory);
        }
        // Change to the new/existing output directory
        gSystem->ChangeDirectory(directory.c_str());
    } catch(std::invalid_argument& e) {
        LOG(ERROR) << "Cannot create output directory " << directory << ": " << e.what()
                   << ". Using current directory instead.";
    }

    // Enable relevant multithreading if needed (disabled by default)
    if(global_config.get<bool>("experimental_multithreading", false)) {
        // Enable thread safety for ROOT
        ROOT::EnableThreadSafety();
    }

    // Set the default units to use
    add_units();

    // Set the ROOT style
    set_style();

    // Load the geometry
    geo_mgr_->load(conf_mgr_.get(), seeder_core);

    // Load the modules from the configuration
    if(!terminate_) {
        mod_mgr_->load(msg_.get(), conf_mgr_.get(), geo_mgr_.get(), seeder_modules);
    } else {
        LOG(INFO) << "Skip loading modules because termination is requested";
    }
}

/**
 * Runs the Module::init() method linearly for every module
 */
void Allpix::init() {
    if(!terminate_) {
        LOG(TRACE) << "Initializing Allpix";
        mod_mgr_->init();
    } else {
        LOG(INFO) << "Skip initializing modules because termination is requested";
    }
}
/**
 * Runs every modules Module::run() method linearly for the number of events
 */
void Allpix::run() {
    if(!terminate_) {
        LOG(TRACE) << "Running Allpix";
        mod_mgr_->run();

        // Set that we have run and want to finalize as well
        has_run_ = true;
    } else {
        LOG(INFO) << "Skip running modules because termination is requested";
    }
}
/**
 * Runs all modules Module::finalize() method linearly for every module
 */
void Allpix::finalize() {
    if(has_run_) {
        LOG(TRACE) << "Finalizing Allpix";
        mod_mgr_->finalize();
    } else {
        LOG(INFO) << "Skip finalizing modules because no module did run";
    }
}

/*
 * This function can be called safely from any signal handler. Time between the request to terminate
 * and the actual termination is not always negigible.
 */
void Allpix::terminate() {
    terminate_ = true;
    mod_mgr_->terminate();
}

void Allpix::add_units() {
    LOG(TRACE) << "Adding physical units";

    // LENGTH
    Units::add("nm", 1e-6);
    Units::add("um", 1e-3);
    Units::add("mm", 1);
    Units::add("cm", 1e1);
    Units::add("dm", 1e2);
    Units::add("m", 1e3);
    Units::add("km", 1e6);

    // TIME
    Units::add("ps", 1e-3);
    Units::add("ns", 1);
    Units::add("us", 1e3);
    Units::add("ms", 1e6);
    Units::add("s", 1e9);

    // TEMPERATURE
    Units::add("K", 1);

    // ENERGY
    Units::add("eV", 1e-6);
    Units::add("keV", 1e-3);
    Units::add("MeV", 1);
    Units::add("GeV", 1e3);

    // CHARGE
    Units::add("e", 1);
    Units::add("ke", 1e3);
    Units::add("C", 1.6021766208e-19);

    // VOLTAGE
    // NOTE: fixed by above
    Units::add("V", 1e-6);
    Units::add("kV", 1e-3);

    // MAGNETIC FIELD
    Units::add("T", 1e-3);
    Units::add("mT", 1e-6);

    // ANGLES
    // NOTE: these are fake units
    Units::add("deg", 0.01745329252);
    Units::add("rad", 1);
    Units::add("mrad", 1e-3);
}

/**
 * This style is inspired by the CLICdp plot style
 */
void Allpix::set_style() {
    LOG(TRACE) << "Setting ROOT plotting style";

    // use plain style as base
    gROOT->SetStyle("Plain");
    TStyle* style = gROOT->GetStyle("Plain");

    // Prefer OpenGL if available
    style->SetCanvasPreferGL(kTRUE);

    // Set backgrounds
    style->SetCanvasColor(kWhite);
    style->SetFrameFillColor(kWhite);
    style->SetStatColor(kWhite);
    style->SetPadColor(kWhite);
    style->SetFillColor(10);
    style->SetTitleFillColor(kWhite);

    // SetPaperSize wants width & height in cm: A4 is 20,26
    style->SetPaperSize(20, 26);
    // No yellow border around histogram
    style->SetDrawBorder(0);
    // Remove border of canvas*
    style->SetCanvasBorderMode(0);
    // Remove border of pads
    style->SetPadBorderMode(0);
    style->SetFrameBorderMode(0);
    style->SetLegendBorderSize(0);

    // Default text size
    style->SetTextSize(0.04f);
    style->SetTitleSize(0.04f, "xyz");
    style->SetLabelSize(0.03f, "xyz");

    // Title offset: distance between given text and axis
    style->SetLabelOffset(0.01f, "xyz");
    style->SetTitleOffset(1.6f, "yz");
    style->SetTitleOffset(1.4f, "x");

    // Set font settings
    short font = 42; // Use a clear font
    style->SetTitleFont(font);
    style->SetTitleFontSize(0.06f);
    style->SetStatFont(font);
    style->SetStatFontSize(0.07f);
    style->SetTextFont(font);
    style->SetLabelFont(font, "xyz");
    style->SetTitleFont(font, "xyz");
    style->SetTitleBorderSize(0);
    style->SetStatBorderSize(1);

    // Set style for markers
    style->SetMarkerStyle(1);
    style->SetLineWidth(2);
    style->SetMarkerSize(1.2f);

    // Set palette in 2d histogram to nice and colorful one
    style->SetPalette(1, nullptr);

    // Disable title by default for histograms
    style->SetOptTitle(0);

    // Set statistics
    style->SetOptStat(0);
    style->SetOptFit(0);

    // Number of decimals used for errors
    style->SetEndErrorSize(5);

    // Set line width to 2 by default so that histograms are visible when printed small
    // Idea: emphasize the data, not the frame around
    style->SetHistLineWidth(2);
    style->SetFrameLineWidth(2);
    style->SetFuncWidth(2);
    style->SetHistLineColor(kBlack);
    style->SetFuncColor(kRed);
    style->SetLabelColor(kBlack, "xyz");

    // Set the margins
    style->SetPadBottomMargin(0.18f);
    style->SetPadTopMargin(0.08f);
    style->SetPadRightMargin(0.18f);
    style->SetPadLeftMargin(0.17f);

    // Set the default number of divisions to show
    style->SetNdivisions(506, "xy");

    // Turn off xy grids
    style->SetPadGridX(false);
    style->SetPadGridY(false);

    // Set the tick mark style
    style->SetPadTickX(1);
    style->SetPadTickY(1);
    style->SetCanvasDefW(800);
    style->SetCanvasDefH(700);

    // Force the style
    gROOT->ForceStyle();
}
<commit_msg>Fixing bug with units conversion to Coulombs and adding fC to units.<commit_after>/** @file
 *  @brief Implementation of interface to the core framework
 *  @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#include "Allpix.hpp"

#include <chrono>
#include <climits>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <thread>
#include <utility>

#include <TROOT.h>
#include <TRandom.h>
#include <TStyle.h>
#include <TSystem.h>

#include "core/config/exceptions.h"
#include "core/utils/file.h"
#include "core/utils/log.h"
#include "core/utils/unit.h"

using namespace allpix;

/**
 * This class will own the managers for the lifetime of the simulation. Will do early initialization:
 * - Configure the special header sections.
 * - Set the log level and log format as requested.
 * - Load the detector configuration and parse it
 */
Allpix::Allpix(std::string config_file_name,
               const std::vector<std::string>& module_options,
               const std::vector<std::string>& detector_options)
    : terminate_(false), has_run_(false), msg_(std::make_unique<Messenger>()), mod_mgr_(std::make_unique<ModuleManager>()),
      geo_mgr_(std::make_unique<GeometryManager>()) {
    // Load the global configuration
    conf_mgr_ = std::make_unique<ConfigManager>(std::move(config_file_name),
                                                std::initializer_list<std::string>({"Allpix", ""}),
                                                std::initializer_list<std::string>({"Ignore"}));

    // Load and apply the provided module options
    conf_mgr_->loadModuleOptions(module_options);

    // Load and apply the provided detector options
    conf_mgr_->loadDetectorOptions(detector_options);

    // Fetch the global configuration
    Configuration& global_config = conf_mgr_->getGlobalConfiguration();

    // Set the log level from config if not specified earlier
    std::string log_level_string;
    if(Log::getReportingLevel() == LogLevel::NONE) {
        log_level_string = global_config.get<std::string>("log_level", "INFO");
        std::transform(log_level_string.begin(), log_level_string.end(), log_level_string.begin(), ::toupper);
        try {
            LogLevel log_level = Log::getLevelFromString(log_level_string);
            Log::setReportingLevel(log_level);
        } catch(std::invalid_argument& e) {
            LOG(ERROR) << "Log level \"" << log_level_string
                       << "\" specified in the configuration is invalid, defaulting to INFO instead";
            Log::setReportingLevel(LogLevel::INFO);
        }
    } else {
        log_level_string = Log::getStringFromLevel(Log::getReportingLevel());
    }

    // Set the log format from config
    std::string log_format_string = global_config.get<std::string>("log_format", "DEFAULT");
    std::transform(log_format_string.begin(), log_format_string.end(), log_format_string.begin(), ::toupper);
    try {
        LogFormat log_format = Log::getFormatFromString(log_format_string);
        Log::setFormat(log_format);
    } catch(std::invalid_argument& e) {
        LOG(ERROR) << "Log format \"" << log_format_string
                   << "\" specified in the configuration is invalid, using DEFAULT instead";
        Log::setFormat(LogFormat::DEFAULT);
    }

    // Open log file to write output to
    if(global_config.has("log_file")) {
        // NOTE: this stream should be available for the duration of the logging
        log_file_.open(global_config.getPath("log_file"), std::ios_base::out | std::ios_base::trunc);
        LOG(TRACE) << "Added log stream to file " << global_config.getPath("log_file");
        Log::addStream(log_file_);
    }

    // Wait for the first detailed messages until level and format are properly set
    LOG(TRACE) << "Global log level is set to " << log_level_string;
    LOG(TRACE) << "Global log format is set to " << log_format_string;
}

/**
 * Performs the initialization, including:
 * - Initialize the random seeder
 * - Determine and create the output directory
 * - Include all the defined units
 * - Load the modules from the configuration
 */
void Allpix::load() {
    LOG(TRACE) << "Loading Allpix";

    // Fetch the global configuration
    Configuration& global_config = conf_mgr_->getGlobalConfiguration();

    // Put welcome message and set version
    LOG(STATUS) << "Welcome to Allpix^2 " << ALLPIX_PROJECT_VERSION;
    global_config.set<std::string>("version", ALLPIX_PROJECT_VERSION);

    // Initialize the random seeders, one for modules, one for core components
    std::mt19937_64 seeder_modules;
    std::mt19937_64 seeder_core;

    uint64_t seed = 0;
    if(global_config.has("random_seed")) {
        // Use provided random seed
        seed = global_config.get<uint64_t>("random_seed");
        seeder_modules.seed(seed);
        LOG(STATUS) << "Initialized PRNG with configured seed " << seed;
    } else {
        // Compute random entropy seed
        // Use the clock
        auto clock_seed = static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
        // Use memory location local variable
        auto mem_seed = reinterpret_cast<uint64_t>(&seed); // NOLINT
        // Use thread id
        std::hash<std::thread::id> thrd_hasher;
        auto thread_seed = thrd_hasher(std::this_thread::get_id());
        seed = (clock_seed ^ mem_seed ^ thread_seed);
        seeder_modules.seed(seed);
        LOG(STATUS) << "Initialized PRNG with system entropy seed " << seed;
        global_config.set<uint64_t>("random_seed", seed);
    }

    if(global_config.has("random_seed_core")) {
        // Use provided random seed
        seed = global_config.get<uint64_t>("random_seed_core");
        seeder_core.seed(seed);
        LOG(STATUS) << "Initialized core PRNG with configured seed " << seed;
    } else {
        // Use module seeder + 1
        seeder_core.seed(seed + 1);
        global_config.set<uint64_t>("random_seed_core", seed + 1);
    }

    // Initialize ROOT random generator
    gRandom->SetSeed(seeder_modules());

    // Get output directory
    std::string directory = gSystem->pwd();
    directory += "/output";
    if(global_config.has("output_directory")) {
        // Use config specified one if available
        directory = global_config.getPath("output_directory");
    }

    // Use existing output directory if it exists
    bool create_output_dir = true;
    if(allpix::path_is_directory(directory)) {
        if(global_config.get<bool>("purge_output_directory", false)) {
            LOG(DEBUG) << "Deleting previous output directory " << directory;
            allpix::remove_path(directory);
        } else {
            LOG(DEBUG) << "Output directory " << directory << " already exists";
            create_output_dir = false;
        }
    }
    // Create the output directory
    try {
        if(create_output_dir) {
            LOG(DEBUG) << "Creating output directory " << directory;
            allpix::create_directories(directory);
        }
        // Change to the new/existing output directory
        gSystem->ChangeDirectory(directory.c_str());
    } catch(std::invalid_argument& e) {
        LOG(ERROR) << "Cannot create output directory " << directory << ": " << e.what()
                   << ". Using current directory instead.";
    }

    // Enable relevant multithreading if needed (disabled by default)
    if(global_config.get<bool>("experimental_multithreading", false)) {
        // Enable thread safety for ROOT
        ROOT::EnableThreadSafety();
    }

    // Set the default units to use
    add_units();

    // Set the ROOT style
    set_style();

    // Load the geometry
    geo_mgr_->load(conf_mgr_.get(), seeder_core);

    // Load the modules from the configuration
    if(!terminate_) {
        mod_mgr_->load(msg_.get(), conf_mgr_.get(), geo_mgr_.get(), seeder_modules);
    } else {
        LOG(INFO) << "Skip loading modules because termination is requested";
    }
}

/**
 * Runs the Module::init() method linearly for every module
 */
void Allpix::init() {
    if(!terminate_) {
        LOG(TRACE) << "Initializing Allpix";
        mod_mgr_->init();
    } else {
        LOG(INFO) << "Skip initializing modules because termination is requested";
    }
}
/**
 * Runs every modules Module::run() method linearly for the number of events
 */
void Allpix::run() {
    if(!terminate_) {
        LOG(TRACE) << "Running Allpix";
        mod_mgr_->run();

        // Set that we have run and want to finalize as well
        has_run_ = true;
    } else {
        LOG(INFO) << "Skip running modules because termination is requested";
    }
}
/**
 * Runs all modules Module::finalize() method linearly for every module
 */
void Allpix::finalize() {
    if(has_run_) {
        LOG(TRACE) << "Finalizing Allpix";
        mod_mgr_->finalize();
    } else {
        LOG(INFO) << "Skip finalizing modules because no module did run";
    }
}

/*
 * This function can be called safely from any signal handler. Time between the request to terminate
 * and the actual termination is not always negigible.
 */
void Allpix::terminate() {
    terminate_ = true;
    mod_mgr_->terminate();
}

void Allpix::add_units() {
    LOG(TRACE) << "Adding physical units";

    // LENGTH
    Units::add("nm", 1e-6);
    Units::add("um", 1e-3);
    Units::add("mm", 1);
    Units::add("cm", 1e1);
    Units::add("dm", 1e2);
    Units::add("m", 1e3);
    Units::add("km", 1e6);

    // TIME
    Units::add("ps", 1e-3);
    Units::add("ns", 1);
    Units::add("us", 1e3);
    Units::add("ms", 1e6);
    Units::add("s", 1e9);

    // TEMPERATURE
    Units::add("K", 1);

    // ENERGY
    Units::add("eV", 1e-6);
    Units::add("keV", 1e-3);
    Units::add("MeV", 1);
    Units::add("GeV", 1e3);

    // CHARGE
    Units::add("e", 1);
    Units::add("ke", 1e3);
    Units::add("fC", 1/1.6021766208e-4);
    Units::add("C", 1/1.6021766208e-19);

    // VOLTAGE
    // NOTE: fixed by above
    Units::add("V", 1e-6);
    Units::add("kV", 1e-3);

    // MAGNETIC FIELD
    Units::add("T", 1e-3);
    Units::add("mT", 1e-6);

    // ANGLES
    // NOTE: these are fake units
    Units::add("deg", 0.01745329252);
    Units::add("rad", 1);
    Units::add("mrad", 1e-3);
}

/**
 * This style is inspired by the CLICdp plot style
 */
void Allpix::set_style() {
    LOG(TRACE) << "Setting ROOT plotting style";

    // use plain style as base
    gROOT->SetStyle("Plain");
    TStyle* style = gROOT->GetStyle("Plain");

    // Prefer OpenGL if available
    style->SetCanvasPreferGL(kTRUE);

    // Set backgrounds
    style->SetCanvasColor(kWhite);
    style->SetFrameFillColor(kWhite);
    style->SetStatColor(kWhite);
    style->SetPadColor(kWhite);
    style->SetFillColor(10);
    style->SetTitleFillColor(kWhite);

    // SetPaperSize wants width & height in cm: A4 is 20,26
    style->SetPaperSize(20, 26);
    // No yellow border around histogram
    style->SetDrawBorder(0);
    // Remove border of canvas*
    style->SetCanvasBorderMode(0);
    // Remove border of pads
    style->SetPadBorderMode(0);
    style->SetFrameBorderMode(0);
    style->SetLegendBorderSize(0);

    // Default text size
    style->SetTextSize(0.04f);
    style->SetTitleSize(0.04f, "xyz");
    style->SetLabelSize(0.03f, "xyz");

    // Title offset: distance between given text and axis
    style->SetLabelOffset(0.01f, "xyz");
    style->SetTitleOffset(1.6f, "yz");
    style->SetTitleOffset(1.4f, "x");

    // Set font settings
    short font = 42; // Use a clear font
    style->SetTitleFont(font);
    style->SetTitleFontSize(0.06f);
    style->SetStatFont(font);
    style->SetStatFontSize(0.07f);
    style->SetTextFont(font);
    style->SetLabelFont(font, "xyz");
    style->SetTitleFont(font, "xyz");
    style->SetTitleBorderSize(0);
    style->SetStatBorderSize(1);

    // Set style for markers
    style->SetMarkerStyle(1);
    style->SetLineWidth(2);
    style->SetMarkerSize(1.2f);

    // Set palette in 2d histogram to nice and colorful one
    style->SetPalette(1, nullptr);

    // Disable title by default for histograms
    style->SetOptTitle(0);

    // Set statistics
    style->SetOptStat(0);
    style->SetOptFit(0);

    // Number of decimals used for errors
    style->SetEndErrorSize(5);

    // Set line width to 2 by default so that histograms are visible when printed small
    // Idea: emphasize the data, not the frame around
    style->SetHistLineWidth(2);
    style->SetFrameLineWidth(2);
    style->SetFuncWidth(2);
    style->SetHistLineColor(kBlack);
    style->SetFuncColor(kRed);
    style->SetLabelColor(kBlack, "xyz");

    // Set the margins
    style->SetPadBottomMargin(0.18f);
    style->SetPadTopMargin(0.08f);
    style->SetPadRightMargin(0.18f);
    style->SetPadLeftMargin(0.17f);

    // Set the default number of divisions to show
    style->SetNdivisions(506, "xy");

    // Turn off xy grids
    style->SetPadGridX(false);
    style->SetPadGridY(false);

    // Set the tick mark style
    style->SetPadTickX(1);
    style->SetPadTickY(1);
    style->SetCanvasDefW(800);
    style->SetCanvasDefH(700);

    // Force the style
    gROOT->ForceStyle();
}
<|endoftext|>