Skip to content
Snippets Groups Projects
binary_c_python.c 18 KiB
Newer Older
#include <Python.h>
#include "binary_c_python.h"

/*
 * binary_c/PYTHON API interface functions
 *
 * Remember: variables must be passed by references
 * (i.e. as pointers).
 *
David Hendriks's avatar
David Hendriks committed
 * See apitest.py for an example of how to use these functions.
 *
 * See also
 * http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html
 */

/* list of variables used in the Py<>C interface */

/************************************************************/
/*
 * function prototypes : these are the functions
 * called by PYTHON code, without the trailing underscore.
 */
/************************************************************/

David Hendriks's avatar
David Hendriks committed
// Docstrings
static char module_docstring[] MAYBE_UNUSED =
    "This module is a python wrapper around binary_c";
#ifdef __DEPRECATED
static char create_binary_docstring[] =
    "Allocate memory for a binary";
#endif
static char function_prototype_docstring[] =
    "The prototype for a binary_c python function";
static char new_binary_system_docstring[] =
    "Return an object containing a binary, ready for evolution";

// Evolution function docstrings
static char run_binary_docstring[] =
    "Run one binary using binary_c";
static char run_binary_with_log_docstring[] =
David Hendriks's avatar
David Hendriks committed
    "Run one binary using binary_c and allow the logfile to be written. Do not use for populations!";
static char run_binary_custom_logging_docstring[] =
David Hendriks's avatar
David Hendriks committed
    "TODO";
static char run_population_docstring[] = 
    "Run population of systems";
static char run_system_docstring[] = 
    "Function to run a system. This is a general function that will be able to handle different kinds of situations: single system run with different settings, population run with different settings, etc. To avoid having too many functions doing slightly different things.";
David Hendriks's avatar
David Hendriks committed
static char return_arglines_docstring[] =
    "Return the default args for a binary_c system";
static char return_help_info_docstring[] = 
    "Return the help info for a given parameter";
static char return_help_all_info_docstring[] = 
    "Return an overview of all the parameters, their description, categorized in sections";
static char return_version_info_docstring[] = 
    "Return the version information of the used binary_c build";

// other functionality
static char return_store_docstring[] = 
    "Return the store memory adress that will be passed to run_population";

static struct libbinary_c_store_t *store = NULL;

David Hendriks's avatar
David Hendriks committed
// Initialize pyobjects
#ifdef __DEPRECATED
static PyObject* binary_c_create_binary(PyObject *self, PyObject *args);
#endif
static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args);
static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args);

// Evolution function headers
static PyObject* binary_c_run_binary(PyObject *self, PyObject *args);
David Hendriks's avatar
David Hendriks committed
static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args);
static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *args);
static PyObject* binary_c_run_population(PyObject *self, PyObject *args);
static PyObject* binary_c_run_system(PyObject *self, PyObject *args);
David Hendriks's avatar
David Hendriks committed
static PyObject* binary_c_return_arglines(PyObject *self, PyObject *args);
static PyObject* binary_c_return_help_info(PyObject *self, PyObject *args);
static PyObject* binary_c_return_help_all_info(PyObject *self, PyObject *args);
static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args);

// Other function headers
static PyObject* binary_c_return_store(PyObject *self, PyObject *args);

/*
 * Python 3 interface is described at
 *
 * http://scipy-lectures.org/advanced/interfacing_with_c/interfacing_with_c.html
 */

static PyMethodDef module_methods[] = {
#ifdef __DEPRECATED
David Hendriks's avatar
David Hendriks committed
    {"create_binary", 
        binary_c_create_binary, 
        METH_VARARGS, 
        create_binary_docstring
    },
    {"function_prototype", binary_c_function_prototype, METH_VARARGS, function_prototype_docstring},
    {"new_system", binary_c_new_binary_system, METH_VARARGS, new_binary_system_docstring},

    {"run_binary", binary_c_run_binary, METH_VARARGS, run_binary_docstring},
    {"run_binary_with_logfile", binary_c_run_binary_with_logfile, METH_VARARGS, run_binary_with_log_docstring},
    {"run_binary_custom_logging", binary_c_run_binary_custom_logging, METH_VARARGS, run_binary_custom_logging_docstring},
    {"run_population", binary_c_run_population, METH_VARARGS, run_population_docstring},
    {"run_system", binary_c_run_system, METH_VARARGS, run_system_docstring},


David Hendriks's avatar
David Hendriks committed
    {"return_arglines", binary_c_return_arglines, METH_VARARGS, return_arglines_docstring},
    {"return_help", binary_c_return_help_info, METH_VARARGS, return_help_info_docstring},
    {"return_help_all", binary_c_return_help_all_info, METH_VARARGS, return_help_all_info_docstring},
    {"return_version_info", binary_c_return_version_info, METH_VARARGS, return_version_info_docstring},

    {"return_store", binary_c_return_store, METH_VARARGS, return_store_docstring},

    {NULL, NULL, 0, NULL}
};

#if PY_MAJOR_VERSION >= 3

/* Python 3+ */
static struct PyModuleDef Py_binary_c_python_api =
    "binary_c_python_api", /* name of module */
    "binary_c_python_api docs",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    module_methods
};

PyMODINIT_FUNC PyInit_binary_c_python_api(void)
    return PyModule_Create(&Py_binary_c_python_api);
}

#else

/*
 * Python pre-V3
 *
 * NOT TESTED THOROUGHLY!
 */

PyMODINIT_FUNC initbinary_c(void)
{
    PyObject *m = Py_InitModule3("binary_c_python_api", module_methods, module_docstring);
    if(m == NULL)
        return;
}
#endif // Python version check


#ifdef __DEPRECATED
static PyObject* binary_c_create_binary(PyObject *self, PyObject *args)
{

    double var1, var2;
    char * empty_str = "";
    int i;
    const int N = 1;

    /* Parse the input tuple */
    if(!PyArg_ParseTuple(args, "dd", &var1, &var2))
        return NULL;


    /* Binary structures */
    struct libbinary_c_stardata_t *stardata[N];
    struct libbinary_c_store_t *store = NULL;

    /* Allocate memory for binaries */
    for(i=0;i<N;i++){
        stardata[i] = NULL;
        binary_c_new_system(&stardata[i], NULL, NULL, &store, &empty_str, -1);
    }

    /* Return the evolved binary */
    PyObject *ret = Py_BuildValue("");

    return ret;
}


static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args)
{
    /* Binary structures */
    struct libbinary_c_stardata_t *stardata;

    /* Allocate memory for binaries */
    char * empty_str = "";
    stardata = NULL;
    binary_c_new_system(&stardata, NULL, NULL, &store, &empty_str, -1);
    
    /* Return an object containing the stardata */
    PyObject *ret = Py_BuildValue("");
    return ret;
}

static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args)
{
David Hendriks's avatar
David Hendriks committed

    // This function is an very bare example of how a function would look like.

    double var1, var2;

    /* Parse the input tuple */
    if(!PyArg_ParseTuple(args, "dd", &var1, &var2))
    {
        return NULL;
    }
    else
    {
        /* Return the evolved binary */
        PyObject *ret = Py_BuildValue("");
        return ret;
    }
}

    Below are the real funtions:
    binary_c_run_binary
    binary_c_run_binary_custom_logging
    binary_c_run_binary_with_logfile
    binary_c_run_population

    binary_c_return_arglines
    binary_c_return_help_info
    binary_c_return_help_all_info
    binary_c_return_version_info
/* ============================================================================== */
/* Wrappers to functions that evolve binary systems.                              */
/* ============================================================================== */

static PyObject* binary_c_run_binary(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    
    if(!PyArg_ParseTuple(args, "s", &argstring))
    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = run_binary(argstring,
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);
    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
David Hendriks's avatar
David Hendriks committed

static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    if(!PyArg_ParseTuple(args, "sl", &argstring, &func_memaddr))
David Hendriks's avatar
David Hendriks committed
    {
        return NULL;
    }

    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = run_binary_custom_logging(argstring,
                                      func_memaddr, 
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);
    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);
    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
David Hendriks's avatar
David Hendriks committed
}

static PyObject* binary_c_run_binary_with_logfile(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    
    if(!PyArg_ParseTuple(args, "s", &argstring))
    {
        return NULL;
    }

    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = run_binary_with_logfile(argstring,
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);
    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
}
static PyObject* binary_c_run_population(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    long int custom_logging_func_memaddr;
    long int store_memaddr;

    if(!PyArg_ParseTuple(args, "sll", &argstring, &custom_logging_func_memaddr, &store_memaddr))
    {
        return NULL;

    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = run_population(argstring,
                                      custom_logging_func_memaddr, 
                                      store_memaddr,
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
static PyObject* binary_c_run_system(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    long int custom_logging_func_memaddr;
    long int store_memaddr;

    if(!PyArg_ParseTuple(args, "sll", &argstring, &custom_logging_func_memaddr, &store_memaddr))
    {
        return NULL;
    }

    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = run_system(argstring,
                                      custom_logging_func_memaddr, 
                                      store_memaddr,
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
}



/* ============================================================================== */
/* Wrappers to functions that call other API functionality like help and arglines */
/* ============================================================================== */
David Hendriks's avatar
David Hendriks committed
static PyObject* binary_c_return_arglines(PyObject *self, PyObject *args)
{
    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = return_arglines(&buffer,
                                          &error_buffer,
                                          &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_string;
}

static PyObject* binary_c_return_help_info(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    
    if(!PyArg_ParseTuple(args, "s", &argstring))
    {
        return NULL;
    }
    else
    {
        char * buffer;
        char * error_buffer;
        size_t nbytes;
        int out MAYBE_UNUSED = return_help_info(argstring,
                                              &buffer,
                                              &error_buffer,
                                              &nbytes);

        /* copy the buffer to a python string */
        PyObject * return_string = Py_BuildValue("s", buffer);
        PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

        if(error_buffer != NULL && strlen(error_buffer)>0)
        {
            fprintf(stderr,
                    "Error in binary_c run : %s\n",
                    error_buffer);
        }
        
        Safe_free(buffer);
        Safe_free(error_buffer);

        return return_string;
    }
}

static PyObject* binary_c_return_help_all_info(PyObject *self, PyObject *args)
{
    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = return_help_all_info(&buffer,
                                          &error_buffer,
                                          &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    return return_string;
}

static PyObject* binary_c_return_version_info(PyObject *self, PyObject *args)
{
    char * buffer;
    char * error_buffer;
    size_t nbytes;
    int out MAYBE_UNUSED = return_version_info(&buffer,
                                          &error_buffer,
                                          &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    return return_string;
}

/* ============================================================================== */
/* Wrappers to functions that call other functionality */
/* ============================================================================== */

static PyObject* binary_c_return_store(PyObject *self, PyObject *args)
{
    /* Parse the input tuple */
    char *argstring;
    
    if(!PyArg_ParseTuple(args, "s", &argstring))
    {
        return NULL;
    }

    char * buffer;
    char * error_buffer;
    size_t nbytes;
    long int out MAYBE_UNUSED = return_store(argstring,
                                      &buffer,
                                      &error_buffer,
                                      &nbytes);

    /* copy the buffer to a python string */
    PyObject * return_string = Py_BuildValue("s", buffer);
    PyObject * return_error_string MAYBE_UNUSED = Py_BuildValue("s", error_buffer);

    PyObject * return_store_memaddr = Py_BuildValue("l", out);

    if(error_buffer != NULL && strlen(error_buffer)>0)
    {
        fprintf(stderr,
                "Error in binary_c run : %s\n",
                error_buffer);
    }
    
    Safe_free(buffer);
    Safe_free(error_buffer);

    /* 
     * TODO
     * return the return_error_string as well!
     */
    return return_store_memaddr;