Skip to content

Commit b710be8

Browse files
Merge pull request #254 from jacobwilliams/path_sep
Added option to change default path sep character.
2 parents e889753 + f650da3 commit b710be8

5 files changed

+89
-46
lines changed

src/json_file_module.F90

+8-4
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
275275
no_whitespace,&
276276
unescape_strings,&
277277
comment_char,&
278-
use_rfc6901_paths)
278+
use_rfc6901_paths,&
279+
path_separator)
279280

280281
implicit none
281282

@@ -290,7 +291,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
290291
no_whitespace,&
291292
unescape_strings,&
292293
comment_char,&
293-
use_rfc6901_paths)
294+
use_rfc6901_paths,&
295+
path_separator)
294296

295297
end subroutine initialize_json_core_in_file
296298
!*****************************************************************************************
@@ -352,7 +354,8 @@ function initialize_json_file(p,verbose,compact_reals,&
352354
no_whitespace,&
353355
unescape_strings,&
354356
comment_char,&
355-
use_rfc6901_paths) result(file_object)
357+
use_rfc6901_paths,&
358+
path_separator) result(file_object)
356359

357360
implicit none
358361

@@ -369,7 +372,8 @@ function initialize_json_file(p,verbose,compact_reals,&
369372
no_whitespace,&
370373
unescape_strings,&
371374
comment_char,&
372-
use_rfc6901_paths)
375+
use_rfc6901_paths,&
376+
path_separator)
373377

374378
if (present(p)) file_object%p => p
375379

src/json_initialize_arguments.inc

+7
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,10 @@
2626
!! `get_by_path` routines are interpreted
2727
!! as RFC 6901 "JSON Pointer" paths.
2828
!! By default, this is False.
29+
character(kind=CK,len=1),intent(in),optional :: path_separator !! The `path` separator to use
30+
!! in the "default" mode for
31+
!! the paths in the various
32+
!! `get_by_path` routines.
33+
!! Example: `.` [default] or `%`.
34+
!! Note: if `use_rfc6901_paths=true`
35+
!! then this is ignored.

src/json_parameters.F90

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ module json_parameters
4949
character(kind=CK,len=*),parameter :: end_array_alt = CK_')' !! for [[json_get_by_path]]
5050
character(kind=CK,len=*),parameter :: root = CK_'$' !! for [[json_get_by_path]]
5151
character(kind=CK,len=*),parameter :: this = CK_'@' !! for [[json_get_by_path]]
52-
character(kind=CK,len=*),parameter :: child = CK_'.' !! for [[json_get_by_path]]
53-
character(kind=CK,len=*),parameter :: tilde = CK_'~'
52+
character(kind=CK,len=*),parameter :: dot = CK_'.' !! for [[json_get_by_path]]
53+
character(kind=CK,len=*),parameter :: tilde = CK_'~' !! RFC 6901 escape character
54+
character(kind=CK,len=*),parameter :: percent = CK_'%' !! Fortran path separator
5455
character(kind=CK,len=*),parameter :: bspace = achar(8, kind=CK)
5556
character(kind=CK,len=*),parameter :: horizontal_tab = achar(9, kind=CK)
5657
character(kind=CK,len=*),parameter :: newline = achar(10, kind=CK)

src/json_value_module.F90

+59-40
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,21 @@ module json_value_module
204204
logical(LK) :: allow_comments = .true. !! if true, any comments will be ignored when
205205
!! parsing a file. The comment token is defined
206206
!! by the `comment_char` string.
207-
character(kind=CK,len=1) :: comment_char = '!' !! comment token when
208-
!! `allow_comments` is true.
209-
!! Examples: '`!`' or '`#`'.
207+
character(kind=CK,len=1) :: comment_char = CK_'!' !! comment token when
208+
!! `allow_comments` is true.
209+
!! Examples: '`!`' or '`#`'.
210210

211211
logical(LK) :: use_rfc6901_paths = .false. !! use the RFC 6901 standard for
212212
!! JSON paths. Otherwise, the original
213213
!! default method is used
214214

215+
character(kind=CK,len=1) :: path_separator = dot !! The `path` separator to use
216+
!! in the "default" mode for
217+
!! the paths in the various
218+
!! `get_by_path` routines.
219+
!! Note: if `use_rfc6901_paths=true`
220+
!! then this is ignored.
221+
215222
contains
216223

217224
private
@@ -653,7 +660,8 @@ function initialize_json_core(verbose,compact_reals,&
653660
no_whitespace,&
654661
unescape_strings,&
655662
comment_char,&
656-
use_rfc6901_paths) result(json_core_object)
663+
use_rfc6901_paths,&
664+
path_separator) result(json_core_object)
657665

658666
implicit none
659667

@@ -668,7 +676,8 @@ function initialize_json_core(verbose,compact_reals,&
668676
no_whitespace,&
669677
unescape_strings,&
670678
comment_char,&
671-
use_rfc6901_paths)
679+
use_rfc6901_paths,&
680+
path_separator)
672681

673682
end function initialize_json_core
674683
!*****************************************************************************************
@@ -700,7 +709,8 @@ subroutine json_initialize(json,verbose,compact_reals,&
700709
no_whitespace,&
701710
unescape_strings,&
702711
comment_char,&
703-
use_rfc6901_paths)
712+
use_rfc6901_paths,&
713+
path_separator)
704714

705715
implicit none
706716

@@ -755,6 +765,11 @@ subroutine json_initialize(json,verbose,compact_reals,&
755765
json%comment_char = comment_char
756766
end if
757767

768+
! path separator:
769+
if (present(path_separator)) then
770+
json%path_separator = path_separator
771+
end if
772+
758773
!Set the format for real numbers:
759774
! [if not changing it, then it remains the same]
760775

@@ -3894,12 +3909,10 @@ end subroutine json_get_by_path
38943909
!### Notes
38953910
! The following special characters are used to denote paths:
38963911
!
3897-
!````
3898-
! $ - root
3899-
! @ - this
3900-
! . - child object member
3901-
! [] or () - child array element
3902-
!````
3912+
! * `$` - root
3913+
! * `@` - this
3914+
! * `.` - child object member (note this can be changed using `json%path_separator`)
3915+
! * `[]` or `()` - child array element
39033916
!
39043917
! Thus, if any of these characters are present in the name key,
39053918
! this routine cannot be used to get the value.
@@ -3964,27 +3977,6 @@ subroutine json_get_by_path_default(json, me, path, p, found)
39643977
p => me
39653978
child_i = i + 1
39663979

3967-
case (child)
3968-
3969-
! get child member from p
3970-
if (child_i < i) then
3971-
nullify(tmp)
3972-
call json%get_child(p, path(child_i:i-1), tmp)
3973-
p => tmp
3974-
nullify(tmp)
3975-
else
3976-
child_i = i + 1
3977-
cycle
3978-
end if
3979-
3980-
if (.not. associated(p)) then
3981-
call json%throw_exception('Error in json_get_by_path:'//&
3982-
' Error getting child member.')
3983-
exit
3984-
end if
3985-
3986-
child_i = i+1
3987-
39883980
case (start_array,start_array_alt)
39893981

39903982
!....Modified to allow for 'var[3]' style syntax
@@ -4026,6 +4018,31 @@ subroutine json_get_by_path_default(json, me, path, p, found)
40264018

40274019
child_i= i + 1
40284020

4021+
case default
4022+
4023+
if (c==json%path_separator) then
4024+
4025+
! get child member from p
4026+
if (child_i < i) then
4027+
nullify(tmp)
4028+
call json%get_child(p, path(child_i:i-1), tmp)
4029+
p => tmp
4030+
nullify(tmp)
4031+
else
4032+
child_i = i + 1
4033+
cycle
4034+
end if
4035+
4036+
if (.not. associated(p)) then
4037+
call json%throw_exception('Error in json_get_by_path:'//&
4038+
' Error getting child member.')
4039+
exit
4040+
end if
4041+
4042+
child_i = i+1
4043+
4044+
end if
4045+
40294046
end select
40304047

40314048
end do
@@ -4096,7 +4113,7 @@ end subroutine json_get_by_path_default
40964113
!### Reference
40974114
! * [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901)
40984115
!
4099-
!@note Not doing anything special about the "-" character to index an array.
4116+
!@note Not doing anything special about the `-` character to index an array.
41004117
! This is considered a normal error.
41014118
!
41024119
!@warning Not checking if the member that is referenced is unique.
@@ -4309,7 +4326,7 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
43094326
logical(LK),intent(in),optional :: use_alt_array_tokens !! if true, then '()' are used for array elements
43104327
!! otherwise, '[]' are used [default]
43114328
character(kind=CK,len=1),intent(in),optional :: path_sep !! character to use for path separator
4312-
!! (default is '.')
4329+
!! (otherwise use `json%path_separator`)
43134330

43144331
type(json_value),pointer :: tmp !! for traversing the structure
43154332
type(json_value),pointer :: element !! for traversing the structure
@@ -4445,11 +4462,11 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
44454462

44464463
contains
44474464

4448-
subroutine add_to_path(str,dot)
4465+
subroutine add_to_path(str,path_sep)
44494466
!! prepend the string to the path
44504467
implicit none
44514468
character(kind=CK,len=*),intent(in) :: str !! string to prepend to `path`
4452-
character(kind=CK,len=1),intent(in),optional :: dot
4469+
character(kind=CK,len=1),intent(in),optional :: path_sep
44534470
!! path separator (default is '.').
44544471
!! (ignored if `json%use_rfc6901_paths=.true.`)
44554472

@@ -4465,10 +4482,12 @@ subroutine add_to_path(str,dot)
44654482
if (path==CK_'') then
44664483
path = str
44674484
else
4468-
if (present(dot)) then
4469-
path = str//dot//path
4485+
if (present(path_sep)) then
4486+
! use user specified:
4487+
path = str//path_sep//path
44704488
else
4471-
path = str//child//path
4489+
! use the default:
4490+
path = str//json%path_separator//path
44724491
end if
44734492
end if
44744493
end if

src/tests/jf_test_1.f90

+12
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ subroutine test_1(error_cnt)
9494
write(error_unit,'(A)') ''
9595
write(error_unit,'(A)') 'get some data from the file...'
9696

97+
call json%initialize(path_separator=json_CK_'%') ! use fortran-style paths
98+
99+
call json%get('version%svn', ival)
100+
if (json%failed()) then
101+
call json%print_error_message(error_unit)
102+
error_cnt = error_cnt + 1
103+
else
104+
write(error_unit,'(A,I5)') 'version%svn = ',ival
105+
end if
106+
107+
call json%initialize(path_separator=json_CK_'.') ! reset to normal paths
108+
97109
write(error_unit,'(A)') ''
98110
call json%get('version.svn', ival)
99111
if (json%failed()) then

0 commit comments

Comments
 (0)