diff --git a/srcgen/Makefile b/srcgen/Makefile index f49cfa2..737022d 100644 --- a/srcgen/Makefile +++ b/srcgen/Makefile @@ -12,7 +12,7 @@ srcgen: generator srcgenf: generatorf ./generatorf -generatorf: utilities.o fortran_code.o c_code.o py_code.o fmain.o +generatorf: utilities.o fortran_code.o c_code.o py_code.o cpy_code.o fmain.o $(FC) $^ -o generatorf generator: main.o diff --git a/srcgen/cpy_code.f90 b/srcgen/cpy_code.f90 new file mode 100644 index 0000000..8db4d48 --- /dev/null +++ b/srcgen/cpy_code.f90 @@ -0,0 +1,42 @@ +module cpy_code + !! Functions for writing the cpython code + use iso_fortran_env + implicit none + +contains + +subroutine write_cpython_extension_declaration(fcode) + !! Generate the cpython module declaration. + implicit none + integer(int32), intent(in) :: fcode + !! File unit of the Python module. + + write(fcode, "(A)") "#define PY_SSIZE_T_CLEAN" + write(fcode, "(A)") "#include " + write(fcode, "(A)") '#include "codata.h"' + write(fcode, "(A)") "" + write(fcode, "(A)") 'PyDoc_STRVAR(module_docstring, "C extension for codata constants.");' + write(fcode, "(A)") "" + write(fcode, "(A)") "static PyMethodDef myMethods[] = {{ NULL, NULL, 0, NULL }};" + write(fcode, "(A)") "" + write(fcode, "(A)") 'static struct PyModuleDef codata = {PyModuleDef_HEAD_INIT, "codata", module_docstring, -1, myMethods};' + write(fcode, "(A)") "" + write(fcode, "(A)") "PyMODINIT_FUNC PyInit_codata(void){" + write(fcode, "(4X, A)") "PyObject *m;" + write(fcode, "(4X, A)") "PyObject *d;" + write(fcode, "(4X, A)") "PyObject *v;" + write(fcode, "(4X, A)") "m = PyModule_Create(&codata);" + write(fcode, "(4X, A)") "d = PyModule_GetDict(m);" + write(fcode, "(A)") "" +end subroutine + +subroutine write_cpython_extension_end(fcode) + !! Generate the cpython module end. + implicit none + integer(int32), intent(in) :: fcode + !! File unit of the Python module. + write(fcode, "(4X, A)") "return m;" + write(fcode, "(A)") "}" +end subroutine + +end module \ No newline at end of file diff --git a/srcgen/fmain.f90 b/srcgen/fmain.f90 index 90c5ef0..49d5d23 100644 --- a/srcgen/fmain.f90 +++ b/srcgen/fmain.f90 @@ -4,6 +4,7 @@ program generator use fortran_code use c_code use py_code + use cpy_code implicit none type(codata_file_props) :: props @@ -11,6 +12,7 @@ program generator integer(int32) :: ffortran integer(int32) :: fcheader integer(int32) :: fpython + integer(int32) :: fcpython integer(int32) :: unit logical :: exist @@ -53,6 +55,15 @@ program generator close(unit=unit, status="delete") endif open(file="../include/codata.txt", newunit=fpython, status="new", action="write") + + ! CPYTHON + print *, "Opening cpython..." + inquire(file="../pywrapper/pycodata/cpycodata.c", exist=exist) + if(exist)then + open(file="../pywrapper/pycodata/cpycodata.c", newunit=unit, status="old") + close(unit=unit, status="delete") + endif + open(file="../pywrapper/pycodata/cpycodata.c", newunit=fcpython, status="new", action="write") print *, "Writing fortran module declaration..." @@ -61,13 +72,16 @@ program generator call write_c_header_doc(fcheader) print *, "Writing Python code as txt doc..." call write_python_module_doc(fpython) + print *, "Writing Cpython code..." + call write_cpython_extension_declaration(fcpython); print *, "Writing all constants..." - call write_all_constants(fcodata, ffortran, fcheader, fpython, props) + call write_all_constants(fcodata, ffortran, fcheader, fpython, fcpython, props) print *, "Writing fortran module end..." call write_fortran_module_end(ffortran) - + print *, "Writing cpython end..." + call write_cpython_extension_end(fcpython); print *, "Closing codata file..." close(fcodata) diff --git a/srcgen/py_code.f90 b/srcgen/py_code.f90 index 0c15624..3f68fb9 100644 --- a/srcgen/py_code.f90 +++ b/srcgen/py_code.f90 @@ -7,7 +7,7 @@ module py_code subroutine write_python_module_doc(fcode) - !! brief Generate the python module declaration. + !! Generate the python module declaration. implicit none ! Arguments integer(int32), intent(in) :: fcode diff --git a/srcgen/utilities.f90 b/srcgen/utilities.f90 index 81578dd..7b088eb 100644 --- a/srcgen/utilities.f90 +++ b/srcgen/utilities.f90 @@ -375,7 +375,7 @@ subroutine convert_value_to_c(value) end do end subroutine -subroutine write_all_constants(fcodata, ffortran, fcheader, fpython, props) +subroutine write_all_constants(fcodata, ffortran, fcheader, fpython, fcpython, props) !! Generate all constants in the Fortran module. implicit none ! Arguments @@ -387,6 +387,7 @@ subroutine write_all_constants(fcodata, ffortran, fcheader, fpython, props) !! File unit of the C header. integer(int32), intent(in) :: fpython !! fpython File unit of the python module. + integer(int32), intent(in) :: fcpython !! fcpython File unit of the cpython module. type(codata_file_props), intent(in) :: props !! props Properties of the codata file. @@ -410,6 +411,11 @@ subroutine write_all_constants(fcodata, ffortran, fcheader, fpython, props) write(fcheader, "(A,/)") "ADD_IMPORT extern const int YEAR;" ! python write(fpython, "(A,/)") 'YEAR = '//props%year + ! cpython + write(fcpython, "(4X, A)") "v = PyLong_FromLong(YEAR);" + write(fcpython, "(4X, A)") 'PyDict_SetItemString(d, "YEAR", v);' + write(fcpython, "(4X, A)") "Py_INCREF(v);" + write(fcpython, "(A)") "" do i=1, props%n call clean_line(line) @@ -442,6 +448,16 @@ subroutine write_all_constants(fcodata, ffortran, fcheader, fpython, props) write(fpython, "(A)") trim(name)//"="//trim(value)//' # '//trim(unit) write(fpython, "(A)") "U_"//trim(name)//"="//trim(uncertainty)//" # "//trim(unit) write(fpython, "(A)") "" + + ! CPython code + write(fcpython, "(4X, A)") "v = PyFloat_FromDouble("//trim(name)//");" + write(fcpython, "(4X, A)") 'PyDict_SetItemString(d, "'//trim(name)//'", v);' + write(fcpython, "(4X, A)") "Py_INCREF(v);" + write(fcpython, "(4X, A)") "v = PyFloat_FromDouble(U_"//trim(name)//");" + write(fcpython, "(4X, A)") 'PyDict_SetItemString(d, "U_'//trim(name)//'", v);' + write(fcpython, "(4X, A)") "Py_INCREF(v);" + write(fcpython, "(A)") "" + end if