From 50bbcde1f31bb08d722b57d25bc4e844e0e5a09a Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Thu, 7 Nov 2019 16:43:24 +0000
Subject: [PATCH] made most code to compile the shared library for binaryc

---
 binaryc/__pycache__/functions.cpython-36.pyc | Bin 0 -> 3263 bytes
 binaryc/custom_logging.c                     |  20 ++
 binaryc/functions.py                         | 238 +++++++++++++++++++
 binaryc/main.py                              |  35 +++
 binaryc/readme.md                            |   2 +
 5 files changed, 295 insertions(+)
 create mode 100644 binaryc/__pycache__/functions.cpython-36.pyc
 create mode 100644 binaryc/custom_logging.c
 create mode 100644 binaryc/functions.py
 create mode 100644 binaryc/main.py
 create mode 100644 binaryc/readme.md

diff --git a/binaryc/__pycache__/functions.cpython-36.pyc b/binaryc/__pycache__/functions.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d94edfad50de7db8a96e18cb3cb9c54647929fad
GIT binary patch
literal 3263
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

literal 0
HcmV?d00001

diff --git a/binaryc/custom_logging.c b/binaryc/custom_logging.c
new file mode 100644
index 0000000..22c19e9
--- /dev/null
+++ b/binaryc/custom_logging.c
@@ -0,0 +1,20 @@
+#pragma push_macro("MAX")
+#pragma push_macro("MIN")
+#undef MAX
+#undef MIN
+#include "binary_c.h"
+
+void custom_output_function(struct stardata_t * stardata);
+void custom_output_function(struct stardata_t * stardata)
+{
+    // struct stardata_t * stardata = (struct stardata_t *)x;
+    PRINTF("MY_STELLAR_DATA %g %g
+",((double)stardata->model.time),((double)stardata->star[0].mass));
+PRINTF("my_sss2 %g %g
+",((double)stardata->model.time),((double)stardata->star[1].mass));;
+}
+
+#undef MAX 
+#undef MIN
+#pragma pop_macro("MIN")
+#pragma pop_macro("MAX")    
\ No newline at end of file
diff --git a/binaryc/functions.py b/binaryc/functions.py
new file mode 100644
index 0000000..b9d635e
--- /dev/null
+++ b/binaryc/functions.py
@@ -0,0 +1,238 @@
+import os
+import textwrap
+import subprocess
+import socket
+
+# Functions for the automatic logging of stuff
+
+def autogen_C_logging_code(logging_dict):
+    # See example_perl.pm autologging
+    """
+    Function that autogenerates PRINTF statements for binaryc
+
+    Input:
+        dictionary where the key is the header of that logging line and items which are lists of parameters that will be put in that logging line
+
+        example: {'MY_STELLAR_DATA': 
+        [
+            'model.time',
+            'star[0].mass',
+            'model.probability',
+            'model.dt'
+        ']}
+    """
+
+    # 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:
+        logging_dict_entry = logging_dict[key]
+
+        # Check if item is of correct type:
+        if type(logging_dict_entry)==list:
+
+            # Construct print statement
+            code += 'PRINTF("{}'.format(key)
+            code += ' {}'.format('%g '*len(logging_dict_entry))
+            code = code.strip()
+            code += '\n"'
+
+            # Add format keys
+            for param in logging_dict_entry:
+                code += ',((double)stardata->{})'.format(param)
+            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
+
+####################################################################################
+def binary_c_log_code(code):
+    """
+    Function to construct the code to construct the custom logging function
+    # see example_perl.pm binary_c_log_code in perl
+    """
+    custom_logging_function_string = """\
+#pragma push_macro(\"MAX\")
+#pragma push_macro(\"MIN\")
+#undef MAX
+#undef MIN
+#include \"binary_c.h\"
+
+void custom_output_function(struct stardata_t * stardata);
+void custom_output_function(struct stardata_t * stardata)
+{{
+    // struct stardata_t * stardata = (struct stardata_t *)x;
+    {};
+}}
+
+#undef MAX 
+#undef MIN
+#pragma pop_macro(\"MIN\")
+#pragma pop_macro(\"MAX\")\
+    """.format(code)
+     
+    # print(repr(textwrap.dedent(custom_logging_function_string)))
+    return textwrap.dedent(custom_logging_function_string)
+
+def binary_c_write_log_code(code, filename):
+    """
+    Function to write the generated logging code to a file
+    """
+
+    cwd = os.getcwd()
+
+    filePath = os.path.join(cwd, filename)
+    if os.path.exists(filePath):
+        try:
+            os.remove(filePath)
+        except:
+            print("Error while deleting file {}".format(filePath))
+
+    with open(filePath, 'w') as f:
+        f.write(code)
+
+def from_binary_c_config(config_file, flag):
+    """
+    Function to run the binaryc_config command with flags
+    """
+
+    res = subprocess.check_output('{config_file} {flag}'.format(config_file=config_file, flag=flag),
+        shell=True, stderr=subprocess.STDOUT)
+
+    # convert and chop off newline
+    res = res.decode('utf').rstrip()
+    return res
+
+def return_compilation_dict():
+    """
+    Function to build the compile command for the shared library
+
+    inspired by binary_c_inline_config command in perl
+
+    TODO: this function still has some cleaning up to do wrt default values for the compile command
+    
+    returns:
+     - string containing the command to build the shared library
+    """    
+
+    # use binary_c-config to get necessary flags
+    BINARY_C_DIR = os.getenv('BINARY_C')
+    if BINARY_C_DIR:
+        BINARY_C_CONFIG = os.path.join(BINARY_C_DIR, 'binary_c-config')
+        BINARY_C_SRC_DIR = os.path.join(BINARY_C_DIR, 'src')
+        # TODO: build in check to see whether the file exists
+    else:
+        raise NameError('Envvar BINARY_C doesnt exist')
+        return None
+
+    # TODO: make more options for the compiling
+    cc = from_binary_c_config(BINARY_C_CONFIG, 'cc')
+
+    # Check for binary_c
+    BINARY_C_EXE = os.path.join(BINARY_C_DIR, 'binary_c')
+    if not os.path.isfile(BINARY_C_EXE):
+        print("We require  binary_c executable; have you built binary_c?")
+        raise NameError('BINARY_C executable doesnt exist')
+
+    # TODO: debug
+    binclibs = from_binary_c_config(BINARY_C_CONFIG, 'libs')
+    libdirs = "{} -L{}".format(from_binary_c_config(BINARY_C_CONFIG, 'libdirs'), BINARY_C_SRC_DIR)
+    bincflags = from_binary_c_config(BINARY_C_CONFIG, 'cflags')
+    bincincdirs = from_binary_c_config(BINARY_C_CONFIG, 'incdirs')
+
+    # combine 
+    binclibs = ' {} {}'.format(libdirs, binclibs)
+
+    # setup defaults:
+    defaults = {
+        'cc': 'gcc', # default compiler
+        'ccflags': bincflags,
+        'ld': 'ld',         # 'ld': $Config{ld}, # default linker
+        'debug': 0,
+        'inc': '{} -I{}'.format(bincincdirs, BINARY_C_SRC_DIR),
+        # inc => ' '.($Config{inc}//' ').' '.$bincincdirs." -I$srcdir ", # include the defaults plus # GSL and binary_c
+        # 'libname': libname, # libname is usually just binary_c corresponding to libbinary_c.so
+        'libs': binclibs,
+    }
+
+    # set values with defaults. TODO: make other input possile.
+    ld = defaults['ld']
+    debug = defaults['debug']
+    inc = defaults['inc'] # = ($ENV{BINARY_GRID2_INC} // $defaults{inc}).' '.($ENV{BINARY_GRID2_EXTRAINC} // '');
+    libs = defaults['libs'] # = ($ENV{BINARY_GRID2_LIBS} // $defaults{libs}).' '.($ENV{BINARY_GRID2_EXTRALIBS}//'');
+    ccflags = defaults['ccflags'] #  = $ENV{BINARY_GRID2_CCFLAGS} // ($defaults{ccflags}) . ($ENV{BINARY_GRID2_EXTRACCFLAGS} // '');
+  
+    # you must define _SEARCH_H to prevent it being loaded twice
+    ccflags += ' -D_SEARCH_H'
+
+    # ensure library paths to the front of the libs:
+    libs_content = libs.split(' ')
+    library_paths = [el for el in libs_content if el.startswith('-L')]
+    non_library_paths = [el for el in libs_content if (not el.startswith('-L') and not el=='')]
+    libs = "{} {}".format(' '.join(library_paths), ' '.join(non_library_paths))
+
+    print("Building shared library for custom logging with (binary_c.h) at {} on {}\n".format(BINARY_C_SRC_DIR, socket.gethostname()))
+    print("With options:\n\tcc = {cc}\n\tccflags = {ccflags}\n\tld = {ld}\n\tlibs = {libs}\n\tinc = {inc}\n\n".format(
+        cc=cc, ccflags=ccflags, ld=ld, libs=libs, inc=inc)
+    )
+
+    return {
+        'cc': cc,
+        'ld': ld,
+        'ccflags': ccflags,
+        'libs': libs,
+        'inc': inc
+        }
+
+# compilation_dict = return_compilation_dict('libcustomlogging')
+def compile_shared_lib(code, sourcefile_name, outfile_name):
+    """
+    Function to write the custom logging code to a file and then compile it.
+    """
+
+    # Write code to file
+    binary_c_write_log_code(code, sourcefile_name)
+
+    # create compilation command
+    compilation_dict = return_compilation_dict()
+
+    command = "{cc} {ccflags} {libs} -o {outfile_name} {sourcefile_name} {inc}".format(
+        cc=compilation_dict['cc'],
+        ccflags=compilation_dict['ccflags'],
+        libs=compilation_dict['libs'],
+        outfile_name=outfile_name,
+        sourcefile_name=sourcefile_name,
+        inc=compilation_dict['inc'])
+
+    # remove extra whitespaces:
+    command = ' '.join(command.split())
+
+    # Execute compilation
+    res = subprocess.check_output('{command}'.format(command=command),
+        shell=True, stderr=subprocess.STDOUT)
+    print(res)    
+
+
+
+    # return command
+
+# generate logging lines
+logging_line = autogen_C_logging_code(
+    {
+        'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 
+        'my_sss2': ['model.time', 'star[1].mass']
+    }
+)
+
+# Generate code around logging lines
+created_code = binary_c_log_code(logging_line)
+
+compile_shared_lib(created_code, sourcefile_name='custom_logging.c', outfile_name='lib_custom_logging.so')
\ No newline at end of file
diff --git a/binaryc/main.py b/binaryc/main.py
new file mode 100644
index 0000000..ccc28fa
--- /dev/null
+++ b/binaryc/main.py
@@ -0,0 +1,35 @@
+from functions import autogen_C_logging_code, binary_c_log_code, binary_c_write_log_code
+
+import textwrap
+
+# generate logging lines
+logging_line = autogen_C_logging_code(
+    {
+        'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], 
+        'my_sss2': ['model.time', 'star[1].mass']
+    }
+)
+
+# Generate code around logging lines
+created_code = binary_c_log_code(logging_line)
+
+binary_c_write_log_code(created_code)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaryc/readme.md b/binaryc/readme.md
new file mode 100644
index 0000000..9c5fd5f
--- /dev/null
+++ b/binaryc/readme.md
@@ -0,0 +1,2 @@
+# function for binaryc to work
+
-- 
GitLab