diff --git a/TODO.org b/TODO.org index 42fa47440bb5ce7f8771a5eb0410219de43e358c..5c13dd893145e2c3d51fc5897f8556a476633c60 100644 --- a/TODO.org +++ b/TODO.org @@ -124,7 +124,8 @@ sub autogen_C_logging_code *** TODO Make function in python that puts code into c function -*** TODO Make function in python that generates c-function from a list of arguments +*** DONE Make function in python that generates c-function from a list of arguments + CLOSED: [2019-10-29 Tue 23:52] *** TODO Resolve current issue malloc ➜ binary_c-python git:(master) ✗ python python_API_test.py Traceback (most recent call last): diff --git a/binary_c_python.h b/binary_c_python.h index d4381f6885e5596556dc5bda3291af5e3540a7d7..0122aa7885538b422f0ffe8c29420b33c94c16f6 100644 --- a/binary_c_python.h +++ b/binary_c_python.h @@ -17,8 +17,6 @@ int run_binary_with_log (char * argstring, char ** outstring, int * nbytes); - - int return_arglines(char ** buffer, int * nbytes); diff --git a/binaryc_python_utils/logging_functions.py b/binaryc_python_utils/logging_functions.py index 1d4aa71c3b6fbca3ca2222ad77ccae3c0215edac..c0c3645e973c1bcb7d69009a9174567abc2b8c28 100644 --- a/binaryc_python_utils/logging_functions.py +++ b/binaryc_python_utils/logging_functions.py @@ -1,4 +1,11 @@ +import textwrap # Functions for the automatic logging of stuff +# https://stackoverflow.com/questions/41954269/create-c-function-pointers-structure-in-python +# https://stackabuse.com/enhancing-python-with-custom-c-extensions/ Read +# https://stackoverflow.com/questions/49941617/runtime-generation-and-compilation-of-cython-functions +# https://realpython.com/cpython-source-code-guide/ +# https://docs.python.org/3.6/c-api/index.html + # Perl code for autogeneration # sub autogen_C_logging_code @@ -69,19 +76,15 @@ def autogen_C_logging_code(logging_dict): # Check if the input is of the correct form if not type(logging_dict)==dict: print("Error: please use a dictionary as input") + return None - # code = '' - # Loop over dict keys for key in logging_dict: - print('{}'.format(key)) - logging_dict_entry = logging_dict[key] # Check if item is of correct type: if type(logging_dict_entry)==list: - print(logging_dict_entry) # Construct print statement code += 'PRINTF("{}'.format(key) @@ -92,14 +95,119 @@ def autogen_C_logging_code(logging_dict): # Add format keys for param in logging_dict_entry: code += ',((double)stardata->{})'.format(param) - code += ');' + code += ');\n' else: print('Error: please use a list for the list of parameters that you want to have logged') + code = code.strip() + # print("MADE AUTO CODE\n\n{}\n\n{}\n\n{}\n".format('*'*60, repr(code), '*'*60)) + return code - print(repr(code)) -autogen_C_logging_code({'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 'my_sss2': ['model.time', 'star[1].mass']}) +autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + 'my_sss2': ['model.time', 'star[1].mass'] + } +) +#################################################################################### + +# sub binary_c_log_code +# { +# my ($code) = @_; +# return " +# #pragma push_macro(\"MAX\") +# #pragma push_macro(\"MIN\") +# #undef MAX +# #undef MIN +# #include \"binary_c.h\" + +# void custom_output_function(SV * x); +# SV * custom_output_function_pointer(void); + +# SV * custom_output_function_pointer() +# { +# /* +# * use PTR2UV to convert the function pointer +# * &custom_output_function to an unsigned int, +# * which is then converted to a Perl SV +# */ +# return (SV*)newSVuv(PTR2UV(&custom_output_function)); +# } + +# void custom_output_function(SV * x) +# { +# struct stardata_t * stardata = (struct stardata_t *)x; +# $code; +# } +# #undef MAX +# #undef MIN +# #pragma pop_macro(\"MIN\") +# #pragma pop_macro(\"MAX\") +# "; +# } + +# And then to use it via +# $population->set( +# C_logging_code => ' +# PRINTF("MY_STELLAR_DATA %g %g %g %g\n", +# stardata->model.time, +# stardata->star[0].mass, +# stardata->model.probability, +# stardata->model.dt); +# ' +# ); + + + +def binary_c_log_code(code): + """ + Function to construct the code to construct the custom logging function + """ + custom_logging_function_string = """ + #pragma push_macro(\"MAX\") + #pragma push_macro(\"MIN\") + #undef MAX + #undef MIN + #include \"binary_c.h\" + + void custom_output_function(SV * x); + SV * custom_output_function_pointer(void); + + SV * custom_output_function_pointer() + {{ + /* + * use PTR2UV to convert the function pointer + * &custom_output_function to an unsigned int, + * which is then converted to a Perl SV + */ + return (SV*)newSVuv(PTR2UV(custom_output_function)); + }} + + void custom_output_function(SV * x) + {{ + struct stardata_t * stardata = (struct stardata_t *)x; + {code}; + }} + + #undef MAX + #undef MIN + #pragma pop_macro(\"MIN\") + #pragma pop_macro(\"MAX\") + """.format(code=code) + + print(textwrap.dedent(custom_logging_function_string)) + # return custom_logging_function_string + + +code = autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + 'my_sss2': ['model.time', 'star[1].mass'] + } +) + +binary_c_log_code(code)