libfyaml backend

currently it simply converts the whole file content to flow mode.
The nice thing is: It can convert EVERYTHING to flow mode. libfyaml is
the only library that passes the whole YAML test suite
This commit is contained in:
Martin Diehl 2022-04-12 22:14:04 +02:00
parent affa7baa22
commit 723252ef15
5 changed files with 146 additions and 50 deletions

View File

@ -115,8 +115,14 @@ if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")
set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} ${DEBUG_FLAGS}") set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} ${DEBUG_FLAGS}")
endif() endif()
set(CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${PETSC_INCLUDES} ${BUILDCMD_POST}") set(CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${PETSC_INCLUDES} ${BUILDCMD_POST}")
set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L${PETSC_LIBRARY_DIRS} -lpetsc ${PETSC_EXTERNAL_LIB} -lz ${BUILDCMD_POST}")
set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -L${PETSC_LIBRARY_DIRS} -lpetsc ${PETSC_EXTERNAL_LIB} -lz")
if(fYAML_FOUND STREQUAL "1")
set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} -L${fYAML_LIBRARY_DIRS} -l${fYAML_LIBRARIES}")
add_definitions(-DFYAML)
endif()
set(CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} ${BUILDCMD_POST}")
message("Fortran Compiler Flags:\n${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}\n") message("Fortran Compiler Flags:\n${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}\n")
message("C Compiler Flags:\n${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}\n") message("C Compiler Flags:\n${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}\n")

View File

@ -9,6 +9,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "zlib.h" #include "zlib.h"
#ifdef FYAML
#include <libfyaml.h>
#endif
#define PATHLEN 4096 #define PATHLEN 4096
#define STRLEN 256 #define STRLEN 256
@ -80,3 +84,26 @@ void inflate_c(const uLong *s_deflated, const uLong *s_inflated, const Byte defl
} }
} }
} }
#ifdef FYAML
void to_flow_c(char **flow, int* length_flow, const char *mixed){
struct fy_document *fyd = NULL;
enum fy_emitter_cfg_flags emit_flags = FYECF_MODE_FLOW_ONELINE | FYECF_STRIP_LABELS | FYECF_STRIP_DOC;
fyd = fy_document_build_from_string(NULL, mixed, -1);
if (!fyd) {
*length_flow = -1;
return;
}
int err = fy_document_resolve(fyd);
if (err) {
*length_flow = -1;
return;
}
*flow = fy_emit_document_to_string(fyd,emit_flags);
*length_flow = strlen(*flow);
fy_document_destroy(fyd);
}
#endif

View File

@ -483,7 +483,9 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
case (701) case (701)
msg = 'Incorrect indent/Null value not allowed' msg = 'Incorrect indent/Null value not allowed'
case (702) case (702)
msg = 'Invalid use of flow yaml' msg = 'Invalid use of flow YAML'
case (703)
msg = 'Invalid YAML'
case (704) case (704)
msg = 'Space expected after a colon for <key>: <value> pair' msg = 'Space expected after a colon for <key>: <value> pair'
case (705) case (705)

View File

@ -8,6 +8,9 @@ module YAML_parse
use prec use prec
use IO use IO
use YAML_types use YAML_types
#ifdef FYAML
use system_routines
#endif
implicit none implicit none
private private
@ -16,14 +19,34 @@ module YAML_parse
YAML_parse_init, & YAML_parse_init, &
YAML_parse_str YAML_parse_str
#ifdef FYAML
interface
subroutine to_flow_C(flow,length_flow,mixed) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR, C_PTR
type(C_PTR), intent(out) :: flow
integer(C_INT), intent(out) :: length_flow
character(kind=C_CHAR), dimension(*), intent(in) :: mixed
end subroutine to_flow_C
end interface
#endif
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Do sanity checks. !> @brief Do sanity checks.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine YAML_parse_init subroutine YAML_parse_init()
call selfTest print'(/,1x,a)', '<<<+- YAML_parse init -+>>>'
#ifdef FYAML
print'(/,1x,a)', 'libfyaml powered'
#else
call selfTest()
#endif
end subroutine YAML_parse_init end subroutine YAML_parse_init
@ -155,8 +178,37 @@ logical function quotedString(line)
end function quotedString end function quotedString
#ifdef FYAML
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! @brief Returns Indentation. ! @brief Convert all block style YAML parts to flow style.
!--------------------------------------------------------------------------------------------------
function to_flow(mixed) result(flow)
character(len=*), intent(in) :: mixed
character(:,C_CHAR), allocatable :: flow
type(C_PTR) :: str_ptr
integer(C_INT) :: strlen
call to_flow_C(str_ptr,strlen,f_c_string(mixed))
if (strlen < 1) call IO_error(703,ext_msg='libyfaml')
allocate(character(len=strlen,kind=c_char) :: flow)
block
character(len=strlen,kind=c_char), pointer :: s
call c_f_pointer(str_ptr,s)
flow = s
end block
call free_C(str_ptr)
end function to_flow
#else
!--------------------------------------------------------------------------------------------------
! @brief Determine Indentation.
! @details It determines the indentation level for a given block/line. ! @details It determines the indentation level for a given block/line.
! In cases for nested lists, an offset is added to determine the indent of the item block (skip ! In cases for nested lists, an offset is added to determine the indent of the item block (skip
! leading dashes) ! leading dashes)
@ -737,7 +789,7 @@ end subroutine
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! @brief convert all block style YAML parts to flow style ! @brief Convert all block style YAML parts to flow style.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function to_flow(blck) function to_flow(blck)
@ -921,5 +973,6 @@ subroutine selfTest
end block basic_mixed end block basic_mixed
end subroutine selfTest end subroutine selfTest
#endif
end module YAML_parse end module YAML_parse

View File

@ -17,59 +17,67 @@ module system_routines
getUserName, & getUserName, &
signalterm_C, & signalterm_C, &
signalusr1_C, & signalusr1_C, &
signalusr2_C signalusr2_C, &
f_c_string, &
free_C
interface interface
function setCWD_C(cwd) bind(C) function setCWD_C(cwd) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR
integer(C_INT) :: setCWD_C integer(C_INT) :: setCWD_C
character(kind=C_CHAR), dimension(*), intent(in) :: cwd character(kind=C_CHAR), dimension(*), intent(in) :: cwd
end function setCWD_C end function setCWD_C
subroutine getCWD_C(cwd, stat) bind(C) subroutine getCWD_C(cwd, stat) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR
use prec use prec
character(kind=C_CHAR), dimension(pPathLen+1), intent(out) :: cwd ! NULL-terminated array character(kind=C_CHAR), dimension(pPathLen+1), intent(out) :: cwd ! NULL-terminated array
integer(C_INT), intent(out) :: stat integer(C_INT), intent(out) :: stat
end subroutine getCWD_C end subroutine getCWD_C
subroutine getHostName_C(hostname, stat) bind(C) subroutine getHostName_C(hostname, stat) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR
use prec use prec
character(kind=C_CHAR), dimension(pStringLen+1), intent(out) :: hostname ! NULL-terminated array character(kind=C_CHAR), dimension(pStringLen+1), intent(out) :: hostname ! NULL-terminated array
integer(C_INT), intent(out) :: stat integer(C_INT), intent(out) :: stat
end subroutine getHostName_C end subroutine getHostName_C
subroutine getUserName_C(username, stat) bind(C) subroutine getUserName_C(username, stat) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR use, intrinsic :: ISO_C_Binding, only: C_INT, C_CHAR
use prec use prec
character(kind=C_CHAR), dimension(pStringLen+1), intent(out) :: username ! NULL-terminated array character(kind=C_CHAR), dimension(pStringLen+1), intent(out) :: username ! NULL-terminated array
integer(C_INT), intent(out) :: stat integer(C_INT), intent(out) :: stat
end subroutine getUserName_C end subroutine getUserName_C
subroutine signalterm_C(handler) bind(C) subroutine signalterm_C(handler) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_FUNPTR use, intrinsic :: ISO_C_Binding, only: C_FUNPTR
type(C_FUNPTR), intent(in), value :: handler type(C_FUNPTR), intent(in), value :: handler
end subroutine signalterm_C end subroutine signalterm_C
subroutine signalusr1_C(handler) bind(C) subroutine signalusr1_C(handler) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_FUNPTR use, intrinsic :: ISO_C_Binding, only: C_FUNPTR
type(C_FUNPTR), intent(in), value :: handler type(C_FUNPTR), intent(in), value :: handler
end subroutine signalusr1_C end subroutine signalusr1_C
subroutine signalusr2_C(handler) bind(C) subroutine signalusr2_C(handler) bind(C)
use, intrinsic :: ISO_C_Binding, only: C_FUNPTR use, intrinsic :: ISO_C_Binding, only: C_FUNPTR
type(C_FUNPTR), intent(in), value :: handler
end subroutine signalusr2_C
subroutine free_C(ptr) bind(C,name='free')
import c_ptr
type(c_ptr), value :: ptr
end subroutine free_C
type(C_FUNPTR), intent(in), value :: handler
end subroutine signalusr2_C
end interface end interface