From c8dcd4b4ae3658877e3c37781b2578ff3ae1e5da Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 22 Sep 2020 23:51:47 +0200 Subject: [PATCH 1/8] 'decide' function should handle everything bug fixed in case of only flow yaml --- src/YAML_parse.f90 | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index d655bc2dc..6cefc5443 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -552,19 +552,17 @@ function to_flow(blck) s_flow, & !< start position in flow offset, & !< counts leading '- ' in nested lists end_line - if(isFlow(blck)) then - to_flow = trim(adjustl(blck)) - else - allocate(character(len=len(blck)*2)::to_flow) - ! move forward here (skip empty lines) and remove '----' if found - s_flow = 1 - s_blck = 1 - offset = 0 - call decide(blck,to_flow,s_blck,s_flow,offset) - to_flow = trim(to_flow(:s_flow-1)) - endif - end_line = index(to_flow,IO_EOL) - if(end_line > 0) to_flow = to_flow(:end_line-1) + + allocate(character(len=len(blck)*2)::to_flow) + ! move forward here (skip empty lines) and remove '----' if found + s_flow = 1 + s_blck = 1 + offset = 0 + call decide(blck,to_flow,s_blck,s_flow,offset) + to_flow = trim(to_flow(:s_flow-1)) + + end_line = index(to_flow,IO_EOL) + if(end_line > 0) to_flow = to_flow(:end_line-1) end function to_flow @@ -636,6 +634,20 @@ subroutine selfTest if (.not. to_flow(block_dict_newline) == flow_dict) error stop 'to_flow' end block basic_dict + only_flow: block + character(len=*), parameter :: flow_dict = & + " {a: [b,c: {d: e}, f: g, e]}"//IO_EOL + character(len=*), parameter :: flow_list = & + " [a,b: c, d,e: {f: g}]"//IO_EOL + character(len=*), parameter :: flow_1 = & + "{a: [b, {c: {d: e}}, {f: g}, e]}" + character(len=*), parameter :: flow_2 = & + "[a, {b: c}, d, {e: {f: g}}]" + + if (.not. to_flow(flow_dict) == flow_1) error stop 'to_flow' + if (.not. to_flow(flow_list) == flow_2) error stop 'to_flow' + end block only_flow + basic_flow: block character(len=*), parameter :: flow_braces = & " source: [{param: 1}, {param: 2}, {param: 3}, {param: 4}]"//IO_EOL From 0de54404ee38f53cca8c6cd20921bf0641f059a8 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Fri, 25 Sep 2020 04:07:40 +0200 Subject: [PATCH 2/8] skip empty lines; yaml file optional start/stop indicator can be added --- src/IO.f90 | 2 ++ src/YAML_parse.f90 | 71 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index f9e708ead..eeb4ec8c6 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -494,6 +494,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) msg = 'Unsupported feature' case (706) msg = 'Access by incorrect node type' + case (707) + msg = 'Abrupt end of file' !------------------------------------------------------------------------------------------------- ! errors related to the grid solver diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index 6cefc5443..ade104cb2 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -227,6 +227,35 @@ logical function isKey(line) end function isKey +!-------------------------------------------------------------------------------------------------- +! @brief skip empty lines +! @details update start position in the block by skipping empty lines if present. +!-------------------------------------------------------------------------------------------------- +subroutine skip_empty_lines(blck,s_blck) + + character(len=*), intent(in) :: blck + integer, intent(inout) :: s_blck + + character(len=:), allocatable :: line + integer :: e_blck + logical :: not_empty + + not_empty = .false. + do while(.not. not_empty) + e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 + line = IO_rmComment(blck(s_blck:e_blck)) + if(len_trim(line) == 0) then + s_blck = e_blck + 2 + not_empty = .false. + else + not_empty = .true. + endif + enddo + + +end subroutine skip_empty_lines + + !-------------------------------------------------------------------------------------------------- ! @brief reads a line of YAML block which is already in flow style ! @details Dicts should be enlcosed within '{}' for it to be consistent with DAMASK YAML parser @@ -363,7 +392,9 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if (len_trim(line) == 0) then + if(trim(line) == '---') then + exit + elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line cycle elseif(indentDepth(line,offset) > indent) then @@ -377,8 +408,10 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) else if(trim(adjustl(line)) == '-') then ! list item in next line s_blck = e_blck + 2 - e_blck = e_blck + index(blck(e_blck+2:),IO_EOL) + call skip_empty_lines(blck,s_blck) + e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) + if(trim(line) == '---') call IO_error(707,ext_msg=line) if(indentDepth(line) < indent .or. indentDepth(line) == indent) & call IO_error(701,ext_msg=line) @@ -447,7 +480,9 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if (len_trim(line) == 0) then + if(trim(line) == '---') then + exit + elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line cycle elseif(indentDepth(line,offset) < indent) then @@ -510,10 +545,12 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) character(len=:), allocatable :: line if(s_blck <= len(blck)) then + call skip_empty_lines(blck,s_blck) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - - if(len_trim(line) == 0) then + if(trim(line) == '---') then + continue ! end parsing at this point but not stop the simulation + elseif(len_trim(line) == 0) then s_blck = e_blck +2 call decide(blck,flow,s_blck,s_flow,offset) elseif (isListItem(line)) then @@ -548,16 +585,24 @@ function to_flow(blck) character(len=:), allocatable :: to_flow character(len=*), intent(in) :: blck !< YAML mixed style + + character(len=:), allocatable :: line integer :: s_blck, & !< start position in blck + e_blck, & !< end position of a line s_flow, & !< start position in flow offset, & !< counts leading '- ' in nested lists end_line - + allocate(character(len=len(blck)*2)::to_flow) - ! move forward here (skip empty lines) and remove '----' if found s_flow = 1 s_blck = 1 offset = 0 + + call skip_empty_lines(blck,s_blck) + e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 + line = IO_rmComment(blck(s_blck:e_blck)) + if(trim(line) == '---') s_blck = e_blck + 2 + call decide(blck,to_flow,s_blck,s_flow,offset) to_flow = trim(to_flow(:s_flow-1)) @@ -662,12 +707,20 @@ subroutine selfTest basic_mixed: block character(len=*), parameter :: block_flow = & + " "//IO_EOL//& + " "//IO_EOL//& + "---"//IO_EOL//& " aa:"//IO_EOL//& " - "//IO_EOL//& - " param_1: [a: b, c, {d: {e: [f: g, h]}}]"//IO_EOL//& + " "//IO_EOL//& + " "//IO_EOL//& + " param_1: [a: b, c, {d: {e: [f: g, h]}}]"//IO_EOL//& " - c: d"//IO_EOL//& " bb:"//IO_EOL//& - " - {param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}"//IO_EOL + " "//IO_EOL//& + " - "//IO_EOL//& + " {param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}"//IO_EOL//& + "---"//IO_EOL character(len=*), parameter :: mixed_flow = & "{aa: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}, {c: d}], bb: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}]}" From 21ff587e1720c53eb7bf441860e05a29f3f7ed8d Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Fri, 25 Sep 2020 04:52:03 +0200 Subject: [PATCH 3/8] better logic --- src/YAML_parse.f90 | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index ade104cb2..218d4688b 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -238,18 +238,14 @@ subroutine skip_empty_lines(blck,s_blck) character(len=:), allocatable :: line integer :: e_blck - logical :: not_empty + logical :: empty - not_empty = .false. - do while(.not. not_empty) + empty = .true. + do while(empty) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(len_trim(line) == 0) then - s_blck = e_blck + 2 - not_empty = .false. - else - not_empty = .true. - endif + empty = len_trim(line) == 0 + if(empty) s_blck = e_blck + 2 enddo From 08f5851c82771fb4365d898c62a104558ddf6d29 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Fri, 25 Sep 2020 10:59:03 +0200 Subject: [PATCH 4/8] take care of empty lines in this slightly new setup --- src/YAML_parse.f90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index 218d4688b..65b9afe3d 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -594,12 +594,13 @@ function to_flow(blck) s_blck = 1 offset = 0 - call skip_empty_lines(blck,s_blck) - e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 - line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') s_blck = e_blck + 2 - - call decide(blck,to_flow,s_blck,s_flow,offset) + if(len_trim(blck) /= 0) then + call skip_empty_lines(blck,s_blck) + e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 + line = IO_rmComment(blck(s_blck:e_blck)) + if(trim(line) == '---') s_blck = e_blck + 2 + call decide(blck,to_flow,s_blck,s_flow,offset) + endif to_flow = trim(to_flow(:s_flow-1)) end_line = index(to_flow,IO_EOL) From a61bf3bb26d4eac3a04002225ac0cda10e832727 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 29 Sep 2020 19:33:30 +0200 Subject: [PATCH 5/8] file endings, file header can be added, take care of EOF --- src/IO.f90 | 5 +++++ src/YAML_parse.f90 | 50 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index eeb4ec8c6..0542e7a62 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -496,6 +496,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) msg = 'Access by incorrect node type' case (707) msg = 'Abrupt end of file' + case (708) + msg = '--- expected after YAML file header' !------------------------------------------------------------------------------------------------- ! errors related to the grid solver @@ -623,6 +625,9 @@ subroutine IO_warning(warning_ID,el,ip,g,ext_msg) msg = 'polar decomposition failed' case (700) msg = 'unknown crystal symmetry' + case (709) + msg = 'read only the first document' + case (850) msg = 'max number of cut back exceeded, terminating' case default diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index 65b9afe3d..bb990fc52 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -236,15 +236,13 @@ subroutine skip_empty_lines(blck,s_blck) character(len=*), intent(in) :: blck integer, intent(inout) :: s_blck - character(len=:), allocatable :: line integer :: e_blck logical :: empty empty = .true. - do while(empty) + do while(empty .and. len_trim(blck(s_blck:)) /= 0) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 - line = IO_rmComment(blck(s_blck:e_blck)) - empty = len_trim(line) == 0 + empty = len_trim(IO_rmComment(blck(s_blck:e_blck))) == 0 if(empty) s_blck = e_blck + 2 enddo @@ -252,6 +250,31 @@ subroutine skip_empty_lines(blck,s_blck) end subroutine skip_empty_lines +!-------------------------------------------------------------------------------------------------- +! @brief skip file header +! @details update start position in the block by skipping file header if present. +!-------------------------------------------------------------------------------------------------- +subroutine skip_file_header(blck,s_blck) + + character(len=*), intent(in) :: blck + integer, intent(inout) :: s_blck + + character(len=:), allocatable :: line + + line = IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2)) + if(adjustl(line(1:5)) == '%YAML') then + s_blck = s_blck + index(blck(s_blck:),IO_EOL) + call skip_empty_lines(blck,s_blck) + if(trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == '---') then + s_blck = s_blck + index(blck(s_blck:),IO_EOL) + else + call IO_error(708,ext_msg = line) + endif + endif + +end subroutine skip_file_header + + !-------------------------------------------------------------------------------------------------- ! @brief reads a line of YAML block which is already in flow style ! @details Dicts should be enlcosed within '{}' for it to be consistent with DAMASK YAML parser @@ -388,7 +411,7 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') then + if(trim(line) == '---' .or. trim(line) == '...') then exit elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line @@ -476,7 +499,7 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') then + if(trim(line) == '---' .or. trim(line) == '...') then exit elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line @@ -544,7 +567,7 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) call skip_empty_lines(blck,s_blck) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') then + if(trim(line) == '---' .or. trim(line) == '...') then continue ! end parsing at this point but not stop the simulation elseif(len_trim(line) == 0) then s_blck = e_blck +2 @@ -584,7 +607,6 @@ function to_flow(blck) character(len=:), allocatable :: line integer :: s_blck, & !< start position in blck - e_blck, & !< end position of a line s_flow, & !< start position in flow offset, & !< counts leading '- ' in nested lists end_line @@ -596,13 +618,14 @@ function to_flow(blck) if(len_trim(blck) /= 0) then call skip_empty_lines(blck,s_blck) - e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 - line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') s_blck = e_blck + 2 + call skip_file_header(blck,s_blck) + line = IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2)) + if(trim(line) == '---') s_blck = s_blck + index(blck(s_blck:),IO_EOL) call decide(blck,to_flow,s_blck,s_flow,offset) endif + line = IO_rmComment(blck(s_blck:s_blck+index(blck(s_blck:),IO_EOL)-2)) + if(trim(line)== '---') call IO_warning(709,ext_msg=line) to_flow = trim(to_flow(:s_flow-1)) - end_line = index(to_flow,IO_EOL) if(end_line > 0) to_flow = to_flow(:end_line-1) @@ -704,6 +727,7 @@ subroutine selfTest basic_mixed: block character(len=*), parameter :: block_flow = & + "%YAML 1.2"//IO_EOL//& " "//IO_EOL//& " "//IO_EOL//& "---"//IO_EOL//& @@ -717,7 +741,7 @@ subroutine selfTest " "//IO_EOL//& " - "//IO_EOL//& " {param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}"//IO_EOL//& - "---"//IO_EOL + "..."//IO_EOL character(len=*), parameter :: mixed_flow = & "{aa: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}, {c: d}], bb: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}]}" From 45b906906d90bfec363f63598c29c4dae0d3ed4e Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 29 Sep 2020 20:07:33 +0200 Subject: [PATCH 6/8] test before reading config files --- src/CPFEM.f90 | 4 ++-- src/CPFEM2.f90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 05255e2a1..f93472e51 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -78,11 +78,11 @@ subroutine CPFEM_initAll call DAMASK_interface_init call prec_init call IO_init + call YAML_types_init + call YAML_parse_init call config_init call math_init call rotations_init - call YAML_types_init - call YAML_parse_init call HDF5_utilities_init call results_init(.false.) call discretization_marc_init diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index fed43ba78..994859758 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -48,11 +48,11 @@ subroutine CPFEM_initAll #ifdef Mesh call FEM_quadrature_init #endif + call YAML_types_init + call YAML_parse_init call config_init call math_init call rotations_init - call YAML_types_init - call YAML_parse_init call lattice_init call HDF5_utilities_init call results_init(restart=interface_restartInc>0) From 385cda9224dba4e84d0e93f5aba967efed279811 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 29 Sep 2020 20:13:02 +0200 Subject: [PATCH 7/8] remove unnecessary variables --- src/YAML_parse.f90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index bb990fc52..a63a07cf1 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -236,14 +236,12 @@ subroutine skip_empty_lines(blck,s_blck) character(len=*), intent(in) :: blck integer, intent(inout) :: s_blck - integer :: e_blck logical :: empty empty = .true. do while(empty .and. len_trim(blck(s_blck:)) /= 0) - e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 - empty = len_trim(IO_rmComment(blck(s_blck:e_blck))) == 0 - if(empty) s_blck = e_blck + 2 + empty = len_trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == 0 + if(empty) s_blck = s_blck + index(blck(s_blck:),IO_EOL) enddo From 15ef6c8ceb65e671b6c950af4ce62c153da47421 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Wed, 30 Sep 2020 01:50:10 +0200 Subject: [PATCH 8/8] more fortran like --- src/YAML_parse.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index a63a07cf1..cb5b726dc 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -260,7 +260,7 @@ subroutine skip_file_header(blck,s_blck) character(len=:), allocatable :: line line = IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2)) - if(adjustl(line(1:5)) == '%YAML') then + if(index(adjustl(line),'%YAML') == 1) then s_blck = s_blck + index(blck(s_blck:),IO_EOL) call skip_empty_lines(blck,s_blck) if(trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == '---') then @@ -725,7 +725,7 @@ subroutine selfTest basic_mixed: block character(len=*), parameter :: block_flow = & - "%YAML 1.2"//IO_EOL//& + "%YAML 1.1"//IO_EOL//& " "//IO_EOL//& " "//IO_EOL//& "---"//IO_EOL//&