Skip to content

Commit c13a83d

Browse files
committed
Merge branch 'master' of https://github.com/jacobwilliams/json-fortran into get_alloc_string
2 parents 4907f50 + b710be8 commit c13a83d

File tree

9 files changed

+249
-134
lines changed

9 files changed

+249
-134
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
JSON-Fortran: A Fortran 2008 JSON API
22
<https://github.com/jacobwilliams/json-fortran>
33

4-
Copyright (c) 2014-2016, Jacob Williams
4+
Copyright (c) 2014-2017, Jacob Williams
55
All rights reserved.
66

77
Redistribution and use in source and binary forms, with or without modification,

files/inputs/test1.json

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,49 @@
11
{
2-
"version": {
3-
"major": 2,
4-
"minor": 2,
5-
"patch": 1,
6-
"string": "2.2.1",
7-
"svn": 7191
8-
},
9-
"files": [
10-
"..\\path\\to\\files\\file1.txt",
11-
"..\\path\\to\\files\\file2.txt",
12-
"..\\path\\to\\files\\file3.txt",
13-
"test \u2FA4 \uABCD \uABCD\uABCDtest",
14-
" test \\u \" blah\\\" test test",
15-
"..\\path\\to\\files\\"
16-
],
17-
"empty_array": [
18-
],
19-
"empty_object": {
20-
},
21-
"empty_string": "",
22-
"data": [
23-
{
24-
"number": 1,
25-
"tf1": true,
26-
"tf2": false,
27-
"empty": null,
28-
"name": "Horatio",
29-
"array": [
30-
"1",
31-
"2",
32-
"3"
33-
]
34-
},
35-
{
36-
"number": 2,
37-
"integer": 33,
38-
"real": 0.2333000000000000E+003,
39-
"name": "Nelson"
40-
}
41-
]
2+
"version": {
3+
"major": 2,
4+
"minor": 2,
5+
"patch": 1,
6+
"string": "2.2.1",
7+
"svn": 7191
8+
},
9+
"files": [
10+
"..\\path\\to\\files\\file1.txt",
11+
"..\\path\\to\\files\\file2.txt",
12+
"..\\path\\to\\files\\file3.txt",
13+
"test \u2FA4 \uABCD \uABCD\uABCDtest",
14+
" test \\u \" blah\\\" test test",
15+
"..\\path\\to\\files\\"
16+
],
17+
"empty_array": [],
18+
"empty_object": {},
19+
"empty_string": "",
20+
"data": [{
21+
"number": 1,
22+
"tf1": true,
23+
"tf2": false,
24+
"empty": null,
25+
"name": "Horatio",
26+
"array": [
27+
"1",
28+
"2",
29+
"3"
30+
]
31+
}, {
32+
"number": 2,
33+
"integer": 33,
34+
"real": 0.2333000000000000E+003,
35+
"name": "Nelson"
36+
}],
37+
"rfc6901 tests": {
38+
"foo": ["bar", "baz"],
39+
" ": 0,
40+
"a/b": 1,
41+
"c%d": 2,
42+
"e^f": 3,
43+
"g|h": 4,
44+
"i\\j": 5,
45+
"k\"l": 6,
46+
" ": 7,
47+
"m~n": 8
48+
}
4249
}

src/json_file_module.F90

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
277277
no_whitespace,&
278278
unescape_strings,&
279279
comment_char,&
280-
use_rfc6901_paths)
280+
use_rfc6901_paths,&
281+
path_separator)
281282

282283
implicit none
283284

@@ -292,7 +293,8 @@ subroutine initialize_json_core_in_file(me,verbose,compact_reals,&
292293
no_whitespace,&
293294
unescape_strings,&
294295
comment_char,&
295-
use_rfc6901_paths)
296+
use_rfc6901_paths,&
297+
path_separator)
296298

297299
end subroutine initialize_json_core_in_file
298300
!*****************************************************************************************
@@ -354,7 +356,8 @@ function initialize_json_file(p,verbose,compact_reals,&
354356
no_whitespace,&
355357
unescape_strings,&
356358
comment_char,&
357-
use_rfc6901_paths) result(file_object)
359+
use_rfc6901_paths,&
360+
path_separator) result(file_object)
358361

359362
implicit none
360363

@@ -371,7 +374,8 @@ function initialize_json_file(p,verbose,compact_reals,&
371374
no_whitespace,&
372375
unescape_strings,&
373376
comment_char,&
374-
use_rfc6901_paths)
377+
use_rfc6901_paths,&
378+
path_separator)
375379

376380
if (present(p)) file_object%p => p
377381

src/json_initialize_arguments.inc

Lines changed: 7 additions & 0 deletions
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

Lines changed: 3 additions & 2 deletions
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_string_utilities.F90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,8 +796,8 @@ pure subroutine replace_string(str,s1,s2)
796796
if (i>0) then
797797
if (i>1) tmp = tmp//str(1:i-1)
798798
tmp = tmp//s2 ! replace s1 with s2 in new string
799-
n = i+ilen1+1 ! start of remainder of str to keep
800-
if (n<ilen) then
799+
n = i+ilen1 ! start of remainder of str to keep
800+
if (n<=ilen) then
801801
str = str(n:ilen)
802802
else
803803
! done

src/json_value_module.F90

Lines changed: 59 additions & 40 deletions
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
@@ -661,7 +668,8 @@ function initialize_json_core(verbose,compact_reals,&
661668
no_whitespace,&
662669
unescape_strings,&
663670
comment_char,&
664-
use_rfc6901_paths) result(json_core_object)
671+
use_rfc6901_paths,&
672+
path_separator) result(json_core_object)
665673

666674
implicit none
667675

@@ -676,7 +684,8 @@ function initialize_json_core(verbose,compact_reals,&
676684
no_whitespace,&
677685
unescape_strings,&
678686
comment_char,&
679-
use_rfc6901_paths)
687+
use_rfc6901_paths,&
688+
path_separator)
680689

681690
end function initialize_json_core
682691
!*****************************************************************************************
@@ -708,7 +717,8 @@ subroutine json_initialize(json,verbose,compact_reals,&
708717
no_whitespace,&
709718
unescape_strings,&
710719
comment_char,&
711-
use_rfc6901_paths)
720+
use_rfc6901_paths,&
721+
path_separator)
712722

713723
implicit none
714724

@@ -763,6 +773,11 @@ subroutine json_initialize(json,verbose,compact_reals,&
763773
json%comment_char = comment_char
764774
end if
765775

776+
! path separator:
777+
if (present(path_separator)) then
778+
json%path_separator = path_separator
779+
end if
780+
766781
!Set the format for real numbers:
767782
! [if not changing it, then it remains the same]
768783

@@ -4058,12 +4073,10 @@ end subroutine json_get_by_path
40584073
!### Notes
40594074
! The following special characters are used to denote paths:
40604075
!
4061-
!````
4062-
! $ - root
4063-
! @ - this
4064-
! . - child object member
4065-
! [] or () - child array element
4066-
!````
4076+
! * `$` - root
4077+
! * `@` - this
4078+
! * `.` - child object member (note this can be changed using `json%path_separator`)
4079+
! * `[]` or `()` - child array element
40674080
!
40684081
! Thus, if any of these characters are present in the name key,
40694082
! this routine cannot be used to get the value.
@@ -4128,27 +4141,6 @@ subroutine json_get_by_path_default(json, me, path, p, found)
41284141
p => me
41294142
child_i = i + 1
41304143

4131-
case (child)
4132-
4133-
! get child member from p
4134-
if (child_i < i) then
4135-
nullify(tmp)
4136-
call json%get_child(p, path(child_i:i-1), tmp)
4137-
p => tmp
4138-
nullify(tmp)
4139-
else
4140-
child_i = i + 1
4141-
cycle
4142-
end if
4143-
4144-
if (.not. associated(p)) then
4145-
call json%throw_exception('Error in json_get_by_path:'//&
4146-
' Error getting child member.')
4147-
exit
4148-
end if
4149-
4150-
child_i = i+1
4151-
41524144
case (start_array,start_array_alt)
41534145

41544146
!....Modified to allow for 'var[3]' style syntax
@@ -4190,6 +4182,31 @@ subroutine json_get_by_path_default(json, me, path, p, found)
41904182

41914183
child_i= i + 1
41924184

4185+
case default
4186+
4187+
if (c==json%path_separator) then
4188+
4189+
! get child member from p
4190+
if (child_i < i) then
4191+
nullify(tmp)
4192+
call json%get_child(p, path(child_i:i-1), tmp)
4193+
p => tmp
4194+
nullify(tmp)
4195+
else
4196+
child_i = i + 1
4197+
cycle
4198+
end if
4199+
4200+
if (.not. associated(p)) then
4201+
call json%throw_exception('Error in json_get_by_path:'//&
4202+
' Error getting child member.')
4203+
exit
4204+
end if
4205+
4206+
child_i = i+1
4207+
4208+
end if
4209+
41934210
end select
41944211

41954212
end do
@@ -4260,7 +4277,7 @@ end subroutine json_get_by_path_default
42604277
!### Reference
42614278
! * [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901)
42624279
!
4263-
!@note Not doing anything special about the "-" character to index an array.
4280+
!@note Not doing anything special about the `-` character to index an array.
42644281
! This is considered a normal error.
42654282
!
42664283
!@warning Not checking if the member that is referenced is unique.
@@ -4473,7 +4490,7 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
44734490
logical(LK),intent(in),optional :: use_alt_array_tokens !! if true, then '()' are used for array elements
44744491
!! otherwise, '[]' are used [default]
44754492
character(kind=CK,len=1),intent(in),optional :: path_sep !! character to use for path separator
4476-
!! (default is '.')
4493+
!! (otherwise use `json%path_separator`)
44774494

44784495
type(json_value),pointer :: tmp !! for traversing the structure
44794496
type(json_value),pointer :: element !! for traversing the structure
@@ -4609,11 +4626,11 @@ subroutine json_get_path(json, p, path, found, use_alt_array_tokens, path_sep)
46094626

46104627
contains
46114628

4612-
subroutine add_to_path(str,dot)
4629+
subroutine add_to_path(str,path_sep)
46134630
!! prepend the string to the path
46144631
implicit none
46154632
character(kind=CK,len=*),intent(in) :: str !! string to prepend to `path`
4616-
character(kind=CK,len=1),intent(in),optional :: dot
4633+
character(kind=CK,len=1),intent(in),optional :: path_sep
46174634
!! path separator (default is '.').
46184635
!! (ignored if `json%use_rfc6901_paths=.true.`)
46194636

@@ -4629,10 +4646,12 @@ subroutine add_to_path(str,dot)
46294646
if (path==CK_'') then
46304647
path = str
46314648
else
4632-
if (present(dot)) then
4633-
path = str//dot//path
4649+
if (present(path_sep)) then
4650+
! use user specified:
4651+
path = str//path_sep//path
46344652
else
4635-
path = str//child//path
4653+
! use the default:
4654+
path = str//json%path_separator//path
46364655
end if
46374656
end if
46384657
end if

src/tests/jf_test_1.f90

Lines changed: 12 additions & 0 deletions
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)