diff --git a/binary_c_python.c b/binary_c_python.c index 552ad2225029b14ab13f063f602ba364d3e1b28a..00f4abd5efb1d98f7411855d4c1c7a80258244ee 100644 --- a/binary_c_python.c +++ b/binary_c_python.c @@ -7,7 +7,7 @@ * Remember: variables must be passed by references * (i.e. as pointers). * - * See apitest.py for an expmple of how to use these functions. + * 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 @@ -22,7 +22,7 @@ */ /************************************************************/ - +// Docstrings static char module_docstring[] MAYBE_UNUSED = "This module is a python wrapper around binary_c"; #ifdef __DEPRECATED @@ -31,34 +31,50 @@ static char create_binary_docstring[] = #endif static char run_binary_docstring[] = "Run one binary using binary_c"; +static char run_binary_with_logdocstring[] = + "Run one binary using binary_c and allow the logfile to be written. Do not use for populations!"; +static char run_binary_custom_loggingdocstring[] = + "TODO"; static char new_binary_system_docstring[] = "Return an object containing a binary, ready for evolution"; static char function_prototype_docstring[] = "The prototype for a binary_c python function"; - +static char return_arglines_docstring[] = + "Return the default args for a binary_c system"; static struct libbinary_c_store_t *store = NULL; +// Initialize pyobjects #ifdef __DEPRECATED static PyObject* binary_c_create_binary(PyObject *self, PyObject *args); #endif static PyObject* binary_c_run_binary(PyObject *self, PyObject *args); +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_function_prototype(PyObject *self, PyObject *args); static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args); +static PyObject* binary_c_return_arglines(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 - {"create_binary", binary_c_create_binary, METH_VARARGS, create_binary_docstring}, + {"create_binary", + binary_c_create_binary, + METH_VARARGS, + create_binary_docstring + }, #endif {"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_logdocstring}, + {"run_binary_custom_logging", binary_c_run_binary_custom_logging, METH_VARARGS, run_binary_custom_loggingdocstring}, {"function_prototype", binary_c_function_prototype, METH_VARARGS, function_prototype_docstring}, {"new_system", binary_c_new_binary_system, METH_VARARGS, new_binary_system_docstring}, + {"return_arglines", binary_c_return_arglines, METH_VARARGS, return_arglines_docstring}, {NULL, NULL, 0, NULL} }; @@ -66,7 +82,6 @@ static PyMethodDef module_methods[] = { #if PY_MAJOR_VERSION >= 3 /* Python 3+ */ - static struct PyModuleDef Py_binary_c = { PyModuleDef_HEAD_INIT, @@ -89,7 +104,6 @@ PyMODINIT_FUNC PyInit_binary_c(void) * NOT TESTED THOROUGHLY! */ - PyMODINIT_FUNC initbinary_c(void) { PyObject *m = Py_InitModule3("binary_c", module_methods, module_docstring); @@ -145,9 +159,11 @@ static PyObject* binary_c_new_binary_system(PyObject *self, PyObject *args) return ret; } - static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args) { + + // This function is an very bare example of how a function would look like. + double var1, var2; /* Parse the input tuple */ @@ -163,7 +179,6 @@ static PyObject* binary_c_function_prototype(PyObject *self, PyObject *args) } } - static PyObject* binary_c_run_binary(PyObject *self, PyObject *args) { /* Parse the input tuple */ @@ -203,3 +218,116 @@ static PyObject* binary_c_run_binary(PyObject *self, PyObject *args) return return_string; } } + +static PyObject* binary_c_run_binary_custom_logging(PyObject *self, PyObject *args) +{ + /* Parse the input tuple */ + char *argstring; + long int str_1; + + if(!PyArg_ParseTuple(args, "sl", &argstring, &str_1)) + { + return NULL; + } + else + { + char * buffer; + char * error_buffer; + size_t nbytes; + int out MAYBE_UNUSED = run_binary_custom_logging(argstring, + str_1, + &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_binary_with_logfile(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 = 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_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; +} \ No newline at end of file diff --git a/binary_c_python.h b/binary_c_python.h index 914b1d4920d2b11de54d11099a6413447dd7534e..152c6e51428f473cddf2f61f84c9128d5f00bcad 100644 --- a/binary_c_python.h +++ b/binary_c_python.h @@ -14,6 +14,21 @@ int run_binary (char * argstring, char ** const errorstring, size_t * const nbytes); +int run_binary_with_logfile (char * argstring, + char ** const outstring, + char ** const errorstring, + size_t * const nbytes); + +int run_binary_custom_logging(char * argstring, + long int str_1, + char ** const buffer, + char ** const error_buffer, + size_t * const nbytes); + +int return_arglines(char ** const outstring, + char ** const errorstring, + size_t * const nbytes); + /* C macros */ #define BINARY_C_APITEST_VERSION 0.1 #define APIprint(...) APIprintf(__VA_ARGS__); diff --git a/binary_c_python_api.c b/binary_c_python_api.c index 0b4eff2e2ace0ee4f47c3754abc30da8b0e352b4..04a0a9a8a442faa2f82eb5fbd47de8cb49c304d1 100644 --- a/binary_c_python_api.c +++ b/binary_c_python_api.c @@ -35,49 +35,69 @@ * I have tested this with gcc 4.7.2 (Ubuntu 12.10) only. */ - // #define _CAPTURE #ifdef _CAPTURE static void show_stdout(void); static void capture_stdout(void); #endif - /* global variables */ int out_pipe[2]; int stdoutwas; -int main(int argc, - char * argv[]) +int run_binary(char * argstring, + char ** const buffer, + char ** const error_buffer, + size_t * const nbytes) { - char * argstring = Malloc(sizeof(char) * (size_t)STRING_LENGTH); - snprintf(argstring, - STRING_LENGTH, - "binary_c M_1 %g M_2 %g separation %g orbital_period %g metallicity %g max_evolution_time %g\n", - 20.0, - 15.0, - 0.0, - 3.0, - 0.02, - 15000.0); - - char * buffer; - char * error_buffer; - size_t nbytes; - int out = run_binary(argstring, - &buffer, - &error_buffer, - &nbytes); + /* memory for N binary systems */ + struct libbinary_c_stardata_t *stardata; + struct libbinary_c_store_t * store = NULL; + + /* make new stardata */ + stardata = NULL; + binary_c_new_system(&stardata, + NULL, + NULL, + &store, + &argstring, + -1); - printf("output (binary_c returned %d)\n%s\n",out,buffer); + /* disable logging */ + snprintf(stardata->preferences->log_filename, + STRING_LENGTH-1, + "%s", + "/dev/null"); + snprintf(stardata->preferences->api_log_filename_prefix, + STRING_LENGTH-1, + "%s", + "/dev/null"); + /* output to strings */ + stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE; + stardata->preferences->batchmode = BATCHMODE_LIBRARY; - free(buffer); + /* do binary evolution */ + binary_c_evolve_for_dt(stardata, + stardata->model.max_evolution_time); + + /* get buffer pointer */ + binary_c_buffer_info(stardata,buffer,nbytes); + + /* get error buffer pointer */ + binary_c_error_buffer(stardata,error_buffer); - return out; + /* set raw_buffer_size = -1 to prevent it being freed */ + stardata->tmpstore->raw_buffer_size = -1; + + /* free stardata (except the buffer) */ + binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE); + binary_c_free_store_contents(store); + + return 0; } - -int run_binary(char * argstring, +int run_binary_custom_logging(char * argstring, + long int str_1, char ** const buffer, char ** const error_buffer, size_t * const nbytes) @@ -94,7 +114,6 @@ int run_binary(char * argstring, &store, &argstring, -1); - printf("have new stardata %p\n",stardata);fflush(NULL); /* disable logging */ snprintf(stardata->preferences->log_filename, @@ -108,6 +127,7 @@ int run_binary(char * argstring, /* output to strings */ stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE; stardata->preferences->batchmode = BATCHMODE_LIBRARY; + stardata->preferences->custom_output_function = str_1; /* do binary evolution */ binary_c_evolve_for_dt(stardata, @@ -128,3 +148,95 @@ int run_binary(char * argstring, return 0; } + +int return_arglines(char ** const buffer, + char ** const error_buffer, + size_t * const nbytes) +{ + /* memory for N binary systems */ + struct libbinary_c_stardata_t *stardata; + struct libbinary_c_store_t * store = NULL; + + /* make new stardata */ + stardata = NULL; + char * empty_str = ""; + binary_c_new_system(&stardata, + NULL, + NULL, + &store, + &empty_str, + -1); + + /* disable logging */ + snprintf(stardata->preferences->log_filename, + STRING_LENGTH-1, + "%s", + "/dev/null"); + snprintf(stardata->preferences->api_log_filename_prefix, + STRING_LENGTH-1, + "%s", + "/dev/null"); + + /* output to strings */ + stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE; + stardata->preferences->batchmode = BATCHMODE_LIBRARY; + + /* List available arguments */ + binary_c_list_args(stardata); + + /* get buffer pointer */ + binary_c_buffer_info(stardata,buffer,nbytes); + + /* get error buffer pointer */ + binary_c_error_buffer(stardata,error_buffer); + + /* set raw_buffer_size = -1 to prevent it being freed */ + stardata->tmpstore->raw_buffer_size = -1; + + /* free stardata (except the buffer) */ + binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE); + binary_c_free_store_contents(store); + + return 0; +} + +int run_binary_with_logfile(char * argstring, + char ** const buffer, + char ** const error_buffer, + size_t * const nbytes) +{ + /* memory for N binary systems */ + struct libbinary_c_stardata_t *stardata; + struct libbinary_c_store_t * store = NULL; + + /* make new stardata */ + stardata = NULL; + binary_c_new_system(&stardata, + NULL, + NULL, + &store, + &argstring, + -1); + + /* output to strings */ + stardata->preferences->internal_buffering = INTERNAL_BUFFERING_STORE; + stardata->preferences->batchmode = BATCHMODE_LIBRARY; + + /* do binary evolution */ + binary_c_evolve_for_dt(stardata, + stardata->model.max_evolution_time); + + /* get buffer pointer */ + binary_c_buffer_info(stardata,buffer,nbytes); + + /* get error buffer pointer */ + binary_c_error_buffer(stardata,error_buffer); + + /* set raw_buffer_size = -1 to prevent it being freed */ + stardata->tmpstore->raw_buffer_size = -1; + + /* free stardata (except the buffer) */ + binary_c_free_memory(&stardata,TRUE,TRUE,FALSE,FALSE); + binary_c_free_store_contents(store); + return 0; +} \ No newline at end of file