Created
July 16, 2015 19:41
-
-
Save zbeekman/d08dc23555db10e2da48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-: 0:Source:/Users/ibeekman/Sandbox/json-fortran/src/json_module.F90 | |
-: 0:Graph:CMakeFiles/jsonfortran.dir/src/json_module.F90.gcno | |
-: 0:Data:CMakeFiles/jsonfortran.dir/src/json_module.F90.gcda | |
-: 0:Runs:11 | |
-: 0:Programs:1 | |
-: 1:!***************************************************************************************** | |
-: 2:!> author: Jacob Williams | |
-: 3:! license: BSD | |
-: 4:! | |
-: 5:!# JSON-Fortran: | |
-: 6:! A Fortran 2008 JSON (JavaScript Object Notation) API. | |
-: 7:! | |
-: 8:! [TOC] | |
-: 9:! | |
-: 10:! This module provides an interface for reading and writing JSON files. | |
-: 11:! | |
-: 12:!@note ```-DUSE_UCS4``` is an optional preprocessor flag. | |
-: 13:! When present, Unicode support is enabled. Note that this | |
-: 14:! is currently only supported with the gfortran compiler. | |
-: 15:! Example: ```gfortran -DUSE_UCS4 ... ``` | |
-: 16:#ifdef USE_UCS4 | |
-: 17:# pragma push_macro("USE_UCS4") | |
-: 18:# undef USE_UCS4 | |
-: 19:! The documentation given here assumes ```USE_UCS4``` **is** defined. | |
-: 20:# pragma pop_macro("USE_UCS4") | |
-: 21:#else | |
-: 22:! The documentation given here assumes ```USE_UCS4``` **is not** defined. | |
-: 23:#endif | |
-: 24:! | |
-: 25:!@warning ```CK``` and ```CDK``` are the JSON-Fortran character kind and JSON-Fortran default | |
-: 26:! character kind respectively. Client code **MUST** ensure characters of ```kind=CK``` | |
-: 27:! are used for all character variables and strings passed to the JSON-Fortran | |
-: 28:! library *EXCEPT* for file names which must be of ```'DEFAULT'``` character kind, | |
-: 29:! provided here as ```CDK```. In particular, any variable that is a: json path, string | |
-: 30:! value or object name passed to the JSON-Fortran library **MUST** be of type ```CK```. | |
-: 31:! | |
-: 32:!@note Most string literal constants of default kind are fine to pass as arguments to | |
-: 33:! JSON-Fortran procedures since they have been overloaded to accept ```intent(in)``` | |
-: 34:! character arguments of the default (```CDK```) kind. If you find a procedure which does | |
-: 35:! not accept an ```intent(in)``` literal string argument of default kind, please | |
-: 36:! [file an issue](https://github.com/jacobwilliams/json-fortran/issues/new) on github. | |
-: 37:! | |
-: 38:!## License | |
-: 39:! | |
-: 40:! **JSON-Fortran License:** | |
-: 41:! | |
-: 42:! JSON-Fortran: A Fortran 2008 JSON API | |
-: 43:! | |
-: 44:! http://github.com/jacobwilliams/json-fortran | |
-: 45:! | |
-: 46:! Copyright (c) 2014-2015, Jacob Williams | |
-: 47:! | |
-: 48:! All rights reserved. | |
-: 49:! | |
-: 50:! Redistribution and use in source and binary forms, with or without modification, | |
-: 51:! are permitted provided that the following conditions are met: | |
-: 52:! * Redistributions of source code must retain the above copyright notice, this | |
-: 53:! list of conditions and the following disclaimer. | |
-: 54:! * Redistributions in binary form must reproduce the above copyright notice, this | |
-: 55:! list of conditions and the following disclaimer in the documentation and/or | |
-: 56:! other materials provided with the distribution. | |
-: 57:! * The names of its contributors may not be used to endorse or promote products | |
-: 58:! derived from this software without specific prior written permission. | |
-: 59:! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
-: 60:! ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
-: 61:! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
-: 62:! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
-: 63:! ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
-: 64:! (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
-: 65:! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
-: 66:! ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
-: 67:! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
-: 68:! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
-: 69:! | |
-: 70:! **Original FSON License:** | |
-: 71:! | |
-: 72:! Copyright (c) 2012 Joseph A. Levin | |
-: 73:! | |
-: 74:! Permission is hereby granted, free of charge, to any person obtaining a copy of this | |
-: 75:! software and associated documentation files (the "Software"), to deal in the Software | |
-: 76:! without restriction, including without limitation the rights to use, copy, modify, merge, | |
-: 77:! publish, distribute, sublicense, and/or sell copies of the Software, and to permit | |
-: 78:! persons to whom the Software is furnished to do so, subject to the following conditions: | |
-: 79:! | |
-: 80:! The above copyright notice and this permission notice shall be included in all copies or | |
-: 81:! substantial portions of the Software. | |
-: 82:! | |
-: 83:! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
-: 84:! INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
-: 85:! PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
-: 86:! LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT | |
-: 87:! OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
-: 88:! DEALINGS IN THE SOFTWARE. | |
-: 89:! | |
-: 90:!## History | |
-: 91:! * Joseph A. Levin : March 2012 : Original FSON code [retrieved on 12/2/2013]. | |
-: 92:! * Jacob Williams : 2/8/2014 : Extensive modifications to the original FSON code. | |
-: 93:! The original F95 code was split into four files: | |
-: 94:! fson_path_m.f95, fson_string_m.f95, fson_value_m.f95, and fson.f95. | |
-: 95:! The new code has been extensively updated, refactored and combined into this | |
-: 96:! one module (json_module.f90). | |
-: 97:! Various Fortran 2003/2008 features are now used | |
-: 98:! (e.g., allocatable strings, newunit, generic, class, and abstract interface). | |
-: 99:! * Development continues at: [Github](http://github.com/jacobwilliams/json-fortran) | |
-: 100:! | |
-: 101:!## See also | |
-: 102:! * [json-fortran development site](http://github.com/jacobwilliams/json-fortran) | |
-: 103:! * [json-fortran online documentation](http://jacobwilliams.github.io/json-fortran) | |
-: 104:! * [JSON website](http://www.json.org/) | |
-: 105:! * [JSON validator](http://jsonlint.com/) | |
-: 106: | |
-: 107: module json_module | |
-: 108: | |
-: 109: use,intrinsic :: iso_fortran_env | |
-: 110: | |
-: 111: implicit none | |
-: 112: | |
-: 113: private | |
-: 114: | |
-: 115: integer,parameter :: RK = real64 !! Default real kind [8 bytes] | |
-: 116: | |
-: 117: integer,parameter :: IK = int32 !! Default integer kind [4 bytes]. | |
-: 118: | |
-: 119: !********************************************************* | |
-: 120: !> | |
-: 121: ! Processor dependendant 'DEFAULT' character kind. | |
-: 122: ! This is 1 byte for the Intel and Gfortran compilers. | |
-: 123: | |
-: 124: integer,parameter,public :: CDK = selected_char_kind('DEFAULT') | |
-: 125: !********************************************************* | |
-: 126: | |
-: 127: !********************************************************* | |
-: 128: !> | |
-: 129: ! Default logical kind. | |
-: 130: ! This is 4 bytes for the Intel and Gfortran compilers | |
-: 131: ! (and perhaps others). | |
-: 132: ! The declaration ensures a valid kind | |
-: 133: ! if the compiler doesn't have a logical_kinds(3). | |
-: 134: ! | |
-: 135: integer,parameter :: LK = logical_kinds(min(3,size(logical_kinds))) | |
-: 136: !********************************************************* | |
-: 137: | |
-: 138: !********************************************************* | |
-: 139: !> | |
-: 140: ! String kind preprocessor macro. | |
-: 141: ! | |
-: 142:#if defined __GFORTRAN__ && defined USE_UCS4 | |
-: 143: ! gfortran compiler AND UCS4 support requested: | |
-: 144: character(kind=CDK,len=*),parameter :: json_fortran_string_kind = 'ISO_10646' | |
-: 145:#else | |
-: 146: ! this is the string kind to use unless compiling with GFortran AND | |
-: 147: ! UCS4/ISO 10646 support is requested | |
-: 148: character(kind=CDK,len=*),parameter :: json_fortran_string_kind = 'DEFAULT' | |
-: 149:#endif | |
-: 150: !********************************************************* | |
-: 151: | |
-: 152: !********************************************************* | |
-: 153: !> | |
-: 154: ! Default character kind used by JSON-Fortran. | |
-: 155: ! If ISO 10646 (UCS4) support is available, use that, | |
-: 156: ! otherwise, gracefully fall back on 'DEFAULT' characters. | |
-: 157: ! Currently only gfortran >= 4.9.2 will correctly support | |
-: 158: ! UCS4 which is stored in 4 bytes. | |
-: 159: ! (and perhaps others). | |
-: 160: | |
-: 161: integer,parameter,public :: CK = selected_char_kind(json_fortran_string_kind) | |
-: 162: !********************************************************* | |
-: 163: | |
-: 164: !********************************************************* | |
-: 165: ! File encoding preprocessor macro. | |
-: 166: ! | |
-: 167:#if defined __GFORTRAN__ && defined USE_UCS4 | |
-: 168: ! gfortran compiler AND UCS4 support requested, & silence redefine warning: | |
-: 169: ! Make sure we output files with utf-8 encoding too | |
-: 170:#define FILE_ENCODING ,encoding='UTF-8' | |
-: 171:#else | |
-: 172: ! don't ask for utf-8 file encoding unless using UCS4 | |
-: 173: ! this may let us use unformatted stream io to read in files more quickly | |
-: 174: ! even with unicode support turned on `inquire( ... encoding=FL_ENCODING)` | |
-: 175: ! may be able to detect json files in which each character is exactly one | |
-: 176: ! byte | |
-: 177:#define FILE_ENCODING | |
-: 178:#endif | |
-: 179: !********************************************************* | |
-: 180: | |
-: 181: !********************************************************* | |
-: 182: ! This C preprocessor macro will take a procedure name as an | |
-: 183: ! input, and output either that same procedure name if the | |
-: 184: ! code is compiled without USE_UCS4 being defined or it will | |
-: 185: ! expand the procedure name to the original procedure name, | |
-: 186: ! followed by a comma and then the original procedure name | |
-: 187: ! with 'wrap_' prepended to it. This is suitable for creating | |
-: 188: ! overloaded interfaces that will accept UCS4 character actual | |
-: 189: ! arguments as well as DEFAULT/ASCII character arguments, | |
-: 190: ! based on whether or not ISO 10646 is supported and requested. | |
-: 191: ! | |
-: 192:# ifdef USE_UCS4 | |
-: 193:# ifdef __GFORTRAN__ | |
-: 194: ! gfortran uses cpp in old-school compatibility mode so | |
-: 195: ! the # stringify and ## concatenate operators don't work | |
-: 196: ! but we can use C/C++ style comment to ensure PROCEDURE is | |
-: 197: ! correctly tokenized and prepended with 'wrap_' when the | |
-: 198: ! macro is expanded | |
-: 199:# define MAYBEWRAP(PROCEDURE) PROCEDURE , wrap_/**/PROCEDURE | |
-: 200:# endif | |
-: 201:! ifdef __INTEL_COMPILER | |
-: 202: ! Intel's fpp does support the more contemporary ## concatenation | |
-: 203: ! operator, but doesn't treat the C/C++ comments the same way. | |
-: 204: ! If you use the gfortran approach and pass the -noB switch to | |
-: 205: ! fpp, the macro will expand, but with a space between wrap_ and | |
-: 206: ! whatever PROCEDURE expands to | |
-: 207: ! Intel doesn't support ISO 10646 yet, but this is here to | |
-: 208: ! ease the transition once they do. | |
-: 209:! define MAYBEWRAP(PROCEDURE) PROCEDURE , wrap_##PROCEDURE | |
-: 210:! endif | |
-: 211:# else | |
-: 212:# define MAYBEWRAP(PROCEDURE) PROCEDURE | |
-: 213:# endif | |
-: 214: !********************************************************* | |
-: 215: | |
-: 216: !********************************************************* | |
-: 217: !> | |
-: 218: ! If Unicode is not enabled, then | |
-: 219: ! JSON files are opened using access='STREAM' and | |
-: 220: ! form='UNFORMATTED'. This allows the file to | |
-: 221: ! be read faster. | |
-: 222: ! | |
-: 223:#ifdef USE_UCS4 | |
-: 224: logical,parameter :: use_unformatted_stream = .false. | |
-: 225:#else | |
-: 226: logical,parameter :: use_unformatted_stream = .true. | |
-: 227:#endif | |
-: 228: !********************************************************* | |
-: 229: | |
-: 230: !********************************************************* | |
-: 231: !> | |
-: 232: ! If Unicode is not enabled, then | |
-: 233: ! JSON files are opened using access='STREAM' and | |
-: 234: ! form='UNFORMATTED'. This allows the file to | |
-: 235: ! be read faster. | |
-: 236: ! | |
-: 237:#ifdef USE_UCS4 | |
-: 238: character(kind=CDK,len=*),parameter :: access_spec = 'SEQUENTIAL' | |
-: 239:#else | |
-: 240: character(kind=CDK,len=*),parameter :: access_spec = 'STREAM' | |
-: 241:#endif | |
-: 242: !********************************************************* | |
-: 243: | |
-: 244: !********************************************************* | |
-: 245: !> | |
-: 246: ! If Unicode is not enabled, then | |
-: 247: ! JSON files are opened using access='STREAM' and | |
-: 248: ! form='UNFORMATTED'. This allows the file to | |
-: 249: ! be read faster. | |
-: 250: ! | |
-: 251:#ifdef USE_UCS4 | |
-: 252: character(kind=CDK,len=*),parameter :: form_spec = 'FORMATTED' | |
-: 253:#else | |
-: 254: character(kind=CDK,len=*),parameter :: form_spec = 'UNFORMATTED' | |
-: 255:#endif | |
-: 256: !********************************************************* | |
-: 257: | |
-: 258: !********************************************************* | |
-: 259: ! | |
-: 260: ! The types of JSON data. | |
-: 261: ! | |
-: 262: integer(IK),parameter,public :: json_unknown = 0 !! Unknown JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 263: integer(IK),parameter,public :: json_null = 1 !! Null JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 264: integer(IK),parameter,public :: json_object = 2 !! Object JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 265: integer(IK),parameter,public :: json_array = 3 !! Array JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 266: integer(IK),parameter,public :: json_logical = 4 !! Logical JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 267: integer(IK),parameter,public :: json_integer = 5 !! Integer JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 268: integer(IK),parameter,public :: json_double = 6 !! Double JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 269: integer(IK),parameter,public :: json_string = 7 !! String JSON data type (see [[json_file_variable_info]] and [[json_info]]) | |
-: 270: !********************************************************* | |
-: 271: | |
-: 272: !********************************************************* | |
-: 273: !> | |
-: 274: ! Type used to construct the linked-list JSON structure. | |
-: 275: ! Normally, this should always be a pointer variable. | |
-: 276: ! | |
-: 277: !# Example | |
-: 278: ! | |
-: 279: !```fortran | |
-: 280: ! type(json_value),pointer :: p | |
-: 281: ! call json_create_object(p,'') !root | |
-: 282: ! call json_add(p,'year',1805) | |
-: 283: ! call json_add(p,'value',1.0d0) | |
-: 284: ! call json_print(p,'test.json') | |
-: 285: ! call json_destroy(p) | |
-: 286: !``` | |
-: 287: ! | |
-: 288: type,public :: json_value | |
-: 289: | |
-: 290: !force the constituents to be stored contiguously | |
-: 291: ![note: on Intel, the order of the variables below | |
-: 292: ! is significant to avoid the misaligned field warnings] | |
-: 293: sequence | |
-: 294: | |
-: 295: private | |
-: 296: | |
-: 297: !for the linked list: | |
-: 298: type(json_value),pointer :: previous => null() !! previous item in the list | |
-: 299: type(json_value),pointer :: next => null() !! next item in the list | |
-: 300: type(json_value),pointer :: parent => null() !! parent item of this | |
-: 301: type(json_value),pointer :: children => null() !! first child item of this | |
-: 302: type(json_value),pointer :: tail => null() !! last child item of this | |
-: 303: | |
-: 304: character(kind=CK,len=:),allocatable :: name !! variable name | |
-: 305: | |
-: 306: real(RK),allocatable :: dbl_value !! real data for this variable | |
-: 307: logical(LK),allocatable :: log_value !! logical data for this variable | |
-: 308: character(kind=CK,len=:),allocatable :: str_value !! string data for this variable | |
-: 309: integer(IK),allocatable :: int_value !! integer data for this variable | |
-: 310: | |
-: 311: integer(IK) :: var_type = json_unknown !! variable type | |
-: 312: | |
-: 313: integer(IK),private :: n_children = 0 !! number of children | |
-: 314: | |
-: 315: end type json_value | |
-: 316: !********************************************************* | |
-: 317: | |
-: 318: !********************************************************* | |
-: 319: !> author: Jacob Williams | |
-: 320: ! date: 12/9/2013 | |
-: 321: ! | |
-: 322: ! The json_file is the main public class that is | |
-: 323: ! used to open a file and get data from it. | |
-: 324: ! | |
-: 325: !# Example | |
-: 326: ! | |
-: 327: !```fortran | |
-: 328: ! type(json_file) :: json | |
-: 329: ! integer :: ival | |
-: 330: ! real(real64) :: rval | |
-: 331: ! character(len=:),allocatable :: cval | |
-: 332: ! logical :: found | |
-: 333: ! call json%load_file(filename='myfile.json') | |
-: 334: ! call json%print_file() !print to the console | |
-: 335: ! call json%get('var.i',ival,found) | |
-: 336: ! call json%get('var.r(3)',rval,found) | |
-: 337: ! call json%get('var.c',cval,found) | |
-: 338: ! call json%destroy() | |
-: 339: !``` | |
-: 340: | |
-: 341: type,public :: json_file | |
-: 342: | |
-: 343: private | |
-: 344: | |
-: 345: !the JSON structure read from the file: | |
-: 346: type(json_value),pointer :: p => null() | |
-: 347: | |
-: 348: contains | |
-: 349: | |
-: 350: procedure,public :: load_file => json_file_load | |
-: 351: | |
-: 352: generic, public :: load_from_string => MAYBEWRAP(json_file_load_from_string) | |
-: 353: | |
-: 354: procedure,public :: destroy => json_file_destroy | |
-: 355: procedure,public :: move => json_file_move_pointer | |
-: 356: generic,public :: info => MAYBEWRAP(json_file_variable_info) | |
-: 357: | |
-: 358: procedure,public :: print_to_string => json_file_print_to_string | |
-: 359: | |
-: 360: generic,public :: print_file => json_file_print_to_console, & | |
-: 361: json_file_print_1, & | |
-: 362: json_file_print_2 | |
-: 363: | |
-: 364: generic,public :: get => MAYBEWRAP(json_file_get_object), & | |
-: 365: MAYBEWRAP(json_file_get_integer), & | |
-: 366: MAYBEWRAP(json_file_get_double), & | |
-: 367: MAYBEWRAP(json_file_get_logical), & | |
-: 368: MAYBEWRAP(json_file_get_string), & | |
-: 369: MAYBEWRAP(json_file_get_integer_vec), & | |
-: 370: MAYBEWRAP(json_file_get_double_vec), & | |
-: 371: MAYBEWRAP(json_file_get_logical_vec), & | |
-: 372: MAYBEWRAP(json_file_get_string_vec) | |
-: 373: | |
-: 374: generic,public :: update => MAYBEWRAP(json_file_update_integer), & | |
-: 375: MAYBEWRAP(json_file_update_logical), & | |
-: 376: MAYBEWRAP(json_file_update_real), & | |
-: 377: MAYBEWRAP(json_file_update_string) | |
-: 378:# ifdef USE_UCS4 | |
-: 379: generic,public :: update => json_file_update_string_name_ascii, & | |
-: 380: json_file_update_string_val_ascii | |
-: 381:# endif | |
-: 382: | |
-: 383: !load from string: | |
-: 384: procedure :: MAYBEWRAP(json_file_load_from_string) | |
-: 385: | |
-: 386: !git info: | |
-: 387: procedure :: MAYBEWRAP(json_file_variable_info) | |
-: 388: | |
-: 389: !get: | |
-: 390: procedure :: MAYBEWRAP(json_file_get_object) | |
-: 391: procedure :: MAYBEWRAP(json_file_get_integer) | |
-: 392: procedure :: MAYBEWRAP(json_file_get_double) | |
-: 393: procedure :: MAYBEWRAP(json_file_get_logical) | |
-: 394: procedure :: MAYBEWRAP(json_file_get_string) | |
-: 395: procedure :: MAYBEWRAP(json_file_get_integer_vec) | |
-: 396: procedure :: MAYBEWRAP(json_file_get_double_vec) | |
-: 397: procedure :: MAYBEWRAP(json_file_get_logical_vec) | |
-: 398: procedure :: MAYBEWRAP(json_file_get_string_vec) | |
-: 399: | |
-: 400: !update: | |
-: 401: procedure :: MAYBEWRAP(json_file_update_integer) | |
-: 402: procedure :: MAYBEWRAP(json_file_update_logical) | |
-: 403: procedure :: MAYBEWRAP(json_file_update_real) | |
-: 404: procedure :: MAYBEWRAP(json_file_update_string) | |
-: 405:# ifdef USE_UCS4 | |
-: 406: procedure :: json_file_update_string_name_ascii | |
-: 407: procedure :: json_file_update_string_val_ascii | |
-: 408:# endif | |
-: 409: | |
-: 410: !print_file: | |
-: 411: procedure :: json_file_print_to_console | |
-: 412: procedure :: json_file_print_1 | |
-: 413: procedure :: json_file_print_2 | |
-: 414: | |
-: 415: end type json_file | |
-: 416: !********************************************************* | |
-: 417: | |
-: 418: !************************************************************************************* | |
-: 419: !> | |
-: 420: ! Array element callback function. Used by [[json_get_array]]. | |
-: 421: | |
-: 422: abstract interface | |
-: 423: subroutine array_callback_func(element, i, count) | |
-: 424: import :: json_value,IK | |
-: 425: implicit none | |
-: 426: type(json_value), pointer,intent(in) :: element | |
-: 427: integer(IK),intent(in) :: i !index | |
-: 428: integer(IK),intent(in) :: count !size of array | |
-: 429: end subroutine array_callback_func | |
-: 430: end interface | |
-: 431: !************************************************************************************* | |
-: 432: | |
-: 433:# ifdef USE_UCS4 | |
-: 434: ! Provide a means to convert to UCS4 while concatenating UCS4 and default strings | |
-: 435: interface operator(//) | |
-: 436: module procedure ucs4_join_default, default_join_ucs4 | |
-: 437: end interface | |
-: 438: | |
-: 439: ! Provide a string comparison operator that works with mixed kinds | |
-: 440: interface operator(==) | |
-: 441: module procedure ucs4_comp_default, default_comp_ucs4 | |
-: 442: end interface | |
-: 443:# endif | |
-: 444: | |
-: 445: !************************************************************************************* | |
-: 446: !> | |
-: 447: ! Get a child, either by index or name string. | |
-: 448: ! Both of these return a [[json_value]] pointer. | |
-: 449: ! | |
-: 450: !@note Formerly, this was called json_value_get_child | |
-: 451: | |
-: 452: interface json_get_child | |
-: 453: module procedure json_value_get_by_index | |
-: 454: module procedure MAYBEWRAP(json_value_get_by_name_chars) | |
-: 455: end interface json_get_child | |
-: 456: !************************************************************************************* | |
-: 457: | |
-: 458: !************************************************************************************* | |
-: 459: !> | |
-: 460: ! Add objects to a linked list of [[json_value]]s. | |
-: 461: ! | |
-: 462: !@note Formerly, this was called json_value_add | |
-: 463: | |
-: 464: interface json_add | |
-: 465: module procedure json_value_add_member | |
-: 466: module procedure MAYBEWRAP(json_value_add_integer) | |
-: 467: module procedure MAYBEWRAP(json_value_add_integer_vec) | |
-: 468: module procedure MAYBEWRAP(json_value_add_double) | |
-: 469: module procedure MAYBEWRAP(json_value_add_double_vec) | |
-: 470: module procedure MAYBEWRAP(json_value_add_logical) | |
-: 471: module procedure MAYBEWRAP(json_value_add_logical_vec) | |
-: 472: module procedure MAYBEWRAP(json_value_add_string) | |
-: 473: module procedure MAYBEWRAP(json_value_add_string_vec) | |
-: 474:# ifdef USE_UCS4 | |
-: 475: module procedure json_value_add_string_name_ascii | |
-: 476: module procedure json_value_add_string_val_ascii | |
-: 477: module procedure json_value_add_string_vec_name_ascii | |
-: 478: module procedure json_value_add_string_vec_val_ascii | |
-: 479:# endif | |
-: 480: end interface json_add | |
-: 481: !************************************************************************************* | |
-: 482: | |
-: 483: !************************************************************************************* | |
-: 484: !> | |
-: 485: ! These are like [[json_add]], except if a child with the same name is | |
-: 486: ! already present, then its value is simply updated. | |
-: 487: ! Note that currently, these only work for scalar variables. | |
-: 488: ! These routines can also change the variable's type (but an error will be | |
-: 489: ! thrown if the existing variable is not a scalar). | |
-: 490: ! | |
-: 491: !@note It should not be used to change the type of a variable in an array, | |
-: 492: ! or it may result in an invalid JSON file. | |
-: 493: | |
-: 494: interface json_update | |
-: 495: module procedure MAYBEWRAP(json_update_logical),& | |
-: 496: MAYBEWRAP(json_update_double),& | |
-: 497: MAYBEWRAP(json_update_integer),& | |
-: 498: MAYBEWRAP(json_update_string) | |
-: 499:# ifdef USE_UCS4 | |
-: 500: module procedure json_update_string_name_ascii | |
-: 501: module procedure json_update_string_val_ascii | |
-: 502:# endif | |
-: 503: end interface json_update | |
-: 504: !************************************************************************************* | |
-: 505: | |
-: 506: !************************************************************************************* | |
-: 507: !> | |
-: 508: ! Get data from a [[json_value]] linked list. | |
-: 509: ! | |
-: 510: !@note There are two versions (e.g. [[json_get_integer]] and [[json_get_integer_with_path]]). | |
-: 511: ! The first one gets the value from the [[json_value]] passed into the routine, | |
-: 512: ! while the second one gets the value from the [[json_value]] found by parsing the | |
-: 513: ! path. The path version is split up into unicode and non-unicode versions. | |
-: 514: | |
-: 515: interface json_get | |
-: 516: module procedure MAYBEWRAP(json_get_by_path) | |
-: 517: module procedure json_get_integer, MAYBEWRAP(json_get_integer_with_path) | |
-: 518: module procedure json_get_integer_vec, MAYBEWRAP(json_get_integer_vec_with_path) | |
-: 519: module procedure json_get_double, MAYBEWRAP(json_get_double_with_path) | |
-: 520: module procedure json_get_double_vec, MAYBEWRAP(json_get_double_vec_with_path) | |
-: 521: module procedure json_get_logical, MAYBEWRAP(json_get_logical_with_path) | |
-: 522: module procedure json_get_logical_vec, MAYBEWRAP(json_get_logical_vec_with_path) | |
-: 523: module procedure json_get_string, MAYBEWRAP(json_get_string_with_path) | |
-: 524: module procedure json_get_string_vec, MAYBEWRAP(json_get_string_vec_with_path) | |
-: 525: module procedure json_get_array, MAYBEWRAP(json_get_array_with_path) | |
-: 526: end interface json_get | |
-: 527: !************************************************************************************* | |
-: 528: | |
-: 529: !************************************************************************************* | |
-: 530: !> | |
-: 531: ! Print the json_value structure to an allocatable string. | |
-: 532: | |
-: 533: interface json_print_to_string | |
-: 534: module procedure json_value_to_string | |
-: 535: end interface | |
-: 536: !************************************************************************************* | |
-: 537: | |
-: 538: !************************************************************************************* | |
-: 539: !> | |
-: 540: ! Print the [[json_value]] to a file. | |
-: 541: ! | |
-: 542: !# Example | |
-: 543: ! | |
-: 544: !```fortran | |
-: 545: ! type(json_value) :: p | |
-: 546: ! !... | |
-: 547: ! call json_print(p,'test.json') !this is [[json_print_2]] | |
-: 548: !``` | |
-: 549: | |
-: 550: interface json_print | |
-: 551: module procedure json_print_1 !input is unit number | |
-: 552: module procedure json_print_2 !input is file name | |
-: 553: end interface | |
-: 554: !************************************************************************************* | |
-: 555: | |
-: 556: !************************************************************************************* | |
-: 557: !> | |
-: 558: ! Destructor routine for a [[json_value]] pointer. | |
-: 559: ! This must be called explicitly if it is no longer needed, | |
-: 560: ! before it goes out of scope. Otherwise, a memory leak will result. | |
-: 561: ! | |
-: 562: !# Example | |
-: 563: ! | |
-: 564: ! Destroy the [[json_value]] pointer before the variable goes out of scope: | |
-: 565: !```fortran | |
-: 566: ! subroutine example1() | |
-: 567: ! type(json_value),pointer :: p | |
-: 568: ! call json_create_object(p,'') | |
-: 569: ! call json_add(p,'year',2015) | |
-: 570: ! call json_print(p) | |
-: 571: ! call json_destroy(p) | |
-: 572: ! end subroutine example1 | |
-: 573: !``` | |
-: 574: ! | |
-: 575: ! Note: it should NOT be called for a [[json_value]] pointer than has already been | |
-: 576: ! added to another [[json_value]] structure, since doing so may render the | |
-: 577: ! other structure invalid. Consider the following example: | |
-: 578: !```fortran | |
-: 579: ! subroutine example2(p) | |
-: 580: ! type(json_value),pointer,intent(out) :: p | |
-: 581: ! type(json_value),pointer :: q | |
-: 582: ! call json_create_object(p,'') | |
-: 583: ! call json_add(p,'year',2015) | |
-: 584: ! call json_create_object(q,'q') | |
-: 585: ! call json_add(q,'val',1) | |
-: 586: ! call json_add(p, q) !add q to p structure | |
-: 587: ! ! do NOT call json_destroy(q) here, because q is | |
-: 588: ! ! now part of the output structure p. p should be destroyed | |
-: 589: ! ! somewhere upstream by the caller of this routine. | |
-: 590: ! nullify(q) !OK, but not strictly necessary | |
-: 591: ! end subroutine example2 | |
-: 592: !``` | |
-: 593: | |
-: 594: interface json_destroy | |
-: 595: module procedure json_value_destroy | |
-: 596: end interface | |
-: 597: !************************************************************************************* | |
-: 598: | |
-: 599: !************************************************************************************* | |
-: 600: !> | |
-: 601: ! Remove a [[json_value]] from a linked-list structure. | |
-: 602: | |
-: 603: interface json_remove | |
-: 604: module procedure json_value_remove | |
-: 605: end interface | |
-: 606: !************************************************************************************* | |
-: 607: | |
-: 608: !************************************************************************************* | |
-: 609: !> | |
-: 610: ! If the child variable is present, then remove it. | |
-: 611: | |
-: 612: interface json_remove_if_present | |
-: 613: module procedure MAYBEWRAP(json_value_remove_if_present) | |
-: 614: end interface | |
-: 615: !************************************************************************************* | |
-: 616: | |
-: 617: !************************************************************************************* | |
-: 618: !> | |
-: 619: ! Allocate a [[json_value]] pointer and make it a double variable. | |
-: 620: ! The pointer should not already be allocated. | |
-: 621: ! | |
-: 622: !# Example | |
-: 623: ! | |
-: 624: !```fortran | |
-: 625: ! type(json_value),pointer :: p | |
-: 626: ! call json_create_double(p,'value',1.0d0) | |
-: 627: !``` | |
-: 628: | |
-: 629: interface json_create_double | |
-: 630: module procedure MAYBEWRAP(json_value_create_double) | |
-: 631: end interface | |
-: 632: !************************************************************************************* | |
-: 633: | |
-: 634: !************************************************************************************* | |
-: 635: !> | |
-: 636: ! Allocate a [[json_value]] pointer and make it an array variable. | |
-: 637: ! The pointer should not already be allocated. | |
-: 638: ! | |
-: 639: !# Example | |
-: 640: ! | |
-: 641: !```fortran | |
-: 642: ! type(json_value),pointer :: p | |
-: 643: ! call json_create(p,'arrayname') | |
-: 644: !``` | |
-: 645: | |
-: 646: interface json_create_array | |
-: 647: module procedure MAYBEWRAP(json_value_create_array) | |
-: 648: end interface | |
-: 649: !************************************************************************************* | |
-: 650: | |
-: 651: !************************************************************************************* | |
-: 652: !> | |
-: 653: ! Allocate a [[json_value]] pointer and make it an object variable. | |
-: 654: ! The pointer should not already be allocated. | |
-: 655: ! | |
-: 656: !# Example | |
-: 657: ! | |
-: 658: !```fortran | |
-: 659: ! type(json_value),pointer :: p | |
-: 660: ! call json_create(p,'objectname') | |
-: 661: !``` | |
-: 662: ! | |
-: 663: !@note The name is not significant for the root structure or an array element. | |
-: 664: ! In those cases, an empty string can be used. | |
-: 665: | |
-: 666: interface json_create_object | |
-: 667: module procedure MAYBEWRAP(json_value_create_object) | |
-: 668: end interface | |
-: 669: !************************************************************************************* | |
-: 670: | |
-: 671: !************************************************************************************* | |
-: 672: !> | |
-: 673: ! Allocate a json_value pointer and make it a null variable. | |
-: 674: ! The pointer should not already be allocated. | |
-: 675: ! | |
-: 676: !# Example | |
-: 677: ! | |
-: 678: !```fortran | |
-: 679: ! type(json_value),pointer :: p | |
-: 680: ! call json_create_null(p,'value') | |
-: 681: !``` | |
-: 682: | |
-: 683: interface json_create_null | |
-: 684: module procedure MAYBEWRAP(json_value_create_null) | |
-: 685: end interface | |
-: 686: !************************************************************************************* | |
-: 687: | |
-: 688: !************************************************************************************* | |
-: 689: !> | |
-: 690: ! Allocate a json_value pointer and make it a string variable. | |
-: 691: ! The pointer should not already be allocated. | |
-: 692: ! | |
-: 693: !# Example | |
-: 694: ! | |
-: 695: !```fortran | |
-: 696: ! type(json_value),pointer :: p | |
-: 697: ! call json_create_string(p,'value','foobar') | |
-: 698: !``` | |
-: 699: | |
-: 700: interface json_create_string | |
-: 701: module procedure MAYBEWRAP(json_value_create_string) | |
-: 702: end interface | |
-: 703: !************************************************************************************* | |
-: 704: | |
-: 705: !************************************************************************************* | |
-: 706: !> | |
-: 707: ! Allocate a json_value pointer and make it an integer variable. | |
-: 708: ! The pointer should not already be allocated. | |
-: 709: ! | |
-: 710: !# Example | |
-: 711: ! | |
-: 712: !```fortran | |
-: 713: ! type(json_value),pointer :: p | |
-: 714: ! call json_create_integer(p,'value',42) | |
-: 715: !``` | |
-: 716: | |
-: 717: interface json_create_integer | |
-: 718: module procedure MAYBEWRAP(json_value_create_integer) | |
-: 719: end interface | |
-: 720: !************************************************************************************* | |
-: 721: | |
-: 722: !************************************************************************************* | |
-: 723: !> | |
-: 724: ! Allocate a json_value pointer and make it a logical variable. | |
-: 725: ! The pointer should not already be allocated. | |
-: 726: ! | |
-: 727: !# Example | |
-: 728: ! | |
-: 729: !```fortran | |
-: 730: ! type(json_value),pointer :: p | |
-: 731: ! call json_create_logical(p,'value',.true.) | |
-: 732: !``` | |
-: 733: | |
-: 734: interface json_create_logical | |
-: 735: module procedure MAYBEWRAP(json_value_create_logical) | |
-: 736: end interface | |
-: 737: !************************************************************************************* | |
-: 738: | |
-: 739: !************************************************************************************* | |
-: 740: !> | |
-: 741: ! Parse the JSON file and populate the [[json_value]] tree. | |
-: 742: | |
-: 743: interface json_parse | |
-: 744: module procedure json_parse_file, MAYBEWRAP(json_parse_string) | |
-: 745: end interface | |
-: 746: !************************************************************************************* | |
-: 747: | |
-: 748: !************************************************************************************* | |
-: 749: !> | |
-: 750: ! Convert a 'DEFAULT' kind character input to 'ISO_10646' kind and return it | |
-: 751: | |
-: 752: interface to_unicode | |
-: 753: module procedure to_uni, to_uni_vec | |
-: 754: end interface | |
-: 755: !************************************************************************************* | |
-: 756: | |
-: 757: !************************************************************************************* | |
-: 758: !> | |
-: 759: ! Throw an exception. | |
-: 760: | |
-: 761: interface throw_exception | |
-: 762: module procedure MAYBEWRAP(json_throw_exception) | |
-: 763: end interface throw_exception | |
-: 764: !************************************************************************************* | |
-: 765: | |
-: 766: !public routines: | |
-: 767: public :: json_add ! add data to a JSON structure | |
-: 768: public :: json_check_for_errors ! check for error and get error message | |
-: 769: public :: json_clear_exceptions ! clear exceptions | |
-: 770: public :: json_count ! count the number of children | |
-: 771: public :: json_create_array ! allocate a json_value array | |
-: 772: public :: json_create_double ! allocate a json_value double | |
-: 773: public :: json_create_integer ! allocate a json_value integer | |
-: 774: public :: json_create_logical ! allocate a json_value logical | |
-: 775: public :: json_create_null ! allocate a json_value null | |
-: 776: public :: json_create_object ! allocate a json_value object | |
-: 777: public :: json_create_string ! allocate a json_value string | |
-: 778: public :: json_destroy ! clear a JSON structure (destructor) | |
-: 779: public :: json_failed ! check for error | |
-: 780: public :: json_get ! get data from the JSON structure | |
-: 781: public :: json_get_child ! get a child of a json_value | |
-: 782: public :: json_info ! get info about a json_value | |
-: 783: public :: json_initialize ! to initialize the module | |
-: 784: public :: json_parse ! read a JSON file and populate the structure | |
-: 785: public :: json_print ! print the JSON structure to a file | |
-: 786: public :: json_print_to_string ! write the JSON structure to a string | |
-: 787: public :: json_remove ! remove from a JSON structure | |
-: 788: public :: json_remove_if_present ! remove from a JSON structure (if it is present) | |
-: 789: public :: json_update ! update a value in a JSON structure | |
-: 790: public :: json_print_error_message ! | |
-: 791: public :: to_unicode ! Function to convert from 'DEFAULT' to 'ISO_10646' strings | |
-: 792: | |
-: 793:# ifdef USE_UCS4 | |
-: 794: public :: operator(//) | |
-: 795: public :: operator(==) | |
-: 796:# endif | |
-: 797: | |
-: 798: character(kind=CDK,len=*),parameter,public :: json_ext = '.json' !! JSON file extension | |
-: 799: | |
-: 800: !special JSON characters | |
-: 801: character(kind=CK,len=*),parameter :: space = ' ' | |
-: 802: character(kind=CK,len=*),parameter :: start_object = '{' | |
-: 803: character(kind=CK,len=*),parameter :: end_object = '}' | |
-: 804: character(kind=CK,len=*),parameter :: start_array = '[' | |
-: 805: character(kind=CK,len=*),parameter :: end_array = ']' | |
-: 806: character(kind=CK,len=*),parameter :: delimiter = ',' | |
-: 807: character(kind=CK,len=*),parameter :: colon_char = ':' | |
-: 808: character(kind=CK,len=*),parameter :: bspace = achar(8) | |
-: 809: character(kind=CK,len=*),parameter :: horizontal_tab = achar(9) | |
-: 810: character(kind=CK,len=*),parameter :: newline = achar(10) | |
-: 811: character(kind=CK,len=*),parameter :: formfeed = achar(12) | |
-: 812: character(kind=CK,len=*),parameter :: carriage_return = achar(13) | |
-: 813: character(kind=CK,len=*),parameter :: quotation_mark = achar(34) | |
-: 814: character(kind=CK,len=*),parameter :: slash = achar(47) | |
-: 815: character(kind=CK,len=*),parameter :: backslash = achar(92) | |
-: 816: | |
-: 817: !These were parameters, but gfortran bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65141) | |
-: 818: !necessitates moving them here to be variables | |
-: 819: character(kind=CK,len=4) :: null_str = 'null' | |
-: 820: character(kind=CK,len=4) :: true_str = 'true' | |
-: 821: character(kind=CK,len=5) :: false_str = 'false' | |
-: 822: | |
-: 823: ! Control characters, possibly in unicode | |
-: 824: integer, private :: i_ | |
-: 825: character(kind=CK,len=*),parameter :: control_chars(32) = [(achar(i_),i_=1,31), achar(127)] | |
-: 826: | |
-: 827: !for indenting (Note: jsonlint.com uses 4 spaces) | |
-: 828: integer(IK),parameter :: spaces_per_tab = 2 | |
-: 829: | |
-: 830: !find out the precision of the floating point number system | |
-: 831: !and set safety factors | |
-: 832: integer(IK),parameter :: rp_safety_factor = 1 | |
-: 833: integer(IK),parameter :: rp_addl_safety = 1 | |
-: 834: integer(IK),parameter :: real_precision = rp_safety_factor*precision(1.0_RK) + & | |
-: 835: rp_addl_safety | |
-: 836: | |
-: 837: !Get the number of possible digits in the exponent when using decimal number system | |
-: 838: integer(IK),parameter :: maxexp = maxexponent(1.0_RK) | |
-: 839: integer(IK),parameter :: minexp = minexponent(1.0_RK) | |
-: 840: integer(IK),parameter :: real_exponent_digits = floor( 1 + log10( & | |
-: 841: real(max(maxexp,abs(maxexp)),& | |
-: 842: kind=RK) ) ) | |
-: 843: | |
-: 844: !6 = sign + leading 0 + decimal + 'E' + exponent sign + 1 extra | |
-: 845: integer(IK),parameter :: max_numeric_str_len = real_precision + real_exponent_digits + 6 | |
-: 846: ! real format set by library initialization | |
-: 847: character(kind=CDK,len=*),parameter :: int_fmt = '(ss,I0)' !minimum width format for integers | |
-: 848: character(kind=CK, len=*),parameter :: star = '*' !for invalid numbers | |
-: 849: | |
-: 850: !real string printing: | |
-: 851: character(kind=CDK,len=:),allocatable :: real_fmt !the format string to use for real numbers | |
-: 852: ! [set in json_initialize] | |
-: 853: logical(LK) :: compact_real = .true. !to use the "compact" form of real numbers for output | |
-: 854: | |
-: 855: ! | |
-: 856: ! Note: the following global variables make this module non thread safe. | |
-: 857: ! | |
-: 858: | |
-: 859: !exception handling [private variables] | |
-: 860: logical(LK) :: is_verbose = .false. !if true, all exceptions are immediately printed to console | |
-: 861: logical(LK) :: exception_thrown = .false. !the error flag | |
-: 862: character(kind=CK,len=:),allocatable :: err_message !the error message | |
-: 863: | |
-: 864: !temp vars used when parsing lines in file [private variables] | |
-: 865: integer(IK) :: char_count = 0 !character position in the current line | |
-: 866: integer(IK) :: line_count = 1 !lines read counter | |
-: 867: integer(IK) :: pushed_index = 0 | |
-: 868: character(kind=CK,len=10) :: pushed_char = '' !JW : what is this magic number 10?? | |
-: 869: | |
-: 870: integer(IK),parameter :: chunk_size = 100 !! for allocatable strings: allocate chunks of this size | |
-: 871: integer(IK) :: ipos = 1 !! for allocatable strings: next character to read | |
-: 872: | |
-: 873: integer(IK),parameter :: unit2str = -1 !! unit number to cause stuff to be | |
-: 874: !! output to strings rather than files. | |
-: 875: !! See 9.5.6.12 in the F2003/08 standard | |
-: 876: | |
-: 877: contains | |
-: 878:!***************************************************************************************** | |
-: 879: | |
-: 880:!***************************************************************************************** | |
-: 881:!> author: Jacob Williams | |
-: 882:! | |
-: 883:! Destroy the data within a [[json_value]], and rest type to json_unknown. | |
-: 884: | |
-: 885: subroutine destroy_json_data(d) | |
777164: 886: | |
-: 887: implicit none | |
-: 888: | |
-: 889: type(json_value),intent(inout) :: d | |
-: 890: | |
-: 891: d%var_type = json_unknown | |
777164: 892: | |
-: 893: if (allocated(d%log_value)) deallocate(d%log_value) | |
777164: 894: if (allocated(d%int_value)) deallocate(d%int_value) | |
777164: 895: if (allocated(d%dbl_value)) deallocate(d%dbl_value) | |
777164: 896: if (allocated(d%str_value)) deallocate(d%str_value) | |
777164: 897: | |
-: 898: end subroutine destroy_json_data | |
777164: 899:!***************************************************************************************** | |
-: 900: | |
-: 901:!***************************************************************************************** | |
-: 902:!> author: Jacob Williams | |
-: 903:! date: 12/9/2013 | |
-: 904:! | |
-: 905:! Destroy the [[json_file]]. | |
-: 906: | |
-: 907: subroutine json_file_destroy(me) | |
11: 908: | |
-: 909: implicit none | |
-: 910: | |
-: 911: class(json_file),intent(inout) :: me | |
-: 912: | |
-: 913: if (associated(me%p)) call json_value_destroy(me%p) | |
11: 914: | |
-: 915: end subroutine json_file_destroy | |
11: 916:!***************************************************************************************** | |
-: 917: | |
-: 918:!***************************************************************************************** | |
-: 919:!> author: Jacob Williams | |
-: 920:! date: 12/5/2014 | |
-: 921:! | |
-: 922:! Move the [[json_value]] pointer from one [[json_file]] to another. | |
-: 923:! The "from" pointer is then nullified, but not destroyed. | |
-: 924:! | |
-: 925:!@note If "from%p" is not associated, then an error is thrown. | |
-: 926: | |
-: 927: subroutine json_file_move_pointer(to,from) | |
1: 928: | |
-: 929: implicit none | |
-: 930: | |
-: 931: class(json_file),intent(inout) :: to | |
-: 932: class(json_file),intent(inout) :: from | |
-: 933: | |
-: 934: if (associated(from%p)) then | |
1: 935: to%p => from%p | |
1: 936: nullify(from%p) | |
1: 937: else | |
-: 938: call throw_exception('Error in json_file_move_pointer: '//& | |
-: 939: 'pointer is not associated.') | |
#####: 940: end if | |
-: 941: | |
-: 942: end subroutine json_file_move_pointer | |
1: 943: | |
-: 944:!***************************************************************************************** | |
-: 945:!> author: Jacob Williams | |
-: 946:! date: 12/9/2013 | |
-: 947:! | |
-: 948:! Load the JSON data from a file. | |
-: 949:! | |
-: 950:!# Example | |
-: 951:! | |
-: 952:!```fortran | |
-: 953:! type(json_file) :: f | |
-: 954:! call f%load_file('my_file.json') | |
-: 955:!``` | |
-: 956: | |
-: 957: subroutine json_file_load(me, filename, unit) | |
10: 958: | |
-: 959: implicit none | |
-: 960: | |
-: 961: class(json_file),intent(inout) :: me | |
-: 962: character(kind=CDK,len=*),intent(in) :: filename !! the filename to open | |
-: 963: integer(IK),intent(in),optional :: unit !! the unit number to use | |
-: 964: | |
-: 965: call json_parse(file=filename, p=me%p, unit=unit) | |
10: 966: | |
-: 967: end subroutine json_file_load | |
20: 968:!***************************************************************************************** | |
-: 969: | |
-: 970:!***************************************************************************************** | |
-: 971:!> author: Jacob Williams | |
-: 972:! date: 1/13/2015 | |
-: 973:! | |
-: 974:! Load the JSON data from a string. | |
-: 975:! | |
-: 976:!# Example | |
-: 977:! | |
-: 978:! Load JSON from a string: | |
-: 979:!```fortran | |
-: 980:! type(json_file) :: f | |
-: 981:! call f%load_from_string('{ "name": "Leonidas" }') | |
-: 982:!``` | |
-: 983: | |
-: 984: subroutine json_file_load_from_string(me, str) | |
3: 985: | |
-: 986: implicit none | |
-: 987: | |
-: 988: class(json_file),intent(inout) :: me | |
-: 989: character(kind=CK,len=*),intent(in) :: str !! string to load JSON data from | |
-: 990: | |
-: 991: call json_parse(str=str, p=me%p) | |
3: 992: | |
-: 993: end subroutine json_file_load_from_string | |
6: 994:!***************************************************************************************** | |
-: 995: | |
-: 996:!***************************************************************************************** | |
-: 997:!> | |
-: 998:! Alternate version of [[json_file_load_from_string]], where "str" is kind=CDK. | |
-: 999: | |
-: 1000: subroutine wrap_json_file_load_from_string(me, str) | |
2: 1001: | |
-: 1002: implicit none | |
-: 1003: | |
-: 1004: class(json_file),intent(inout) :: me | |
-: 1005: character(kind=CDK,len=*),intent(in) :: str | |
-: 1006: | |
-: 1007: call json_file_load_from_string(me,to_unicode(str)) | |
2: 1008: | |
-: 1009: end subroutine wrap_json_file_load_from_string | |
4: 1010:!***************************************************************************************** | |
-: 1011: | |
-: 1012:!***************************************************************************************** | |
-: 1013:!> author: Jacob Williams | |
-: 1014:! date: 1/11/2015 | |
-: 1015:! | |
-: 1016:! Print the JSON file to the console. | |
-: 1017: | |
-: 1018: subroutine json_file_print_to_console(me) | |
4: 1019: | |
-: 1020: implicit none | |
-: 1021: | |
-: 1022: class(json_file),intent(inout) :: me | |
-: 1023: | |
-: 1024: character(kind=CK,len=:),allocatable :: dummy | |
4: 1025: | |
-: 1026: call json_value_print(me%p,iunit=output_unit,str=dummy,indent=1,colon=.true.) | |
4: 1027: | |
-: 1028: end subroutine json_file_print_to_console | |
4: 1029:!***************************************************************************************** | |
-: 1030: | |
-: 1031:!***************************************************************************************** | |
-: 1032:!> author: Jacob Williams | |
-: 1033:! date: 12/9/2013 | |
-: 1034:! | |
-: 1035:! Prints the JSON file to the specified file unit number. | |
-: 1036: | |
-: 1037: subroutine json_file_print_1(me, iunit) | |
4: 1038: | |
-: 1039: implicit none | |
-: 1040: | |
-: 1041: class(json_file),intent(inout) :: me | |
-: 1042: integer(IK),intent(in) :: iunit !! file unit number (must not be -1) | |
-: 1043: | |
-: 1044: integer(IK) :: i | |
-: 1045: character(kind=CK,len=:),allocatable :: dummy | |
4: 1046: | |
-: 1047: if (iunit/=unit2str) then | |
4: 1048: i = iunit | |
4: 1049: call json_value_print(me%p,iunit=i,str=dummy,indent=1,colon=.true.) | |
4: 1050: else | |
-: 1051: call throw_exception('Error in json_file_print_1: iunit must not be -1.') | |
#####: 1052: end if | |
-: 1053: | |
-: 1054: end subroutine json_file_print_1 | |
4: 1055:!***************************************************************************************** | |
-: 1056: | |
-: 1057:!***************************************************************************************** | |
-: 1058:!> author: Jacob Williams | |
-: 1059:! date: 1/11/2015 | |
-: 1060:! | |
-: 1061:! Print the JSON structure to the specified filename. | |
-: 1062:! The file is opened, printed, and then closed. | |
-: 1063:! | |
-: 1064:!# Example | |
-: 1065:! Example loading a JSON file, changing a value, and then printing | |
-: 1066:! result to a new file: | |
-: 1067:!```fortran | |
-: 1068:! type(json_file) :: f | |
-: 1069:! logical :: found | |
-: 1070:! call f%load_file('my_file.json') !open the original file | |
-: 1071:! call f%update('version',4,found) !change the value of a variable | |
-: 1072:! call f%print_file('my_file_2.json') !save file as new name | |
-: 1073:!``` | |
-: 1074: | |
-: 1075: subroutine json_file_print_2(me,filename) | |
2: 1076: | |
-: 1077: implicit none | |
-: 1078: | |
-: 1079: class(json_file),intent(inout) :: me | |
-: 1080: character(kind=CDK,len=*),intent(in) :: filename !! filename to print to | |
-: 1081: | |
-: 1082: integer(IK) :: iunit,istat | |
-: 1083: | |
-: 1084: open(newunit=iunit,file=filename,status='REPLACE',iostat=istat FILE_ENCODING ) | |
2: 1085: if (istat==0) then | |
2: 1086: call me%print_file(iunit) !call the other routine | |
2: 1087: close(iunit,iostat=istat) | |
2: 1088: else | |
-: 1089: call throw_exception('Error in json_file_print_2: could not open file: '//& | |
-: 1090: trim(filename)) | |
#####: 1091: end if | |
-: 1092: | |
-: 1093: end subroutine json_file_print_2 | |
4: 1094:!***************************************************************************************** | |
-: 1095: | |
-: 1096:!***************************************************************************************** | |
-: 1097:!> author: Jacob Williams | |
-: 1098:! date: 1/11/2015 | |
-: 1099:! | |
-: 1100:! Print the JSON file to a string. | |
-: 1101:! | |
-: 1102:!# Example | |
-: 1103:! | |
-: 1104:! Open a JSON file, and then print the contents to a string: | |
-: 1105:!```fortran | |
-: 1106:! type(json_file) :: f | |
-: 1107:! character(kind=CK,len=:),allocatable :: str | |
-: 1108:! call f%load_file('my_file.json') | |
-: 1109:! call f%print_file(str) | |
-: 1110:!``` | |
-: 1111: | |
-: 1112: subroutine json_file_print_to_string(me,str) | |
3: 1113: | |
-: 1114: implicit none | |
-: 1115: | |
-: 1116: class(json_file),intent(inout) :: me | |
-: 1117: character(kind=CK,len=:),allocatable,intent(out) :: str !! string to print JSON data to | |
-: 1118: | |
-: 1119: call json_value_to_string(me%p,str) | |
3: 1120: | |
-: 1121: end subroutine json_file_print_to_string | |
3: 1122:!***************************************************************************************** | |
-: 1123: | |
-: 1124:!***************************************************************************************** | |
-: 1125:!> author: Jacob Williams | |
-: 1126:! date: 2/3/2014 | |
-: 1127:! | |
-: 1128:! Returns information about a variable in a [[json_file]]. | |
-: 1129: | |
-: 1130: subroutine json_file_variable_info(me,path,found,var_type,n_children) | |
1: 1131: | |
-: 1132: implicit none | |
-: 1133: | |
-: 1134: class(json_file),intent(inout) :: me | |
-: 1135: character(kind=CK,len=*),intent(in) :: path !! path to the variable | |
-: 1136: logical(LK),intent(out) :: found !! the variable exists in the structure | |
-: 1137: integer(IK),intent(out) :: var_type !! variable type | |
-: 1138: integer(IK),intent(out) :: n_children !! number of children | |
-: 1139: | |
-: 1140: type(json_value),pointer :: p | |
-: 1141: | |
-: 1142: !initialize: | |
-: 1143: nullify(p) | |
1: 1144: | |
-: 1145: !get a pointer to the variable (if it is there): | |
-: 1146: call me%get(path,p,found) | |
1: 1147: | |
-: 1148: if (found) then | |
1: 1149: | |
-: 1150: !get info: | |
-: 1151: call json_info(p,var_type,n_children) | |
1: 1152: | |
-: 1153: else | |
-: 1154: | |
-: 1155: !set to dummy values: | |
-: 1156: var_type = json_unknown | |
#####: 1157: n_children = 0 | |
#####: 1158: | |
-: 1159: end if | |
-: 1160: | |
-: 1161: !cleanup: | |
-: 1162: nullify(p) | |
1: 1163: | |
-: 1164: end subroutine json_file_variable_info | |
2: 1165:!***************************************************************************************** | |
-: 1166: | |
-: 1167:!***************************************************************************************** | |
-: 1168:!> | |
-: 1169:! Alternate version of [[json_file_variable_info]], where "path" is kind=CDK. | |
-: 1170: | |
-: 1171: subroutine wrap_json_file_variable_info(me,path,found,var_type,n_children) | |
1: 1172: | |
-: 1173: implicit none | |
-: 1174: | |
-: 1175: class(json_file),intent(inout) :: me | |
-: 1176: character(kind=CDK,len=*),intent(in) :: path | |
-: 1177: logical(LK),intent(out) :: found | |
-: 1178: integer(IK),intent(out) :: var_type | |
-: 1179: integer(IK),intent(out) :: n_children | |
-: 1180: | |
-: 1181: call json_file_variable_info(me,to_unicode(path),found,var_type,n_children) | |
1: 1182: | |
-: 1183: end subroutine wrap_json_file_variable_info | |
2: 1184:!***************************************************************************************** | |
-: 1185: | |
-: 1186:!***************************************************************************************** | |
-: 1187:!> author: Jacob Williams | |
-: 1188:! date: 2/13/2014 | |
-: 1189:! | |
-: 1190:! Returns information about a [[json_value]]. | |
-: 1191: | |
-: 1192: subroutine json_info(p,var_type,n_children) | |
9: 1193: | |
-: 1194: implicit none | |
-: 1195: | |
-: 1196: type(json_value),pointer :: p | |
-: 1197: integer(IK),intent(out),optional :: var_type !! variable type | |
-: 1198: integer(IK),intent(out),optional :: n_children !! number of children | |
-: 1199: | |
-: 1200: if (present(var_type)) var_type = p%var_type !variable type | |
9: 1201: if (present(n_children)) n_children = json_count(p) !number of children | |
9: 1202: | |
-: 1203: end subroutine json_info | |
9: 1204:!***************************************************************************************** | |
-: 1205: | |
-: 1206:!***************************************************************************************** | |
-: 1207:!> author: Jacob Williams | |
-: 1208:! date: 2/3/2014 | |
-: 1209:! | |
-: 1210:! Get a [[json_value]] pointer to an object from a JSON file. | |
-: 1211: | |
-: 1212: subroutine json_file_get_object(me, path, p, found) | |
6: 1213: | |
-: 1214: implicit none | |
-: 1215: | |
-: 1216: class(json_file),intent(inout) :: me | |
-: 1217: character(kind=CK,len=*),intent(in) :: path !! the path to the variable | |
-: 1218: type(json_value),pointer,intent(out) :: p !! pointer to the variable | |
-: 1219: logical(LK),intent(out),optional :: found !! if it was really found | |
-: 1220: | |
-: 1221: call json_get_by_path(me%p, path=path, p=p, found=found) | |
6: 1222: | |
-: 1223: end subroutine json_file_get_object | |
12: 1224:!***************************************************************************************** | |
-: 1225: | |
-: 1226:!***************************************************************************************** | |
-: 1227:!> | |
-: 1228:! Alternate version of [[json_file_get_object]], where "path" is kind=CDK. | |
-: 1229: | |
-: 1230: subroutine wrap_json_file_get_object(me, path, p, found) | |
5: 1231: | |
-: 1232: implicit none | |
-: 1233: | |
-: 1234: class(json_file),intent(inout) :: me | |
-: 1235: character(kind=CDK,len=*),intent(in) :: path | |
-: 1236: type(json_value),pointer,intent(out) :: p | |
-: 1237: logical(LK),intent(out),optional :: found | |
-: 1238: | |
-: 1239: call json_file_get_object(me, to_unicode(path), p, found) | |
5: 1240: | |
-: 1241: end subroutine wrap_json_file_get_object | |
10: 1242:!***************************************************************************************** | |
-: 1243: | |
-: 1244:!***************************************************************************************** | |
-: 1245:!> author: Jacob Williams | |
-: 1246:! date: 12/9/2013 | |
-: 1247:! | |
-: 1248:! Get an integer value from a JSON file. | |
-: 1249: | |
-: 1250: subroutine json_file_get_integer(me, path, val, found) | |
4: 1251: | |
-: 1252: implicit none | |
-: 1253: | |
-: 1254: class(json_file),intent(inout) :: me | |
-: 1255: character(kind=CK,len=*),intent(in) :: path !! the path to the variable | |
-: 1256: integer(IK),intent(out) :: val !! value | |
-: 1257: logical(LK),intent(out),optional :: found !! if it was really found | |
-: 1258: | |
-: 1259: call json_get(me%p, path=path, value=val, found=found) | |
4: 1260: | |
-: 1261: end subroutine json_file_get_integer | |
8: 1262:!***************************************************************************************** | |
-: 1263: | |
-: 1264:!***************************************************************************************** | |
-: 1265:!> | |
-: 1266:! Alternate version of [[json_file_get_integer]], where "path" is kind=CDK. | |
-: 1267: | |
-: 1268: subroutine wrap_json_file_get_integer(me, path, val, found) | |
4: 1269: | |
-: 1270: implicit none | |
-: 1271: | |
-: 1272: class(json_file),intent(inout) :: me | |
-: 1273: character(kind=CDK,len=*),intent(in) :: path | |
-: 1274: integer(IK),intent(out) :: val | |
-: 1275: logical(LK),intent(out),optional :: found | |
-: 1276: | |
-: 1277: call json_file_get_integer(me, to_unicode(path), val, found) | |
4: 1278: | |
-: 1279: end subroutine wrap_json_file_get_integer | |
8: 1280:!***************************************************************************************** | |
-: 1281: | |
-: 1282:!***************************************************************************************** | |
-: 1283:!> author: Jacob Williams | |
-: 1284:! date: 1/20/2014 | |
-: 1285:! | |
-: 1286:! Get an integer vector from a JSON file. | |
-: 1287: | |
-: 1288: subroutine json_file_get_integer_vec(me, path, vec, found) | |
1: 1289: | |
-: 1290: implicit none | |
-: 1291: | |
-: 1292: class(json_file),intent(inout) :: me | |
-: 1293: character(kind=CK,len=*),intent(in) :: path !! the path to the variable | |
-: 1294: integer(IK),dimension(:),allocatable,intent(out) :: vec !! the value vector | |
-: 1295: logical(LK),intent(out),optional :: found !! if it was really found | |
-: 1296: | |
-: 1297: call json_get(me%p, path, vec, found) | |
1: 1298: | |
-: 1299: end subroutine json_file_get_integer_vec | |
2: 1300:!***************************************************************************************** | |
-: 1301: | |
-: 1302:!***************************************************************************************** | |
-: 1303:!> | |
-: 1304:! Alternate version of [[json_file_get_integer_vec]], where "path" is kind=CDK. | |
-: 1305: | |
-: 1306: subroutine wrap_json_file_get_integer_vec(me, path, vec, found) | |
1: 1307: | |
-: 1308: implicit none | |
-: 1309: | |
-: 1310: class(json_file),intent(inout) :: me | |
-: 1311: character(kind=CDK,len=*),intent(in) :: path | |
-: 1312: integer(IK),dimension(:),allocatable,intent(out) :: vec | |
-: 1313: logical(LK),intent(out),optional :: found | |
-: 1314: | |
-: 1315: call json_file_get_integer_vec(me, to_unicode(path), vec, found) | |
1: 1316: | |
-: 1317: end subroutine wrap_json_file_get_integer_vec | |
2: 1318:!***************************************************************************************** | |
-: 1319: | |
-: 1320:!***************************************************************************************** | |
-: 1321:!> author: Jacob Williams | |
-: 1322:! date: 12/9/2013 | |
-: 1323:! | |
-: 1324:! Get a real(RK) variable value from a JSON file. | |
-: 1325: | |
-: 1326: subroutine json_file_get_double (me, path, val, found) | |
3: 1327: | |
-: 1328: implicit none | |
-: 1329: | |
-: 1330: class(json_file),intent(inout) :: me | |
-: 1331: character(kind=CK,len=*),intent(in) :: path | |
-: 1332: real(RK),intent(out) :: val | |
-: 1333: logical(LK),intent(out),optional :: found | |
-: 1334: | |
-: 1335: call json_get(me%p, path=path, value=val, found=found) | |
3: 1336: | |
-: 1337: end subroutine json_file_get_double | |
6: 1338:!***************************************************************************************** | |
-: 1339: | |
-: 1340:!***************************************************************************************** | |
-: 1341:!> | |
-: 1342:! Alternate version of [[json_file_get_double]], where "path" is kind=CDK. | |
-: 1343: | |
-: 1344: subroutine wrap_json_file_get_double (me, path, val, found) | |
3: 1345: | |
-: 1346: implicit none | |
-: 1347: | |
-: 1348: class(json_file),intent(inout) :: me | |
-: 1349: character(kind=CDK,len=*),intent(in) :: path | |
-: 1350: real(RK),intent(out) :: val | |
-: 1351: logical(LK),intent(out),optional :: found | |
-: 1352: | |
-: 1353: call json_file_get_double(me, to_unicode(path), val, found) | |
3: 1354: | |
-: 1355: end subroutine wrap_json_file_get_double | |
6: 1356:!***************************************************************************************** | |
-: 1357: | |
-: 1358:!***************************************************************************************** | |
-: 1359:!> author: Jacob Williams | |
-: 1360:! date: 1/19/2014 | |
-: 1361:! | |
-: 1362:! Get a real(RK) vector from a JSON file. | |
-: 1363: | |
-: 1364: subroutine json_file_get_double_vec(me, path, vec, found) | |
4: 1365: | |
-: 1366: implicit none | |
-: 1367: | |
-: 1368: class(json_file),intent(inout) :: me | |
-: 1369: character(kind=CK,len=*),intent(in) :: path | |
-: 1370: real(RK),dimension(:),allocatable,intent(out) :: vec | |
-: 1371: logical(LK),intent(out),optional :: found | |
-: 1372: | |
-: 1373: call json_get(me%p, path, vec, found) | |
4: 1374: | |
-: 1375: end subroutine json_file_get_double_vec | |
8: 1376:!***************************************************************************************** | |
-: 1377: | |
-: 1378:!***************************************************************************************** | |
-: 1379:!> | |
-: 1380:! Alternate version of [[json_file_get_double_vec]], where "path" is kind=CDK. | |
-: 1381: | |
-: 1382: subroutine wrap_json_file_get_double_vec(me, path, vec, found) | |
#####: 1383: | |
-: 1384: implicit none | |
-: 1385: | |
-: 1386: class(json_file),intent(inout) :: me | |
-: 1387: character(kind=CDK,len=*),intent(in) :: path | |
-: 1388: real(RK),dimension(:),allocatable,intent(out) :: vec | |
-: 1389: logical(LK),intent(out),optional :: found | |
-: 1390: | |
-: 1391: call json_file_get_double_vec(me, to_unicode(path), vec, found) | |
#####: 1392: | |
-: 1393: end subroutine wrap_json_file_get_double_vec | |
#####: 1394:!***************************************************************************************** | |
-: 1395: | |
-: 1396:!***************************************************************************************** | |
-: 1397:!> author: Jacob Williams | |
-: 1398:! date: 12/9/2013 | |
-: 1399:! | |
-: 1400:! Get a logical(LK) value from a JSON file. | |
-: 1401: | |
-: 1402: subroutine json_file_get_logical(me,path,val,found) | |
1: 1403: | |
-: 1404: implicit none | |
-: 1405: | |
-: 1406: class(json_file),intent(inout) :: me | |
-: 1407: character(kind=CK,len=*),intent(in) :: path | |
-: 1408: logical(LK),intent(out) :: val | |
-: 1409: logical(LK),intent(out),optional :: found | |
-: 1410: | |
-: 1411: call json_get(me%p, path=path, value=val, found=found) | |
1: 1412: | |
-: 1413: end subroutine json_file_get_logical | |
2: 1414:!***************************************************************************************** | |
-: 1415: | |
-: 1416:!***************************************************************************************** | |
-: 1417:!> | |
-: 1418:! Alternate version of [[json_file_get_logical]], where "path" is kind=CDK. | |
-: 1419: | |
-: 1420: subroutine wrap_json_file_get_logical(me,path,val,found) | |
1: 1421: | |
-: 1422: implicit none | |
-: 1423: | |
-: 1424: class(json_file),intent(inout) :: me | |
-: 1425: character(kind=CDK,len=*),intent(in) :: path | |
-: 1426: logical(LK),intent(out) :: val | |
-: 1427: logical(LK),intent(out),optional :: found | |
-: 1428: | |
-: 1429: call json_file_get_logical(me, to_unicode(path), val, found) | |
1: 1430: | |
-: 1431: end subroutine wrap_json_file_get_logical | |
2: 1432:!***************************************************************************************** | |
-: 1433: | |
-: 1434:!***************************************************************************************** | |
-: 1435:!> author: Jacob Williams | |
-: 1436:! date: 1/20/2014 | |
-: 1437:! | |
-: 1438:! Get a logical(LK) vector from a JSON file. | |
-: 1439: | |
-: 1440: subroutine json_file_get_logical_vec(me, path, vec, found) | |
#####: 1441: | |
-: 1442: implicit none | |
-: 1443: | |
-: 1444: class(json_file),intent(inout) :: me | |
-: 1445: character(kind=CK,len=*),intent(in) :: path | |
-: 1446: logical(LK),dimension(:),allocatable,intent(out) :: vec | |
-: 1447: logical(LK),intent(out),optional :: found | |
-: 1448: | |
-: 1449: call json_get(me%p, path, vec, found) | |
#####: 1450: | |
-: 1451: end subroutine json_file_get_logical_vec | |
#####: 1452:!***************************************************************************************** | |
-: 1453: | |
-: 1454:!***************************************************************************************** | |
-: 1455:!> | |
-: 1456:! Alternate version of [[json_file_get_logical_vec]], where "path" is kind=CDK. | |
-: 1457: | |
-: 1458: subroutine wrap_json_file_get_logical_vec(me, path, vec, found) | |
#####: 1459: | |
-: 1460: implicit none | |
-: 1461: | |
-: 1462: class(json_file),intent(inout) :: me | |
-: 1463: character(kind=CDK,len=*),intent(in) :: path | |
-: 1464: logical(LK),dimension(:),allocatable,intent(out) :: vec | |
-: 1465: logical(LK),intent(out),optional :: found | |
-: 1466: | |
-: 1467: call json_file_get_logical_vec(me, to_unicode(path), vec, found) | |
#####: 1468: | |
-: 1469: end subroutine wrap_json_file_get_logical_vec | |
#####: 1470:!***************************************************************************************** | |
-: 1471: | |
-: 1472:!***************************************************************************************** | |
-: 1473:!> author: Jacob Williams | |
-: 1474:! date: 12/9/2013 | |
-: 1475:! | |
-: 1476:! Get a character string from a json file. | |
-: 1477:! The output val is an allocatable character string. | |
-: 1478: | |
-: 1479: subroutine json_file_get_string(me, path, val, found) | |
46: 1480: | |
-: 1481: implicit none | |
-: 1482: | |
-: 1483: class(json_file),intent(inout) :: me | |
-: 1484: character(kind=CK,len=*),intent(in) :: path | |
-: 1485: character(kind=CK,len=:),allocatable,intent(out) :: val | |
-: 1486: logical(LK),intent(out),optional :: found | |
-: 1487: | |
-: 1488: call json_get(me%p, path=path, value=val, found=found) | |
23: 1489: | |
-: 1490: end subroutine json_file_get_string | |
46: 1491:!***************************************************************************************** | |
-: 1492: | |
-: 1493:!***************************************************************************************** | |
-: 1494:!> | |
-: 1495:! Alternate version of [[json_file_get_string]], where "path" is kind=CDK. | |
-: 1496: | |
-: 1497: subroutine wrap_json_file_get_string(me, path, val, found) | |
38: 1498: | |
-: 1499: implicit none | |
-: 1500: | |
-: 1501: class(json_file),intent(inout) :: me | |
-: 1502: character(kind=CDK,len=*),intent(in) :: path | |
-: 1503: character(kind=CK,len=:),allocatable,intent(out) :: val | |
-: 1504: logical(LK),intent(out),optional :: found | |
-: 1505: | |
-: 1506: call json_file_get_string(me, to_unicode(path), val, found) | |
19: 1507: | |
-: 1508: end subroutine wrap_json_file_get_string | |
38: 1509:!***************************************************************************************** | |
-: 1510: | |
-: 1511:!***************************************************************************************** | |
-: 1512:!> author: Jacob Williams | |
-: 1513:! date: 1/19/2014 | |
-: 1514:! | |
-: 1515:! Get a string vector from a JSON file. | |
-: 1516: | |
-: 1517: subroutine json_file_get_string_vec(me, path, vec, found) | |
1: 1518: | |
-: 1519: implicit none | |
-: 1520: | |
-: 1521: class(json_file),intent(inout) :: me | |
-: 1522: character(kind=CK,len=*),intent(in) :: path | |
-: 1523: character(kind=CK,len=*),dimension(:),allocatable,intent(out) :: vec | |
-: 1524: logical(LK),intent(out),optional :: found | |
-: 1525: | |
-: 1526: call json_get(me%p, path, vec, found) | |
1: 1527: | |
-: 1528: end subroutine json_file_get_string_vec | |
2: 1529:!***************************************************************************************** | |
-: 1530: | |
-: 1531:!***************************************************************************************** | |
-: 1532:!> | |
-: 1533:! Alternate version of [[json_file_get_string_vec]], where "path" is kind=CDK. | |
-: 1534: | |
-: 1535: subroutine wrap_json_file_get_string_vec(me, path, vec, found) | |
1: 1536: | |
-: 1537: implicit none | |
-: 1538: | |
-: 1539: class(json_file),intent(inout) :: me | |
-: 1540: character(kind=CDK,len=*),intent(in) :: path | |
-: 1541: character(kind=CK,len=*),dimension(:),allocatable,intent(out) :: vec | |
-: 1542: logical(LK),intent(out),optional :: found | |
-: 1543: | |
-: 1544: call json_file_get_string_vec(me, to_unicode(path), vec, found) | |
1: 1545: | |
-: 1546: end subroutine wrap_json_file_get_string_vec | |
2: 1547:!***************************************************************************************** | |
-: 1548: | |
-: 1549:!***************************************************************************************** | |
-: 1550:!> author: Jacob Williams | |
-: 1551:! date: 12/4/2013 | |
-: 1552:! | |
-: 1553:! Initialize the JSON-Fortran module. | |
-: 1554:! The routine must be called before any of the routines are used. | |
-: 1555:! It can also be called after using the module and encountering exceptions. | |
-: 1556:! | |
-: 1557:!# Modified | |
-: 1558:! * Izaak Beekman : 02/24/2015 | |
-: 1559: | |
-: 1560: subroutine json_initialize(verbose,compact_reals,print_signs,real_format) | |
27: 1561: | |
-: 1562: implicit none | |
-: 1563: | |
-: 1564: logical(LK),intent(in),optional :: verbose !! mainly useful for debugging (default is false) | |
-: 1565: logical(LK),intent(in),optional :: compact_reals !! to compact the real number strings for output | |
-: 1566: logical(LK),intent(in),optional :: print_signs !! always print numeric sign (default is false) | |
-: 1567: character(len=*,kind=CDK),intent(in),optional :: real_format | |
-: 1568: !! exponential (default), scientific, engineering or general | |
-: 1569: | |
-: 1570: character(kind=CDK,len=10) :: w,d,e | |
-: 1571: character(kind=CDK,len=2) :: sgn, rl_edit_desc | |
-: 1572: integer(IK) :: istat | |
-: 1573: logical(LK) :: sgn_prnt | |
-: 1574: | |
-: 1575: | |
-: 1576: !clear any errors from previous runs: | |
-: 1577: call json_clear_exceptions() | |
27: 1578: | |
-: 1579: !set defaults | |
-: 1580: sgn_prnt = .false. | |
27: 1581: if ( present( print_signs) ) sgn_prnt = print_signs | |
27: 1582: if ( sgn_prnt ) then | |
27: 1583: sgn = 'sp' | |
#####: 1584: else | |
-: 1585: sgn = 'ss' | |
27: 1586: end if | |
-: 1587: | |
-: 1588: rl_edit_desc = 'E' | |
27: 1589: if ( present( real_format ) ) then | |
27: 1590: select case ( real_format ) | |
-: 1591: case ('g','G','e','E','en','EN','es','ES') | |
-: 1592: rl_edit_desc = real_format | |
#####: 1593: case default | |
-: 1594: call throw_exception('Invalid real format, "' // trim(real_format) // '", passed to json_initialize.'// & | |
-: 1595: new_line('a') // 'Acceptable formats are: "G", "E", "EN", and "ES".' ) | |
#####: 1596: end select | |
-: 1597: end if | |
-: 1598: | |
-: 1599:# ifdef USE_UCS4 | |
-: 1600: ! reopen stdout and stderr with utf-8 encoding | |
-: 1601: open(output_unit,encoding='utf-8') | |
27: 1602: open(error_unit, encoding='utf-8') | |
27: 1603:# endif | |
-: 1604: | |
-: 1605: !Ensure gfortran bug work around "parameters" are set properly | |
-: 1606: null_str = 'null' | |
27: 1607: true_str = 'true' | |
27: 1608: false_str = 'false' | |
27: 1609: | |
-: 1610: !optional inputs (if not present, values remains unchanged): | |
-: 1611: if (present(verbose)) is_verbose = verbose | |
27: 1612: if (present(compact_reals)) compact_real = compact_reals | |
27: 1613: | |
-: 1614: ! set the default output/input format for reals: | |
-: 1615: ! [this only needs to be done once, since it can't change] | |
-: 1616: if (.not. allocated(real_fmt)) then | |
27: 1617: write(w,'(ss,I0)',iostat=istat) max_numeric_str_len | |
11: 1618: if (istat==0) write(d,'(ss,I0)',iostat=istat) real_precision | |
11: 1619: if (istat==0) write(e,'(ss,I0)',iostat=istat) real_exponent_digits | |
11: 1620: if (istat==0) then | |
11: 1621: real_fmt = '(' // sgn // ',' // trim(rl_edit_desc) // trim(w) // '.' // trim(d) // 'E' // trim(e) // ')' | |
11: 1622: else | |
-: 1623: real_fmt = '(' // sgn // ',' // trim(rl_edit_desc) // '30.16E3)' !just use this one (should never happen) | |
#####: 1624: end if | |
-: 1625: end if | |
-: 1626: | |
-: 1627: !Just in case, clear these global variables also: | |
-: 1628: pushed_index = 0 | |
27: 1629: pushed_char = '' | |
27: 1630: char_count = 0 | |
27: 1631: line_count = 1 | |
27: 1632: ipos = 1 | |
27: 1633: | |
-: 1634: end subroutine json_initialize | |
54: 1635:!***************************************************************************************** | |
-: 1636: | |
-: 1637:!***************************************************************************************** | |
-: 1638:!> author: Jacob Williams | |
-: 1639:! date: 12/4/2013 | |
-: 1640:! | |
-: 1641:! Clear exceptions in the JSON module. | |
-: 1642: | |
-: 1643: subroutine json_clear_exceptions() | |
35: 1644: | |
-: 1645: implicit none | |
-: 1646: | |
-: 1647: !clear the flag and message: | |
-: 1648: exception_thrown = .false. | |
35: 1649: err_message = '' | |
35: 1650: | |
-: 1651: end subroutine json_clear_exceptions | |
35: 1652:!***************************************************************************************** | |
-: 1653: | |
-: 1654:!***************************************************************************************** | |
-: 1655:!> author: Jacob Williams | |
-: 1656:! date: 12/4/2013 | |
-: 1657:! | |
-: 1658:! Throw an exception in the JSON module. | |
-: 1659:! This routine sets the error flag, and prevents any subsequent routine | |
-: 1660:! from doing anything, until [[json_clear_exceptions]] is called. | |
-: 1661: | |
-: 1662: subroutine json_throw_exception(msg) | |
14: 1663: | |
-: 1664: implicit none | |
-: 1665: | |
-: 1666: character(kind=CK,len=*),intent(in) :: msg !the error message | |
-: 1667: | |
-: 1668: exception_thrown = .true. | |
14: 1669: err_message = trim(msg) | |
14: 1670: | |
-: 1671: if (is_verbose) then | |
14: 1672: write(*,'(A)') '***********************' | |
#####: 1673: write(*,'(A)') 'JSON-Fortran EXCEPTION: '//trim(msg) | |
#####: 1674: !call backtrace() ! gfortran (use -fbacktrace -fall-intrinsics flags) | |
-: 1675: !call tracebackqq(-1) ! intel (requires "use ifcore" in this routine) | |
-: 1676: write(*,'(A)') '***********************' | |
#####: 1677: end if | |
-: 1678: | |
-: 1679: end subroutine json_throw_exception | |
28: 1680:!***************************************************************************************** | |
-: 1681: | |
-: 1682:!***************************************************************************************** | |
-: 1683:!> | |
-: 1684:! Alternate version of [[json_throw_exception]], where "msg" is kind=CDK. | |
-: 1685: | |
-: 1686: subroutine wrap_json_throw_exception(msg) | |
3: 1687: | |
-: 1688: implicit none | |
-: 1689: | |
-: 1690: character(kind=CDK,len=*),intent(in) :: msg !the error message | |
-: 1691: | |
-: 1692: call json_throw_exception(to_unicode(msg)) | |
3: 1693: | |
-: 1694: end subroutine wrap_json_throw_exception | |
6: 1695:!***************************************************************************************** | |
-: 1696: | |
-: 1697:!***************************************************************************************** | |
-: 1698:!> author: Jacob Williams | |
-: 1699:! date: 12/4/2013 | |
-: 1700:! | |
-: 1701:! Retrieve error code from the module. | |
-: 1702:! This should be called after [[json_parse]] to check for errors. | |
-: 1703:! If an error is thrown, before using the module again, [[json_initialize]] | |
-: 1704:! should be called to clean up before it is used again. | |
-: 1705:! | |
-: 1706:!# Example | |
-: 1707:! | |
-: 1708:!```fortran | |
-: 1709:! type(json_file) :: json | |
-: 1710:! logical :: status_ok | |
-: 1711:! character(kind=CK,len=:),allocatable :: error_msg | |
-: 1712:! call json%load_file(filename='myfile.json') | |
-: 1713:! call json_check_for_errors(status_ok, error_msg) | |
-: 1714:! if (.not. status_ok) then | |
-: 1715:! write(*,*) 'Error: '//error_msg | |
-: 1716:! call json_clear_exceptions() | |
-: 1717:! call json%destroy() | |
-: 1718:! end if | |
-: 1719:!``` | |
-: 1720:! | |
-: 1721:!# See also | |
-: 1722:! * [[json_failed]] | |
-: 1723: | |
-: 1724: subroutine json_check_for_errors(status_ok, error_msg) | |
3: 1725: | |
-: 1726: implicit none | |
-: 1727: | |
-: 1728: logical(LK),intent(out) :: status_ok !! true if there were no errors | |
-: 1729: character(kind=CK,len=:),allocatable,intent(out) :: error_msg !! the error message (if there were errors) | |
-: 1730: | |
-: 1731: status_ok = .not. exception_thrown | |
3: 1732: | |
-: 1733: if (.not. status_ok) then | |
3: 1734: if (allocated(err_message)) then | |
3: 1735: error_msg = err_message | |
3: 1736: else | |
-: 1737: error_msg = 'Unknown Error' | |
#####: 1738: end if | |
-: 1739: else | |
-: 1740: error_msg = '' | |
#####: 1741: end if | |
-: 1742: | |
-: 1743: end subroutine json_check_for_errors | |
3: 1744:!***************************************************************************************** | |
-: 1745: | |
-: 1746:!***************************************************************************************** | |
-: 1747:!> author: Jacob Williams | |
-: 1748:! date: 12/5/2013 | |
-: 1749:! | |
-: 1750:! Logical function to indicate if an exception has been thrown. | |
-: 1751:! | |
-: 1752:!# Example | |
-: 1753:! | |
-: 1754:!```fortran | |
-: 1755:! type(json_file) :: json | |
-: 1756:! logical :: status_ok | |
-: 1757:! character(len=:),allocatable :: error_msg | |
-: 1758:! call json%load_file(filename='myfile.json') | |
-: 1759:! if (json_failed()) then | |
-: 1760:! call json_check_for_errors(status_ok, error_msg) | |
-: 1761:! write(*,*) 'Error: '//error_msg | |
-: 1762:! call json_clear_exceptions() | |
-: 1763:! call json%destroy() | |
-: 1764:! end if | |
-: 1765:!``` | |
-: 1766:! | |
-: 1767:!# See also | |
-: 1768:! * [[json_check_for_errors]] | |
-: 1769:! | |
-: 1770: function json_failed() result(failed) | |
302: 1771: | |
-: 1772: implicit none | |
-: 1773: | |
-: 1774: logical(LK) :: failed | |
-: 1775: | |
-: 1776: failed = exception_thrown | |
302: 1777: | |
-: 1778: end function json_failed | |
302: 1779:!***************************************************************************************** | |
-: 1780: | |
-: 1781:!***************************************************************************************** | |
-: 1782:!> | |
-: 1783:! Allocate a [[json_value]] pointer variable. | |
-: 1784:! This should be called before adding data to it. | |
-: 1785:! | |
-: 1786:!# Example | |
-: 1787:! | |
-: 1788:!```fortran | |
-: 1789:! type(json_value),pointer :: var | |
-: 1790:! call json_value_create(var) | |
-: 1791:! call to_double(var,1.0d0) | |
-: 1792:!``` | |
-: 1793:! | |
-: 1794:!# Notes | |
-: 1795:! 1. This routine does not check for exceptions. | |
-: 1796:! 2. The pointer should not already be allocated. | |
-: 1797: | |
-: 1798: subroutine json_value_create(p) | |
388584: 1799: | |
-: 1800: implicit none | |
-: 1801: | |
-: 1802: type(json_value),pointer :: p | |
-: 1803: | |
-: 1804: nullify(p) | |
388584: 1805: allocate(p) | |
388584: 1806: | |
-: 1807: end subroutine json_value_create | |
388584: 1808:!***************************************************************************************** | |
-: 1809: | |
-: 1810:!***************************************************************************************** | |
-: 1811:!> author: Jacob Williams | |
-: 1812:! date: 1/22/2014 | |
-: 1813:! | |
-: 1814:! Destroy a [[json_value]] linked-list structure. | |
-: 1815:! | |
-: 1816:!@note The original FSON version of this | |
-: 1817:! routine was not properly freeing the memory. | |
-: 1818:! It was rewritten. | |
-: 1819: | |
-: 1820: recursive subroutine json_value_destroy(me,destroy_next) | |
388577: 1821: | |
-: 1822: implicit none | |
-: 1823: | |
-: 1824: type(json_value),pointer :: me | |
-: 1825: logical(LK),intent(in),optional :: destroy_next !! if true, then me%next is also destroyed (default is true) | |
-: 1826: | |
-: 1827: logical(LK) :: des_next | |
-: 1828: type(json_value), pointer :: p | |
-: 1829: | |
-: 1830: if (associated(me)) then | |
388577: 1831: | |
-: 1832: if (present(destroy_next)) then | |
388577: 1833: des_next = destroy_next | |
388547: 1834: else | |
-: 1835: des_next = .true. | |
30: 1836: end if | |
-: 1837: | |
-: 1838: if (allocated(me%name)) deallocate(me%name) | |
388577: 1839: | |
-: 1840: call destroy_json_data(me) | |
388577: 1841: | |
-: 1842: if (associated(me%children)) then | |
388577: 1843: do while (me%n_children > 0) | |
836881: 1844: p => me%children | |
388547: 1845: me%children => me%children%next | |
388547: 1846: me%n_children = me%n_children - 1 | |
388547: 1847: call json_value_destroy(p,.false.) | |
388547: 1848: end do | |
-: 1849: nullify(me%children) | |
59787: 1850: nullify(p) | |
59787: 1851: end if | |
-: 1852: | |
-: 1853: if (associated(me%next) .and. des_next) call json_value_destroy(me%next) | |
388577: 1854: | |
-: 1855: if (associated(me%previous)) nullify(me%previous) | |
388577: 1856: if (associated(me%parent)) nullify(me%parent) | |
388577: 1857: if (associated(me%tail)) nullify(me%tail) | |
388577: 1858: | |
-: 1859: deallocate(me) | |
388577: 1860: | |
-: 1861: nullify(me) | |
388577: 1862: | |
-: 1863: end if | |
-: 1864: | |
-: 1865: end subroutine json_value_destroy | |
388577: 1866:!***************************************************************************************** | |
-: 1867: | |
-: 1868:!***************************************************************************************** | |
-: 1869:!> author: Jacob Williams | |
-: 1870:! date: 9/9/2014 | |
-: 1871:! | |
-: 1872:! Remove a [[json_value]] (and all its children) | |
-: 1873:! from a linked-list structure, preserving the rest of the structure. | |
-: 1874:! | |
-: 1875:!# Examples | |
-: 1876:! | |
-: 1877:! To extract an object from one JSON structure, and add it to another: | |
-: 1878:!```fortran | |
-: 1879:! type(json_value),pointer :: json1,json2,p | |
-: 1880:! logical :: found | |
-: 1881:! !create and populate json1 and json2 | |
-: 1882:! call json_get(json1,'name',p,found) ! get pointer to name element of json1 | |
-: 1883:! call json_remove(p,destroy=.false.) ! remove it from json1 (don't destroy) | |
-: 1884:! call json_add(json2,p) ! add it to json2 | |
-: 1885:!``` | |
-: 1886:! | |
-: 1887:! To remove an object from a JSON structure (and destroy it): | |
-: 1888:!```fortran | |
-: 1889:! type(json_value),pointer :: json1,p | |
-: 1890:! logical :: found | |
-: 1891:! !create and populate json1 | |
-: 1892:! call json_get(json1,'name',p,found) ! get pointer to name element of json1 | |
-: 1893:! call json_remove(p) ! remove and destroy it | |
-: 1894:!``` | |
-: 1895:! | |
-: 1896:!# History | |
-: 1897:! * Jacob Williams : 12/28/2014 : added destroy optional argument. | |
-: 1898:! | |
-: 1899: | |
-: 1900: subroutine json_value_remove(me,destroy) | |
5: 1901: | |
-: 1902: implicit none | |
-: 1903: | |
-: 1904: type(json_value),pointer :: me | |
-: 1905: logical(LK),intent(in),optional :: destroy !! If destroy is not present, it is also destroyed. | |
-: 1906: !! If destroy is present and true, it is destroyed. | |
-: 1907: !! If destroy is present and false, it is not destroyed. | |
-: 1908: | |
-: 1909: type(json_value),pointer :: parent,previous,next | |
-: 1910: logical(LK) :: destroy_it | |
-: 1911: | |
-: 1912: if (associated(me)) then | |
5: 1913: | |
-: 1914: !optional input argument: | |
-: 1915: if (present(destroy)) then | |
5: 1916: destroy_it = destroy | |
1: 1917: else | |
-: 1918: destroy_it = .true. | |
4: 1919: end if | |
-: 1920: | |
-: 1921: if (associated(me%parent)) then | |
5: 1922: | |
-: 1923: parent => me%parent | |
5: 1924: | |
-: 1925: if (associated(me%next)) then | |
5: 1926: | |
-: 1927: !there are later items in the list: | |
-: 1928: | |
-: 1929: next => me%next | |
4: 1930: nullify(me%next) | |
4: 1931: | |
-: 1932: if (associated(me%previous)) then | |
4: 1933: !there are earlier items in the list | |
-: 1934: previous => me%previous | |
3: 1935: previous%next => next | |
3: 1936: next%previous => previous | |
3: 1937: else | |
-: 1938: !this is the first item in the list | |
-: 1939: parent%children => next | |
1: 1940: nullify(next%previous) | |
1: 1941: end if | |
-: 1942: | |
-: 1943: else | |
-: 1944: | |
-: 1945: if (associated(me%previous)) then | |
1: 1946: !there are earlier items in the list: | |
-: 1947: previous => me%previous | |
1: 1948: nullify(previous%next) | |
1: 1949: parent%tail => previous | |
1: 1950: else | |
-: 1951: !this is the only item in the list: | |
-: 1952: nullify(parent%children) | |
#####: 1953: nullify(parent%tail) | |
#####: 1954: end if | |
-: 1955: | |
-: 1956: end if | |
-: 1957: | |
-: 1958: parent%n_children = parent%n_children - 1 | |
5: 1959: | |
-: 1960: end if | |
-: 1961: | |
-: 1962: if (destroy_it) call json_value_destroy(me) | |
5: 1963: | |
-: 1964: end if | |
-: 1965: | |
-: 1966: end subroutine json_value_remove | |
5: 1967:!***************************************************************************************** | |
-: 1968: | |
-: 1969:!***************************************************************************************** | |
-: 1970:!> author: Jacob Williams | |
-: 1971:! date: 12/6/2014 | |
-: 1972:! | |
-: 1973:! Given the path string, remove the variable from | |
-: 1974:! the [[json_value]] structure, if it exists. | |
-: 1975: | |
-: 1976: subroutine json_value_remove_if_present(p,name) | |
1: 1977: | |
-: 1978: implicit none | |
-: 1979: | |
-: 1980: type(json_value),pointer :: p | |
-: 1981: character(kind=CK,len=*),intent(in) :: name | |
-: 1982: | |
-: 1983: type(json_value),pointer :: p_var | |
-: 1984: logical(LK) :: found | |
-: 1985: | |
-: 1986: call json_get(p,name,p_var,found) | |
1: 1987: if (found) call json_remove(p_var) | |
1: 1988: | |
-: 1989: end subroutine json_value_remove_if_present | |
2: 1990:!***************************************************************************************** | |
-: 1991: | |
-: 1992:!***************************************************************************************** | |
-: 1993:!> | |
-: 1994:! Alternate version of [[json_value_remove_if_present]], where "name" is kind=CDK. | |
-: 1995: | |
-: 1996: subroutine wrap_json_value_remove_if_present(p,name) | |
1: 1997: | |
-: 1998: implicit none | |
-: 1999: | |
-: 2000: type(json_value),pointer :: p | |
-: 2001: character(kind=CDK,len=*),intent(in) :: name | |
-: 2002: | |
-: 2003: call json_value_remove_if_present(p,to_unicode(name)) | |
1: 2004: | |
-: 2005: end subroutine wrap_json_value_remove_if_present | |
2: 2006:!***************************************************************************************** | |
-: 2007: | |
-: 2008:!***************************************************************************************** | |
-: 2009:!> author: Jacob Williams | |
-: 2010:! date:1/10/2015 | |
-: 2011:! | |
-: 2012:! Given the path string, if the variable is present in the file, | |
-: 2013:! and is a scalar, then update its value. | |
-: 2014:! If it is not present, then create it and set its value. | |
-: 2015:! | |
-: 2016:!# See also | |
-: 2017:! * [[json_update_integer]] | |
-: 2018: | |
-: 2019: subroutine json_file_update_integer(me,name,val,found) | |
1: 2020: implicit none | |
-: 2021: | |
-: 2022: class(json_file),intent(inout) :: me | |
-: 2023: character(kind=CK,len=*),intent(in) :: name | |
-: 2024: integer(IK),intent(in) :: val | |
-: 2025: logical(LK),intent(out) :: found | |
-: 2026: | |
-: 2027: if (.not. exception_thrown) call json_update(me%p,name,val,found) | |
1: 2028: | |
-: 2029: end subroutine json_file_update_integer | |
2: 2030:!***************************************************************************************** | |
-: 2031: | |
-: 2032:!***************************************************************************************** | |
-: 2033:!> | |
-: 2034:! Alternate version of [[json_file_update_integer]], where "name" is kind=CDK. | |
-: 2035: | |
-: 2036: subroutine wrap_json_file_update_integer(me,name,val,found) | |
1: 2037: implicit none | |
-: 2038: | |
-: 2039: class(json_file),intent(inout) :: me | |
-: 2040: character(kind=CDK,len=*),intent(in) :: name | |
-: 2041: integer(IK),intent(in) :: val | |
-: 2042: logical(LK),intent(out) :: found | |
-: 2043: | |
-: 2044: call json_file_update_integer(me,to_unicode(name),val,found) | |
1: 2045: | |
-: 2046: end subroutine wrap_json_file_update_integer | |
2: 2047:!***************************************************************************************** | |
-: 2048: | |
-: 2049:!***************************************************************************************** | |
-: 2050:!> author: Jacob Williams | |
-: 2051:! date: 1/10/2015 | |
-: 2052:! | |
-: 2053:! Given the path string, if the variable is present in the file, | |
-: 2054:! and is a scalar, then update its value. | |
-: 2055:! If it is not present, then create it and set its value. | |
-: 2056:! | |
-: 2057:!# See also | |
-: 2058:! * [[json_update_logical]] | |
-: 2059: | |
-: 2060: subroutine json_file_update_logical(me,name,val,found) | |
2: 2061: implicit none | |
-: 2062: | |
-: 2063: class(json_file),intent(inout) :: me | |
-: 2064: character(kind=CK,len=*),intent(in) :: name | |
-: 2065: logical(LK),intent(in) :: val | |
-: 2066: logical(LK),intent(out) :: found | |
-: 2067: | |
-: 2068: if (.not. exception_thrown) call json_update(me%p,name,val,found) | |
2: 2069: | |
-: 2070: end subroutine json_file_update_logical | |
4: 2071:!***************************************************************************************** | |
-: 2072: | |
-: 2073:!***************************************************************************************** | |
-: 2074:!> | |
-: 2075:! Alternate version of [[json_file_update_logical]], where "name" is kind=CDK. | |
-: 2076: | |
-: 2077: subroutine wrap_json_file_update_logical(me,name,val,found) | |
2: 2078: implicit none | |
-: 2079: | |
-: 2080: class(json_file),intent(inout) :: me | |
-: 2081: character(kind=CDK,len=*),intent(in) :: name | |
-: 2082: logical(LK),intent(in) :: val | |
-: 2083: logical(LK),intent(out) :: found | |
-: 2084: | |
-: 2085: call json_file_update_logical(me,to_unicode(name),val,found) | |
2: 2086: | |
-: 2087: end subroutine wrap_json_file_update_logical | |
4: 2088:!***************************************************************************************** | |
-: 2089: | |
-: 2090:!***************************************************************************************** | |
-: 2091:!> author: Jacob Williams | |
-: 2092:! date: 1/10/2015 | |
-: 2093:! | |
-: 2094:! Given the path string, if the variable is present in the file, | |
-: 2095:! and is a scalar, then update its value. | |
-: 2096:! If it is not present, then create it and set its value. | |
-: 2097:! | |
-: 2098:!# See also | |
-: 2099:! * [[json_update_double]] | |
-: 2100: | |
-: 2101: subroutine json_file_update_real(me,name,val,found) | |
2: 2102: implicit none | |
-: 2103: | |
-: 2104: class(json_file),intent(inout) :: me | |
-: 2105: character(kind=CK,len=*),intent(in) :: name | |
-: 2106: real(RK),intent(in) :: val | |
-: 2107: logical(LK),intent(out) :: found | |
-: 2108: | |
-: 2109: if (.not. exception_thrown) call json_update(me%p,name,val,found) | |
2: 2110: | |
-: 2111: end subroutine json_file_update_real | |
4: 2112:!***************************************************************************************** | |
-: 2113: | |
-: 2114:!***************************************************************************************** | |
-: 2115:!> | |
-: 2116:! Alternate version of [[json_file_update_real]], where "name" is kind=CDK. | |
-: 2117: | |
-: 2118: subroutine wrap_json_file_update_real(me,name,val,found) | |
2: 2119: implicit none | |
-: 2120: | |
-: 2121: class(json_file),intent(inout) :: me | |
-: 2122: character(kind=CDK,len=*),intent(in) :: name | |
-: 2123: real(RK),intent(in) :: val | |
-: 2124: logical(LK),intent(out) :: found | |
-: 2125: | |
-: 2126: call json_file_update_real(me,to_unicode(name),val,found) | |
2: 2127: | |
-: 2128: end subroutine wrap_json_file_update_real | |
4: 2129:!***************************************************************************************** | |
-: 2130: | |
-: 2131:!***************************************************************************************** | |
-: 2132:!> author: Jacob Williams | |
-: 2133:! date: 1/10/2015 | |
-: 2134:! | |
-: 2135:! Given the path string, if the variable is present in the file, | |
-: 2136:! and is a scalar, then update its value. | |
-: 2137:! If it is not present, then create it and set its value. | |
-: 2138:! | |
-: 2139:!# See also | |
-: 2140:! * [[json_update_string]] | |
-: 2141: | |
-: 2142: subroutine json_file_update_string(me,name,val,found) | |
2: 2143: implicit none | |
-: 2144: | |
-: 2145: class(json_file),intent(inout) :: me | |
-: 2146: character(kind=CK,len=*),intent(in) :: name | |
-: 2147: character(kind=CK,len=*),intent(in) :: val | |
-: 2148: logical(LK),intent(out) :: found | |
-: 2149: | |
-: 2150: if (.not. exception_thrown) call json_update(me%p,name,val,found) | |
2: 2151: | |
-: 2152: end subroutine json_file_update_string | |
4: 2153:!***************************************************************************************** | |
-: 2154: | |
-: 2155:!***************************************************************************************** | |
-: 2156:!> | |
-: 2157:! Alternate version of [[json_file_update_string]], where "name" and "val" are kind=CDK. | |
-: 2158: | |
-: 2159: subroutine wrap_json_file_update_string(me,name,val,found) | |
2: 2160: implicit none | |
-: 2161: | |
-: 2162: class(json_file),intent(inout) :: me | |
-: 2163: character(kind=CDK,len=*),intent(in) :: name | |
-: 2164: character(kind=CDK,len=*),intent(in) :: val | |
-: 2165: logical(LK),intent(out) :: found | |
-: 2166: | |
-: 2167: call json_file_update_string(me,to_unicode(name),to_unicode(val),found) | |
2: 2168: | |
-: 2169: end subroutine wrap_json_file_update_string | |
4: 2170:!***************************************************************************************** | |
-: 2171: | |
-: 2172:!***************************************************************************************** | |
-: 2173:!> | |
-: 2174:! Alternate version of [[json_file_update_string]], where "name" is kind=CDK. | |
-: 2175: | |
-: 2176: subroutine json_file_update_string_name_ascii(me,name,val,found) | |
#####: 2177: implicit none | |
-: 2178: | |
-: 2179: class(json_file),intent(inout) :: me | |
-: 2180: character(kind=CDK,len=*),intent(in) :: name | |
-: 2181: character(kind=CK, len=*),intent(in) :: val | |
-: 2182: logical(LK),intent(out) :: found | |
-: 2183: | |
-: 2184: call json_file_update_string(me,to_unicode(name),val,found) | |
#####: 2185: | |
-: 2186: end subroutine json_file_update_string_name_ascii | |
#####: 2187:!***************************************************************************************** | |
-: 2188: | |
-: 2189:!***************************************************************************************** | |
-: 2190:!> | |
-: 2191:! Alternate version of [[json_file_update_string]], where "val" is kind=CDK. | |
-: 2192: | |
-: 2193: subroutine json_file_update_string_val_ascii(me,name,val,found) | |
#####: 2194: implicit none | |
-: 2195: | |
-: 2196: class(json_file),intent(inout) :: me | |
-: 2197: character(kind=CK, len=*),intent(in) :: name | |
-: 2198: character(kind=CDK,len=*),intent(in) :: val | |
-: 2199: logical(LK),intent(out) :: found | |
-: 2200: | |
-: 2201: call json_file_update_string(me,name,to_unicode(val),found) | |
#####: 2202: | |
-: 2203: end subroutine json_file_update_string_val_ascii | |
#####: 2204:!***************************************************************************************** | |
-: 2205: | |
-: 2206:!***************************************************************************************** | |
-: 2207:!> author: Jacob Williams | |
-: 2208:! date: 12/6/2014 | |
-: 2209:! | |
-: 2210:! Given the path string, if the variable is present, | |
-: 2211:! and is a scalar, then update its value. | |
-: 2212:! If it is not present, then create it and set its value. | |
-: 2213: | |
-: 2214: subroutine json_update_logical(p,name,val,found) | |
3: 2215: | |
-: 2216: implicit none | |
-: 2217: | |
-: 2218: type(json_value),pointer :: p | |
-: 2219: character(kind=CK,len=*),intent(in) :: name | |
-: 2220: logical(LK),intent(in) :: val | |
-: 2221: logical(LK),intent(out) :: found | |
-: 2222: | |
-: 2223: type(json_value),pointer :: p_var | |
-: 2224: integer(IK) :: var_type | |
-: 2225: | |
-: 2226: call json_get(p,name,p_var,found) | |
3: 2227: if (found) then | |
3: 2228: | |
-: 2229: call json_info(p_var,var_type) | |
2: 2230: select case (var_type) | |
-: 2231: case (json_null,json_logical,json_integer,json_double,json_string) | |
-: 2232: call to_logical(p_var,val) !update the value | |
2: 2233: case default | |
-: 2234: found = .false. | |
#####: 2235: call throw_exception('Error in json_update_logical: '//& | |
-: 2236: 'the variable is not a scalar value') | |
2: 2237: end select | |
-: 2238: | |
-: 2239: else | |
-: 2240: call json_add(p,name,val) !add the new element | |
1: 2241: end if | |
-: 2242: | |
-: 2243: end subroutine json_update_logical | |
6: 2244:!***************************************************************************************** | |
-: 2245: | |
-: 2246:!***************************************************************************************** | |
-: 2247:!> | |
-: 2248:! Alternate version of [[json_update_logical]], where "name" is kind=CDK. | |
-: 2249: | |
-: 2250: subroutine wrap_json_update_logical(p,name,val,found) | |
1: 2251: | |
-: 2252: implicit none | |
-: 2253: | |
-: 2254: type(json_value),pointer :: p | |
-: 2255: character(kind=CDK,len=*),intent(in) :: name | |
-: 2256: logical(LK),intent(in) :: val | |
-: 2257: logical(LK),intent(out) :: found | |
-: 2258: | |
-: 2259: call json_update_logical(p,to_unicode(name),val,found) | |
1: 2260: | |
-: 2261: end subroutine wrap_json_update_logical | |
2: 2262:!***************************************************************************************** | |
-: 2263: | |
-: 2264:!***************************************************************************************** | |
-: 2265:!> author: Jacob Williams | |
-: 2266:! date: 12/6/2014 | |
-: 2267:! | |
-: 2268:! Given the path string, if the variable is present, | |
-: 2269:! and is a scalar, then update its value. | |
-: 2270:! If it is not present, then create it and set its value. | |
-: 2271: | |
-: 2272: subroutine json_update_double(p,name,val,found) | |
3: 2273: | |
-: 2274: implicit none | |
-: 2275: | |
-: 2276: type(json_value),pointer :: p | |
-: 2277: character(kind=CK,len=*),intent(in) :: name | |
-: 2278: real(RK),intent(in) :: val | |
-: 2279: logical(LK),intent(out) :: found | |
-: 2280: | |
-: 2281: type(json_value),pointer :: p_var | |
-: 2282: integer(IK) :: var_type | |
-: 2283: | |
-: 2284: call json_get(p,name,p_var,found) | |
3: 2285: if (found) then | |
3: 2286: | |
-: 2287: call json_info(p_var,var_type) | |
2: 2288: select case (var_type) | |
-: 2289: case (json_null,json_logical,json_integer,json_double,json_string) | |
-: 2290: call to_double(p_var,val) !update the value | |
2: 2291: case default | |
-: 2292: found = .false. | |
#####: 2293: call throw_exception('Error in json_update_double: '//& | |
-: 2294: 'the variable is not a scalar value') | |
2: 2295: end select | |
-: 2296: | |
-: 2297: else | |
-: 2298: call json_add(p,name,val) !add the new element | |
1: 2299: end if | |
-: 2300: | |
-: 2301: end subroutine json_update_double | |
6: 2302:!***************************************************************************************** | |
-: 2303: | |
-: 2304:!***************************************************************************************** | |
-: 2305:!> | |
-: 2306:! Alternate version of [[json_update_double]], where "name" is kind=CDK. | |
-: 2307: | |
-: 2308: subroutine wrap_json_update_double(p,name,val,found) | |
1: 2309: | |
-: 2310: implicit none | |
-: 2311: | |
-: 2312: type(json_value),pointer :: p | |
-: 2313: character(kind=CDK,len=*),intent(in) :: name | |
-: 2314: real(RK),intent(in) :: val | |
-: 2315: logical(LK),intent(out) :: found | |
-: 2316: | |
-: 2317: call json_update_double(p,to_unicode(name),val,found) | |
1: 2318: | |
-: 2319: end subroutine wrap_json_update_double | |
2: 2320:!***************************************************************************************** | |
-: 2321: | |
-: 2322:!***************************************************************************************** | |
-: 2323:!> author: Jacob Williams | |
-: 2324:! date: 12/6/2014 | |
-: 2325:! | |
-: 2326:! Given the path string, if the variable is present, | |
-: 2327:! and is a scalar, then update its value. | |
-: 2328:! If it is not present, then create it and set its value. | |
-: 2329: | |
-: 2330: subroutine json_update_integer(p,name,val,found) | |
1: 2331: | |
-: 2332: implicit none | |
-: 2333: | |
-: 2334: type(json_value),pointer :: p | |
-: 2335: character(kind=CK,len=*),intent(in) :: name | |
-: 2336: integer(IK),intent(in) :: val | |
-: 2337: logical(LK),intent(out) :: found | |
-: 2338: | |
-: 2339: type(json_value),pointer :: p_var | |
-: 2340: integer(IK) :: var_type | |
-: 2341: | |
-: 2342: call json_get(p,name,p_var,found) | |
1: 2343: if (found) then | |
1: 2344: | |
-: 2345: call json_info(p_var,var_type) | |
1: 2346: select case (var_type) | |
-: 2347: case (json_null,json_logical,json_integer,json_double,json_string) | |
-: 2348: call to_integer(p_var,val) !update the value | |
1: 2349: case default | |
-: 2350: found = .false. | |
#####: 2351: call throw_exception('Error in json_update_integer: '//& | |
-: 2352: 'the variable is not a scalar value') | |
1: 2353: end select | |
-: 2354: | |
-: 2355: else | |
-: 2356: call json_add(p,name,val) !add the new element | |
#####: 2357: end if | |
-: 2358: | |
-: 2359: end subroutine json_update_integer | |
2: 2360:!***************************************************************************************** | |
-: 2361: | |
-: 2362:!***************************************************************************************** | |
-: 2363:!> | |
-: 2364:! Alternate version of [[json_update_integer]], where "name" is kind=CDK. | |
-: 2365: | |
-: 2366: subroutine wrap_json_update_integer(p,name,val,found) | |
#####: 2367: | |
-: 2368: implicit none | |
-: 2369: | |
-: 2370: type(json_value),pointer :: p | |
-: 2371: character(kind=CDK,len=*),intent(in) :: name | |
-: 2372: integer(IK),intent(in) :: val | |
-: 2373: logical(LK),intent(out) :: found | |
-: 2374: | |
-: 2375: call json_update_integer(p,to_unicode(name),val,found) | |
#####: 2376: | |
-: 2377: end subroutine wrap_json_update_integer | |
#####: 2378:!***************************************************************************************** | |
-: 2379: | |
-: 2380:!***************************************************************************************** | |
-: 2381:!> author: Jacob Williams | |
-: 2382:! date: 12/6/2014 | |
-: 2383:! | |
-: 2384:! Given the path string, if the variable is present, | |
-: 2385:! and is a scalar, then update its value. | |
-: 2386:! If it is not present, then create it and set its value. | |
-: 2387: | |
-: 2388: subroutine json_update_string(p,name,val,found) | |
3: 2389: | |
-: 2390: implicit none | |
-: 2391: | |
-: 2392: type(json_value),pointer :: p | |
-: 2393: character(kind=CK,len=*),intent(in) :: name | |
-: 2394: character(kind=CK,len=*),intent(in) :: val | |
-: 2395: logical(LK),intent(out) :: found | |
-: 2396: | |
-: 2397: type(json_value),pointer :: p_var | |
-: 2398: integer(IK) :: var_type | |
-: 2399: | |
-: 2400: call json_get(p,name,p_var,found) | |
3: 2401: if (found) then | |
3: 2402: | |
-: 2403: call json_info(p_var,var_type) | |
2: 2404: select case (var_type) | |
-: 2405: case (json_null,json_logical,json_integer,json_double,json_string) | |
-: 2406: call to_string(p_var,val) !update the value | |
2: 2407: case default | |
-: 2408: found = .false. | |
#####: 2409: call throw_exception('Error in json_update_string: '//& | |
-: 2410: 'the variable is not a scalar value') | |
2: 2411: end select | |
-: 2412: | |
-: 2413: else | |
-: 2414: call json_add(p,name,val) !add the new element | |
1: 2415: end if | |
-: 2416: | |
-: 2417: end subroutine json_update_string | |
6: 2418:!***************************************************************************************** | |
-: 2419: | |
-: 2420:!***************************************************************************************** | |
-: 2421:!> | |
-: 2422:! Alternate version of [[json_update_string]], where "name" and "value" are kind=CDK. | |
-: 2423: | |
-: 2424: subroutine wrap_json_update_string(p,name,val,found) | |
1: 2425: | |
-: 2426: implicit none | |
-: 2427: | |
-: 2428: type(json_value),pointer :: p | |
-: 2429: character(kind=CDK,len=*),intent(in) :: name | |
-: 2430: character(kind=CDK,len=*),intent(in) :: val | |
-: 2431: logical(LK),intent(out) :: found | |
-: 2432: | |
-: 2433: call json_update_string(p,to_unicode(name),to_unicode(val),found) | |
1: 2434: | |
-: 2435: end subroutine wrap_json_update_string | |
2: 2436:!***************************************************************************************** | |
-: 2437: | |
-: 2438:!***************************************************************************************** | |
-: 2439:!> | |
-: 2440:! Alternate version of [[json_update_string]], where "name" is kind=CDK. | |
-: 2441: | |
-: 2442: subroutine json_update_string_name_ascii(p,name,val,found) | |
#####: 2443: | |
-: 2444: implicit none | |
-: 2445: | |
-: 2446: type(json_value),pointer :: p | |
-: 2447: character(kind=CDK,len=*),intent(in) :: name | |
-: 2448: character(kind=CK, len=*),intent(in) :: val | |
-: 2449: logical(LK),intent(out) :: found | |
-: 2450: | |
-: 2451: call json_update_string(p,to_unicode(name),val,found) | |
#####: 2452: | |
-: 2453: end subroutine json_update_string_name_ascii | |
#####: 2454:!***************************************************************************************** | |
-: 2455: | |
-: 2456:!***************************************************************************************** | |
-: 2457:!> | |
-: 2458:! Alternate version of [[json_update_string]], where "val" is kind=CDK. | |
-: 2459: | |
-: 2460: subroutine json_update_string_val_ascii(p,name,val,found) | |
#####: 2461: | |
-: 2462: implicit none | |
-: 2463: | |
-: 2464: type(json_value),pointer :: p | |
-: 2465: character(kind=CK, len=*),intent(in) :: name | |
-: 2466: character(kind=CDK,len=*),intent(in) :: val | |
-: 2467: logical(LK),intent(out) :: found | |
-: 2468: | |
-: 2469: call json_update_string(p,name,to_unicode(val),found) | |
#####: 2470: | |
-: 2471: end subroutine json_update_string_val_ascii | |
#####: 2472:!***************************************************************************************** | |
-: 2473: | |
-: 2474:!***************************************************************************************** | |
-: 2475:!> | |
-: 2476:! Adds "member" as a child of "me". | |
-: 2477: | |
-: 2478: subroutine json_value_add_member(me, member) | |
388553: 2479: | |
-: 2480: implicit none | |
-: 2481: | |
-: 2482: type(json_value),pointer :: me | |
-: 2483: type(json_value),pointer :: member !! the child member to add | |
-: 2484: | |
-: 2485: if (.not. exception_thrown) then | |
388553: 2486: | |
-: 2487: ! associate the parent | |
-: 2488: member%parent => me | |
388553: 2489: | |
-: 2490: ! add to linked list | |
-: 2491: if (associated(me%children)) then | |
388553: 2492: | |
-: 2493: me%tail%next => member | |
328765: 2494: member%previous => me%tail | |
328765: 2495: | |
-: 2496: else | |
-: 2497: | |
-: 2498: me%children => member | |
59788: 2499: member%previous => null() !first in the list | |
59788: 2500: | |
-: 2501: end if | |
-: 2502: | |
-: 2503: ! new member is now the last one in the list | |
-: 2504: me%tail => member | |
388553: 2505: me%n_children = me%n_children + 1 | |
388553: 2506: | |
-: 2507: end if | |
-: 2508: | |
-: 2509: end subroutine json_value_add_member | |
388553: 2510:!***************************************************************************************** | |
-: 2511: | |
-: 2512:!***************************************************************************************** | |
-: 2513:!> author: Jacob Williams | |
-: 2514:! date: 1/19/2014 | |
-: 2515:! | |
-: 2516:! Add a real value child to the [[json_value]] variable | |
-: 2517:! | |
-: 2518:!@note This routine is part of the public API that can be | |
-: 2519:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2520: | |
-: 2521: subroutine json_value_add_double(me, name, val) | |
22: 2522: | |
-: 2523: implicit none | |
-: 2524: | |
-: 2525: type(json_value),pointer :: me | |
-: 2526: character(kind=CK,len=*),intent(in) :: name !! variable name | |
-: 2527: real(RK),intent(in) :: val !! real value | |
-: 2528: | |
-: 2529: type(json_value),pointer :: var | |
-: 2530: | |
-: 2531: !create the variable: | |
-: 2532: call json_value_create(var) | |
22: 2533: call to_double(var,val,name) | |
22: 2534: | |
-: 2535: !add it: | |
-: 2536: call json_add(me, var) | |
22: 2537: | |
-: 2538: !cleanup: | |
-: 2539: nullify(var) | |
22: 2540: | |
-: 2541: end subroutine json_value_add_double | |
44: 2542:!***************************************************************************************** | |
-: 2543: | |
-: 2544:!***************************************************************************************** | |
-: 2545:!> | |
-: 2546:! Alternate version of [[json_value_add_double]] where "name" is kind=CDK. | |
-: 2547: | |
-: 2548: subroutine wrap_json_value_add_double(me, name, val) | |
21: 2549: | |
-: 2550: implicit none | |
-: 2551: | |
-: 2552: type(json_value),pointer :: me | |
-: 2553: character(kind=CDK,len=*),intent(in) :: name !! variable name | |
-: 2554: real(RK),intent(in) :: val !! real value | |
-: 2555: | |
-: 2556: call json_value_add_double(me, to_unicode(name), val) | |
21: 2557: | |
-: 2558: end subroutine wrap_json_value_add_double | |
42: 2559:!***************************************************************************************** | |
-: 2560: | |
-: 2561:!***************************************************************************************** | |
-: 2562:!> author: Jacob Williams | |
-: 2563:! date: 1/20/2014 | |
-: 2564:! | |
-: 2565:! Add a real vector to the structure. | |
-: 2566:! | |
-: 2567:!@note This routine is part of the public API that can be | |
-: 2568:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2569: | |
-: 2570: subroutine json_value_add_double_vec(me, name, val) | |
12: 2571: | |
-: 2572: implicit none | |
-: 2573: | |
-: 2574: type(json_value),pointer :: me | |
-: 2575: character(kind=CK,len=*),intent(in) :: name | |
-: 2576: real(RK),dimension(:),intent(in) :: val | |
-: 2577: | |
-: 2578: type(json_value),pointer :: var | |
-: 2579: integer(IK) :: i | |
-: 2580: | |
-: 2581: !create the variable as an array: | |
-: 2582: call json_value_create(var) | |
6: 2583: call to_array(var,name) | |
6: 2584: | |
-: 2585: !populate the array: | |
-: 2586: do i=1,size(val) | |
24: 2587: call json_add(var, '', val(i)) | |
18: 2588: end do | |
-: 2589: | |
-: 2590: !add it: | |
-: 2591: call json_add(me, var) | |
6: 2592: | |
-: 2593: !cleanup: | |
-: 2594: nullify(var) | |
6: 2595: | |
-: 2596: end subroutine json_value_add_double_vec | |
12: 2597:!***************************************************************************************** | |
-: 2598: | |
-: 2599:!***************************************************************************************** | |
-: 2600:!> | |
-: 2601:! Alternate version of [[json_value_add_double_vec]] where "name" is kind=CDK. | |
-: 2602: | |
-: 2603: subroutine wrap_json_value_add_double_vec(me, name, val) | |
12: 2604: | |
-: 2605: implicit none | |
-: 2606: | |
-: 2607: type(json_value),pointer :: me | |
-: 2608: character(kind=CDK,len=*),intent(in) :: name | |
-: 2609: real(RK),dimension(:),intent(in) :: val | |
-: 2610: | |
-: 2611: call json_value_add_double_vec(me, to_unicode(name), val) | |
6: 2612: | |
-: 2613: end subroutine wrap_json_value_add_double_vec | |
12: 2614:!***************************************************************************************** | |
-: 2615: | |
-: 2616:!***************************************************************************************** | |
-: 2617:!> author: Jacob Williams | |
-: 2618:! date: 1/20/2014 | |
-: 2619:! | |
-: 2620:! Add an integer value child to the [[json_value]] variable | |
-: 2621:! | |
-: 2622:!@note This routine is part of the public API that can be | |
-: 2623:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2624: | |
-: 2625: subroutine json_value_add_integer(me, name, val) | |
112: 2626: | |
-: 2627: implicit none | |
-: 2628: | |
-: 2629: type(json_value),pointer :: me | |
-: 2630: character(kind=CK,len=*),intent(in) :: name | |
-: 2631: integer(IK),intent(in) :: val | |
-: 2632: | |
-: 2633: type(json_value),pointer :: var | |
-: 2634: | |
-: 2635: !create the variable: | |
-: 2636: call json_value_create(var) | |
112: 2637: call to_integer(var,val,name) | |
112: 2638: | |
-: 2639: !add it: | |
-: 2640: call json_add(me, var) | |
112: 2641: | |
-: 2642: !cleanup: | |
-: 2643: nullify(var) | |
112: 2644: | |
-: 2645: end subroutine json_value_add_integer | |
224: 2646:!***************************************************************************************** | |
-: 2647: | |
-: 2648:!***************************************************************************************** | |
-: 2649:!> | |
-: 2650:! Alternate version of [[json_value_add_integer]] where "name" is kind=CDK. | |
-: 2651: | |
-: 2652: subroutine wrap_json_value_add_integer(me, name, val) | |
12: 2653: | |
-: 2654: implicit none | |
-: 2655: | |
-: 2656: type(json_value),pointer :: me | |
-: 2657: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2658: integer(IK),intent(in) :: val !! value | |
-: 2659: | |
-: 2660: call json_value_add_integer(me, to_unicode(name), val) | |
12: 2661: | |
-: 2662: end subroutine wrap_json_value_add_integer | |
24: 2663:!***************************************************************************************** | |
-: 2664: | |
-: 2665:!***************************************************************************************** | |
-: 2666:!> author: Jacob Williams | |
-: 2667:! date: 1/20/2014 | |
-: 2668:! | |
-: 2669:! Add an integer vector to the structure. | |
-: 2670:! | |
-: 2671:!@note This routine is part of the public API that can be | |
-: 2672:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2673: | |
-: 2674: subroutine json_value_add_integer_vec(me, name, val) | |
4: 2675: | |
-: 2676: implicit none | |
-: 2677: | |
-: 2678: type(json_value),pointer :: me | |
-: 2679: character(kind=CK,len=*),intent(in) :: name !! name of the variable | |
-: 2680: integer(IK),dimension(:),intent(in) :: val !! value | |
-: 2681: | |
-: 2682: type(json_value),pointer :: var | |
-: 2683: integer(IK) :: i !counter | |
-: 2684: | |
-: 2685: !create the variable as an array: | |
-: 2686: call json_value_create(var) | |
2: 2687: call to_array(var,name) | |
2: 2688: | |
-: 2689: !populate the array: | |
-: 2690: do i=1,size(val) | |
8: 2691: call json_add(var, '', val(i)) | |
6: 2692: end do | |
-: 2693: | |
-: 2694: !add it: | |
-: 2695: call json_add(me, var) | |
2: 2696: | |
-: 2697: !cleanup: | |
-: 2698: nullify(var) | |
2: 2699: | |
-: 2700: end subroutine json_value_add_integer_vec | |
4: 2701:!***************************************************************************************** | |
-: 2702: | |
-: 2703:!***************************************************************************************** | |
-: 2704:!> | |
-: 2705:! Alternate version of [[json_value_add_integer_vec]] where "name" is kind=CDK. | |
-: 2706: | |
-: 2707: subroutine wrap_json_value_add_integer_vec(me, name, val) | |
4: 2708: | |
-: 2709: implicit none | |
-: 2710: | |
-: 2711: type(json_value),pointer :: me | |
-: 2712: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2713: integer(IK),dimension(:),intent(in) :: val !! value | |
-: 2714: | |
-: 2715: call json_value_add_integer_vec(me, to_unicode(name), val) | |
2: 2716: | |
-: 2717: end subroutine wrap_json_value_add_integer_vec | |
4: 2718:!***************************************************************************************** | |
-: 2719: | |
-: 2720:!***************************************************************************************** | |
-: 2721:!> author: Jacob Williams | |
-: 2722:! date: 1/20/2014 | |
-: 2723:! | |
-: 2724:! Add a logical value child to the [[json_value]] variable | |
-: 2725:! | |
-: 2726:!@note This routine is part of the public API that can be | |
-: 2727:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2728: | |
-: 2729: subroutine json_value_add_logical(me, name, val) | |
5: 2730: | |
-: 2731: implicit none | |
-: 2732: | |
-: 2733: type(json_value),pointer :: me | |
-: 2734: character(kind=CK,len=*),intent(in) :: name !! name of the variable | |
-: 2735: logical(LK),intent(in) :: val !! value | |
-: 2736: | |
-: 2737: type(json_value),pointer :: var | |
-: 2738: | |
-: 2739: !create the variable: | |
-: 2740: call json_value_create(var) | |
5: 2741: call to_logical(var,val,name) | |
5: 2742: | |
-: 2743: !add it: | |
-: 2744: call json_add(me, var) | |
5: 2745: | |
-: 2746: !cleanup: | |
-: 2747: nullify(var) | |
5: 2748: | |
-: 2749: end subroutine json_value_add_logical | |
10: 2750:!***************************************************************************************** | |
-: 2751: | |
-: 2752:!***************************************************************************************** | |
-: 2753:!> | |
-: 2754:! Alternate version of [[json_value_add_logical]] where "name" is kind=CDK. | |
-: 2755: | |
-: 2756: subroutine wrap_json_value_add_logical(me, name, val) | |
4: 2757: | |
-: 2758: implicit none | |
-: 2759: | |
-: 2760: type(json_value),pointer :: me | |
-: 2761: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2762: logical(LK),intent(in) :: val !! value | |
-: 2763: | |
-: 2764: call json_value_add_logical(me, to_unicode(name), val) | |
4: 2765: | |
-: 2766: end subroutine wrap_json_value_add_logical | |
8: 2767:!***************************************************************************************** | |
-: 2768: | |
-: 2769:!***************************************************************************************** | |
-: 2770:!> author: Jacob Williams | |
-: 2771:! date: 1/20/2014 | |
-: 2772:! | |
-: 2773:! Add a logical vector to the structure. | |
-: 2774:! | |
-: 2775:!@note This routine is part of the public API that can be | |
-: 2776:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2777: | |
-: 2778: subroutine json_value_add_logical_vec(me, name, val) | |
2: 2779: | |
-: 2780: implicit none | |
-: 2781: | |
-: 2782: type(json_value),pointer :: me | |
-: 2783: character(kind=CK,len=*),intent(in) :: name !! name of the vector | |
-: 2784: logical(LK),dimension(:),intent(in) :: val !! value | |
-: 2785: | |
-: 2786: type(json_value),pointer :: var | |
-: 2787: integer(IK) :: i !counter | |
-: 2788: | |
-: 2789: !create the variable as an array: | |
-: 2790: call json_value_create(var) | |
1: 2791: call to_array(var,name) | |
1: 2792: | |
-: 2793: !populate the array: | |
-: 2794: do i=1,size(val) | |
4: 2795: call json_add(var, '', val(i)) | |
3: 2796: end do | |
-: 2797: | |
-: 2798: !add it: | |
-: 2799: call json_add(me, var) | |
1: 2800: | |
-: 2801: !cleanup: | |
-: 2802: nullify(var) | |
1: 2803: | |
-: 2804: end subroutine json_value_add_logical_vec | |
2: 2805:!***************************************************************************************** | |
-: 2806: | |
-: 2807:!***************************************************************************************** | |
-: 2808:!> | |
-: 2809:! Alternate version of [[json_value_add_logical_vec]] where "name" is kind=CDK. | |
-: 2810: | |
-: 2811: subroutine wrap_json_value_add_logical_vec(me, name, val) | |
2: 2812: | |
-: 2813: implicit none | |
-: 2814: | |
-: 2815: type(json_value),pointer :: me | |
-: 2816: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2817: logical(LK),dimension(:),intent(in) :: val !! value | |
-: 2818: | |
-: 2819: call json_value_add_logical_vec(me, to_unicode(name), val) | |
1: 2820: | |
-: 2821: end subroutine wrap_json_value_add_logical_vec | |
2: 2822:!***************************************************************************************** | |
-: 2823: | |
-: 2824:!***************************************************************************************** | |
-: 2825:!> author: Jacob Williams | |
-: 2826:! date: 1/19/2014 | |
-: 2827:! | |
-: 2828:! Add a character string child to the [[json_value]] variable. | |
-: 2829:! | |
-: 2830:!@note This routine is part of the public API that can be | |
-: 2831:! used to build a JSON structure using [[json_value]] pointers. | |
-: 2832: | |
-: 2833: subroutine json_value_add_string(me, name, val) | |
36: 2834: | |
-: 2835: implicit none | |
-: 2836: | |
-: 2837: type(json_value),pointer :: me | |
-: 2838: character(kind=CK,len=*),intent(in) :: name !! name of the variable | |
-: 2839: character(kind=CK,len=*),intent(in) :: val !! value | |
-: 2840: | |
-: 2841: type(json_value),pointer :: var | |
-: 2842: character(kind=CK,len=:),allocatable :: str | |
36: 2843: | |
-: 2844: !add escape characters if necessary: | |
-: 2845: call escape_string(val, str) | |
36: 2846: | |
-: 2847: !create the variable: | |
-: 2848: call json_value_create(var) | |
36: 2849: call to_string(var,str,name) | |
36: 2850: | |
-: 2851: !add it: | |
-: 2852: call json_add(me, var) | |
36: 2853: | |
-: 2854: !cleanup: | |
-: 2855: nullify(var) | |
36: 2856: | |
-: 2857: end subroutine json_value_add_string | |
72: 2858:!***************************************************************************************** | |
-: 2859: | |
-: 2860:!***************************************************************************************** | |
-: 2861:!> | |
-: 2862:! Alternate version of [[json_value_add_string]] where "name" and "val" are kind=CDK. | |
-: 2863: | |
-: 2864: subroutine wrap_json_value_add_string(me, name, val) | |
25: 2865: | |
-: 2866: implicit none | |
-: 2867: | |
-: 2868: type(json_value),pointer :: me | |
-: 2869: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2870: character(kind=CDK,len=*),intent(in) :: val !! value | |
-: 2871: | |
-: 2872: call json_value_add_string(me, to_unicode(name), to_unicode(val)) | |
25: 2873: | |
-: 2874: end subroutine wrap_json_value_add_string | |
50: 2875:!***************************************************************************************** | |
-: 2876: | |
-: 2877:!***************************************************************************************** | |
-: 2878:!> | |
-: 2879:! Alternate version of [[json_value_add_string]] where "name" is kind=CDK. | |
-: 2880: | |
-: 2881: subroutine json_value_add_string_name_ascii(me, name, val) | |
10: 2882: | |
-: 2883: implicit none | |
-: 2884: | |
-: 2885: type(json_value),pointer :: me | |
-: 2886: character(kind=CDK,len=*),intent(in) :: name !! name of the variable | |
-: 2887: character(kind=CK, len=*),intent(in) :: val !! value | |
-: 2888: | |
-: 2889: call json_value_add_string(me, to_unicode(name), val) | |
10: 2890: | |
-: 2891: end subroutine json_value_add_string_name_ascii | |
20: 2892:!***************************************************************************************** | |
-: 2893: | |
-: 2894:!***************************************************************************************** | |
-: 2895:!> | |
-: 2896:! Alternate version of [[json_value_add_string]] where "val" is kind=CDK. | |
-: 2897: | |
-: 2898: subroutine json_value_add_string_val_ascii(me, name, val) | |
#####: 2899: | |
-: 2900: implicit none | |
-: 2901: | |
-: 2902: type(json_value),pointer :: me | |
-: 2903: character(kind=CK, len=*),intent(in) :: name !! name of the variable | |
-: 2904: character(kind=CDK,len=*),intent(in) :: val !! value | |
-: 2905: | |
-: 2906: call json_value_add_string(me, name, to_unicode(val)) | |
#####: 2907: | |
-: 2908: end subroutine json_value_add_string_val_ascii | |
#####: 2909:!***************************************************************************************** | |
-: 2910: | |
-: 2911:!***************************************************************************************** | |
-: 2912:!> author: Jacob Williams | |
-: 2913:! date: 1/21/2014 | |
-: 2914:! | |
-: 2915:! Add the escape characters to a string for adding to JSON. | |
-: 2916: | |
-: 2917: subroutine escape_string(str_in, str_out) | |
72: 2918: | |
-: 2919: implicit none | |
-: 2920: | |
-: 2921: character(kind=CK,len=*),intent(in) :: str_in | |
-: 2922: character(kind=CK,len=:),allocatable,intent(out) :: str_out | |
-: 2923: | |
-: 2924: integer(IK) :: i,ipos | |
-: 2925: character(kind=CK,len=1) :: c | |
-: 2926: | |
-: 2927: character(kind=CK,len=*),parameter :: specials = quotation_mark//& | |
-: 2928: backslash//& | |
-: 2929: slash//& | |
-: 2930: bspace//& | |
-: 2931: formfeed//& | |
-: 2932: newline//& | |
-: 2933: carriage_return//& | |
-: 2934: horizontal_tab | |
-: 2935: | |
-: 2936: !Do a quick scan for the special characters, | |
-: 2937: ! if any are present, then process the string, | |
-: 2938: ! otherwise, return the string as is. | |
-: 2939: if (scan(str_in,specials)>0) then | |
36: 2940: | |
-: 2941: str_out = repeat(space,chunk_size) | |
4: 2942: ipos = 1 | |
4: 2943: | |
-: 2944: !go through the string and look for special characters: | |
-: 2945: do i=1,len(str_in) | |
23: 2946: | |
-: 2947: c = str_in(i:i) !get next character in the input string | |
19: 2948: | |
-: 2949: !if the string is not big enough, then add another chunk: | |
-: 2950: if (ipos+3>len(str_out)) str_out = str_out // repeat(space, chunk_size) | |
19: 2951: | |
-: 2952: select case(c) | |
-: 2953: case(quotation_mark,backslash,slash) | |
-: 2954: str_out(ipos:ipos+1) = backslash//c | |
5: 2955: ipos = ipos + 2 | |
5: 2956: case(bspace) | |
-: 2957: str_out(ipos:ipos+1) = '\b' | |
1: 2958: ipos = ipos + 2 | |
1: 2959: case(formfeed) | |
-: 2960: str_out(ipos:ipos+1) = '\f' | |
1: 2961: ipos = ipos + 2 | |
1: 2962: case(newline) | |
-: 2963: str_out(ipos:ipos+1) = '\n' | |
1: 2964: ipos = ipos + 2 | |
1: 2965: case(carriage_return) | |
-: 2966: str_out(ipos:ipos+1) = '\r' | |
1: 2967: ipos = ipos + 2 | |
1: 2968: case(horizontal_tab) | |
-: 2969: str_out(ipos:ipos+1) = '\t' | |
1: 2970: ipos = ipos + 2 | |
1: 2971: case default | |
-: 2972: str_out(ipos:ipos) = c | |
9: 2973: ipos = ipos + 1 | |
28: 2974: end select | |
-: 2975: | |
-: 2976: end do | |
-: 2977: | |
-: 2978: !trim the string if necessary: | |
-: 2979: if (ipos<len(str_out)+1) then | |
4: 2980: if (ipos==1) then | |
4: 2981: str_out = '' | |
#####: 2982: else | |
-: 2983: str_out = str_out(1:ipos-1) | |
4: 2984: end if | |
-: 2985: end if | |
-: 2986: | |
-: 2987: else | |
-: 2988: | |
-: 2989: str_out = str_in | |
32: 2990: | |
-: 2991: end if | |
-: 2992: | |
-: 2993: end subroutine escape_string | |
72: 2994:!***************************************************************************************** | |
-: 2995: | |
-: 2996:!***************************************************************************************** | |
-: 2997:!> author: Jacob Williams | |
-: 2998:! date: 1/19/2014 | |
-: 2999:! | |
-: 3000:! Add an array of character strings to the structure. | |
-: 3001:! | |
-: 3002:!@note This routine is part of the public API that can be | |
-: 3003:! used to build a JSON structure using [[json_value]] pointers. | |
-: 3004: | |
-: 3005: subroutine json_value_add_string_vec(me, name, val, trim_str, adjustl_str) | |
6: 3006: | |
-: 3007: implicit none | |
-: 3008: | |
-: 3009: type(json_value),pointer :: me | |
-: 3010: character(kind=CK,len=*),intent(in) :: name !! variable name | |
-: 3011: character(kind=CK,len=*),dimension(:),intent(in) :: val !! array of strings | |
-: 3012: logical(LK),intent(in),optional :: trim_str !! if TRIM() should be called for each element | |
-: 3013: logical(LK),intent(in),optional :: adjustl_str !! if ADJUSTL() should be called for each element | |
-: 3014: | |
-: 3015: type(json_value),pointer :: var | |
-: 3016: integer(IK) :: i | |
-: 3017: logical(LK) :: trim_string, adjustl_string | |
-: 3018: character(kind=CK,len=:),allocatable :: str | |
3: 3019: | |
-: 3020: !if the string is to be trimmed or not: | |
-: 3021: if (present(trim_str)) then | |
3: 3022: trim_string = trim_str | |
1: 3023: else | |
-: 3024: trim_string = .false. | |
2: 3025: end if | |
-: 3026: if (present(adjustl_str)) then | |
3: 3027: adjustl_string = adjustl_str | |
1: 3028: else | |
-: 3029: adjustl_string = .false. | |
2: 3030: end if | |
-: 3031: | |
-: 3032: !create the variable as an array: | |
-: 3033: call json_value_create(var) | |
3: 3034: call to_array(var,name) | |
3: 3035: | |
-: 3036: !populate the array: | |
-: 3037: do i=1,size(val) | |
13: 3038: | |
-: 3039: !the string to write: | |
-: 3040: str = val(i) | |
10: 3041: if (adjustl_string) str = adjustl(str) | |
10: 3042: if (trim_string) str = trim(str) | |
10: 3043: | |
-: 3044: !write it: | |
-: 3045: call json_add(var, '', str) | |
10: 3046: | |
-: 3047: !cleanup | |
-: 3048: deallocate(str) | |
10: 3049: | |
-: 3050: end do | |
-: 3051: | |
-: 3052: !add it: | |
-: 3053: call json_add(me, var) | |
3: 3054: | |
-: 3055: !cleanup: | |
-: 3056: nullify(var) | |
3: 3057: | |
-: 3058: end subroutine json_value_add_string_vec | |
6: 3059:!***************************************************************************************** | |
-: 3060: | |
-: 3061:!***************************************************************************************** | |
-: 3062:!> | |
-: 3063:! Alternate version of [[json_value_add_string_vec]] where "name" and "val" are kind=CDK. | |
-: 3064: | |
-: 3065: subroutine wrap_json_value_add_string_vec(me, name, val, trim_str, adjustl_str) | |
6: 3066: | |
-: 3067: implicit none | |
-: 3068: | |
-: 3069: type(json_value),pointer :: me | |
-: 3070: character(kind=CDK,len=*),intent(in) :: name | |
-: 3071: character(kind=CDK,len=*),dimension(:),intent(in) :: val | |
-: 3072: logical(LK),intent(in),optional :: trim_str | |
-: 3073: logical(LK),intent(in),optional :: adjustl_str | |
-: 3074: | |
-: 3075: call json_value_add_string_vec(me, to_unicode(name), to_unicode(val), trim_str, adjustl_str) | |
3: 3076: | |
-: 3077: end subroutine wrap_json_value_add_string_vec | |
6: 3078:!***************************************************************************************** | |
-: 3079: | |
-: 3080:!***************************************************************************************** | |
-: 3081:!> | |
-: 3082:! Alternate version of [[json_value_add_string_vec]] where "name" is kind=CDK. | |
-: 3083: | |
-: 3084: subroutine json_value_add_string_vec_name_ascii(me, name, val, trim_str, adjustl_str) | |
#####: 3085: | |
-: 3086: implicit none | |
-: 3087: | |
-: 3088: type(json_value),pointer :: me | |
-: 3089: character(kind=CDK,len=*),intent(in) :: name | |
-: 3090: character(kind=CK, len=*),dimension(:),intent(in) :: val | |
-: 3091: logical(LK),intent(in),optional :: trim_str | |
-: 3092: logical(LK),intent(in),optional :: adjustl_str | |
-: 3093: | |
-: 3094: call json_value_add_string_vec(me, to_unicode(name), val, trim_str, adjustl_str) | |
#####: 3095: | |
-: 3096: end subroutine json_value_add_string_vec_name_ascii | |
#####: 3097:!***************************************************************************************** | |
-: 3098: | |
-: 3099:!***************************************************************************************** | |
-: 3100:!> | |
-: 3101:! Alternate version of [[json_value_add_string_vec]] where "val" is kind=CDK. | |
-: 3102: | |
-: 3103: subroutine json_value_add_string_vec_val_ascii(me, name, val, trim_str, adjustl_str) | |
#####: 3104: | |
-: 3105: implicit none | |
-: 3106: | |
-: 3107: type(json_value),pointer :: me | |
-: 3108: character(kind=CK, len=*),intent(in) :: name | |
-: 3109: character(kind=CDK,len=*),dimension(:),intent(in) :: val | |
-: 3110: logical(LK),intent(in),optional :: trim_str | |
-: 3111: logical(LK),intent(in),optional :: adjustl_str | |
-: 3112: | |
-: 3113: call json_value_add_string_vec(me, name, to_unicode(val), trim_str, adjustl_str) | |
#####: 3114: | |
-: 3115: end subroutine json_value_add_string_vec_val_ascii | |
#####: 3116:!***************************************************************************************** | |
-: 3117: | |
-: 3118:!***************************************************************************************** | |
-: 3119:!> | |
-: 3120:! Count the number of children. | |
-: 3121:! | |
-: 3122:!# History | |
-: 3123:! * JW : 1/4/2014 : Original routine removed. | |
-: 3124:! Now using n_children variable. | |
-: 3125:! Renamed from json_value_count. | |
-: 3126: | |
-: 3127: pure function json_count(me) result(count) | |
208: 3128: | |
-: 3129: implicit none | |
-: 3130: | |
-: 3131: integer(IK) :: count !! number of children | |
-: 3132: type(json_value),pointer,intent(in) :: me | |
-: 3133: | |
-: 3134: count = me%n_children | |
208: 3135: | |
-: 3136: end function json_count | |
208: 3137:!***************************************************************************************** | |
-: 3138: | |
-: 3139:!***************************************************************************************** | |
-: 3140:!> | |
-: 3141:! Returns a child in the object or array given the index. | |
-: 3142: | |
-: 3143: subroutine json_value_get_by_index(me, idx, p) | |
29: 3144: | |
-: 3145: implicit none | |
-: 3146: | |
-: 3147: type(json_value),pointer,intent(in) :: me !! object or array JSON data | |
-: 3148: integer(IK),intent(in) :: idx !! index of the child | |
-: 3149: type(json_value),pointer :: p !! pointer to the child | |
-: 3150: | |
-: 3151: integer(IK) :: i | |
-: 3152: | |
-: 3153: nullify(p) | |
29: 3154: | |
-: 3155: if (.not. exception_thrown) then | |
29: 3156: | |
-: 3157: if (associated(me%children)) then | |
29: 3158: | |
-: 3159: p => me%children | |
29: 3160: | |
-: 3161: do i = 1, idx - 1 | |
63: 3162: | |
-: 3163: if (associated(p%next)) then | |
35: 3164: p => p%next | |
34: 3165: else | |
-: 3166: call throw_exception('Error in json_value_get_by_index:'//& | |
-: 3167: ' p%next is not associated.') | |
1: 3168: nullify(p) | |
1: 3169: return | |
1: 3170: end if | |
-: 3171: | |
-: 3172: end do | |
-: 3173: | |
-: 3174: else | |
-: 3175: | |
-: 3176: call throw_exception('Error in json_value_get_by_index:'//& | |
-: 3177: ' me%children is not associated.') | |
#####: 3178: | |
-: 3179: end if | |
-: 3180: | |
-: 3181: end if | |
-: 3182: | |
-: 3183: end subroutine json_value_get_by_index | |
-: 3184:!***************************************************************************************** | |
-: 3185: | |
-: 3186:!***************************************************************************************** | |
-: 3187:!> | |
-: 3188:! Returns a child in the object or array given the name string. | |
-: 3189:! | |
-: 3190:! It is a case-sensitive search, and the name string is not trimmed. | |
-: 3191:! So, for example, | |
-: 3192:!```fortran | |
-: 3193:! 'a ' /= 'A ' /= 'a ' | |
-: 3194:!``` | |
-: 3195:! | |
-: 3196:!@note The "name" input is not a path, and is not parsed like it is in [[json_get_by_path]]. | |
-: 3197: | |
-: 3198: subroutine json_value_get_by_name_chars(me, name, p) | |
95: 3199: | |
-: 3200: implicit none | |
-: 3201: | |
-: 3202: type(json_value),pointer,intent(in) :: me | |
-: 3203: character(kind=CK,len=*),intent(in) :: name !! the name of a child of "me" | |
-: 3204: type(json_value),pointer :: p !! pointer to the child | |
-: 3205: | |
-: 3206: integer(IK) :: i,n_children | |
-: 3207: | |
-: 3208: nullify(p) | |
95: 3209: | |
-: 3210: if (.not. exception_thrown) then | |
95: 3211: | |
-: 3212: if (associated(me)) then | |
95: 3213: | |
-: 3214: if (me%var_type==json_object) then | |
95: 3215: n_children = json_count(me) | |
95: 3216: p => me%children !start with first one | |
95: 3217: do i=1, n_children | |
380: 3218: if (allocated(p%name)) then | |
376: 3219: if (p%name == name) return | |
376: 3220: end if | |
-: 3221: p => p%next | |
285: 3222: end do | |
-: 3223: end if | |
-: 3224: | |
-: 3225: !did not find anything: | |
-: 3226: call throw_exception('Error in json_value_get_by_name_chars: '//& | |
-: 3227: 'child variable '//trim(name)//' was not found.') | |
4: 3228: nullify(p) | |
4: 3229: | |
-: 3230: else | |
-: 3231: call throw_exception('Error in json_value_get_by_name_chars: '//& | |
-: 3232: 'pointer is not associated.') | |
#####: 3233: end if | |
-: 3234: | |
-: 3235: end if | |
-: 3236: | |
-: 3237: end subroutine json_value_get_by_name_chars | |
95: 3238:!***************************************************************************************** | |
-: 3239: | |
-: 3240:!***************************************************************************************** | |
-: 3241:!> | |
-: 3242:! Alternate version of [[json_value_get_by_name_chars]] where "name" is kind=CDK. | |
-: 3243: | |
-: 3244: subroutine wrap_json_value_get_by_name_chars(me, name, p) | |
1: 3245: | |
-: 3246: implicit none | |
-: 3247: | |
-: 3248: type(json_value),pointer,intent(in) :: me | |
-: 3249: character(kind=CDK,len=*),intent(in) :: name | |
-: 3250: type(json_value),pointer :: p | |
-: 3251: | |
-: 3252: call json_value_get_by_name_chars(me,to_unicode(name),p) | |
1: 3253: | |
-: 3254: end subroutine wrap_json_value_get_by_name_chars | |
2: 3255:!***************************************************************************************** | |
-: 3256: | |
-: 3257:!***************************************************************************************** | |
-: 3258:!> author: Jacob Williams | |
-: 3259:! date: 2/12/2014 | |
-: 3260:! | |
-: 3261:! Print the [[json_value]] structure to an allocatable string. | |
-: 3262: | |
-: 3263: subroutine json_value_to_string(me,str) | |
4: 3264: | |
-: 3265: implicit none | |
-: 3266: | |
-: 3267: type(json_value),pointer,intent(in) :: me | |
-: 3268: character(kind=CK,len=:),intent(out),allocatable :: str !! prints structure to this string | |
-: 3269: | |
-: 3270: str = '' | |
4: 3271: call json_value_print(me, iunit=unit2str, str=str, indent=1, colon=.true.) | |
4: 3272: | |
-: 3273: end subroutine json_value_to_string | |
4: 3274:!***************************************************************************************** | |
-: 3275: | |
-: 3276:!***************************************************************************************** | |
-: 3277:!> author: Jacob Williams | |
-: 3278:! date: 6/20/2014 | |
-: 3279:! | |
-: 3280:! Print the [[json_value]] structure to a file. | |
-: 3281: | |
-: 3282: subroutine json_print_1(me,iunit) | |
7: 3283: | |
-: 3284: implicit none | |
-: 3285: | |
-: 3286: type(json_value),pointer,intent(in) :: me | |
-: 3287: integer(IK),intent(in) :: iunit !! the file unit (the file must already have been opened, can't be -1). | |
-: 3288: | |
-: 3289: character(kind=CK,len=:),allocatable :: dummy | |
7: 3290: | |
-: 3291: if (iunit/=unit2str) then | |
7: 3292: call json_value_print(me,iunit,str=dummy, indent=1, colon=.true.) | |
7: 3293: else | |
-: 3294: call throw_exception('Error in json_print: iunit must not be -1.') | |
#####: 3295: end if | |
-: 3296: | |
-: 3297: end subroutine json_print_1 | |
7: 3298:!***************************************************************************************** | |
-: 3299: | |
-: 3300:!***************************************************************************************** | |
-: 3301:!> author: Jacob Williams | |
-: 3302:! date: 12/23/2014 | |
-: 3303:! | |
-: 3304:! Print the [[json_value]] structure to a file. | |
-: 3305: | |
-: 3306: subroutine json_print_2(me,filename) | |
1: 3307: | |
-: 3308: implicit none | |
-: 3309: | |
-: 3310: type(json_value),pointer,intent(in) :: me | |
-: 3311: character(kind=CDK,len=*),intent(in) :: filename !! the filename to print to (should not already be open) | |
-: 3312: | |
-: 3313: integer(IK) :: iunit,istat | |
-: 3314: | |
-: 3315: open(newunit=iunit,file=filename,status='REPLACE',iostat=istat FILE_ENCODING ) | |
1: 3316: if (istat==0) then | |
1: 3317: call json_print(me,iunit) | |
1: 3318: close(iunit,iostat=istat) | |
1: 3319: else | |
-: 3320: call throw_exception('Error in json_print: could not open file: '//& | |
-: 3321: trim(filename)) | |
#####: 3322: end if | |
-: 3323: | |
-: 3324: end subroutine json_print_2 | |
2: 3325:!***************************************************************************************** | |
-: 3326: | |
-: 3327:!***************************************************************************************** | |
-: 3328:!> | |
-: 3329:! Print the JSON structure to a string or a file. | |
-: 3330:! | |
-: 3331:!# Notes | |
-: 3332:! * This is an internal routine called by the wrapper routines | |
-: 3333:! [[json_print]] and [[json_value_to_string]]. | |
-: 3334:! * The reason the str argument is non-optional is because of a | |
-: 3335:! bug in v4.9 of the gfortran compiler. | |
-: 3336: | |
-: 3337: recursive subroutine json_value_print(me,iunit,str,indent,need_comma,colon,is_array_element) | |
604: 3338: | |
-: 3339: implicit none | |
-: 3340: | |
-: 3341: type(json_value),pointer,intent(in) :: me | |
-: 3342: integer(IK),intent(in) :: iunit !! file unit to write to (6=console) | |
-: 3343: integer(IK),intent(in),optional :: indent !! indention level | |
-: 3344: logical(LK),intent(in),optional :: is_array_element !! if this is an array element | |
-: 3345: logical(LK),intent(in),optional :: need_comma !! if it needs a comma after it | |
-: 3346: logical(LK),intent(in),optional :: colon !! if the colon was just written | |
-: 3347: character(kind=CK,len=:),intent(inout),allocatable :: str | |
-: 3348: !! if iunit==unit2str (-1) then the structure is | |
-: 3349: !! printed to this string rather than | |
-: 3350: !! a file. This mode is used by | |
-: 3351: !! [[json_value_to_string]]. | |
-: 3352: | |
-: 3353: character(kind=CK,len=max_numeric_str_len) :: tmp !for val to string conversions | |
-: 3354: character(kind=CK,len=:),allocatable :: s | |
604: 3355: type(json_value),pointer :: element | |
-: 3356: integer(IK) :: tab, i, count, spaces | |
-: 3357: logical(LK) :: print_comma | |
-: 3358: logical(LK) :: write_file, write_string | |
-: 3359: logical(LK) :: is_array | |
-: 3360: | |
-: 3361: if (.not. exception_thrown) then | |
1208: 3362: | |
-: 3363: !whether to write a string or a file (one or the other): | |
-: 3364: write_string = (iunit==unit2str) | |
604: 3365: write_file = .not. write_string | |
604: 3366: | |
-: 3367: !if the comma will be printed after the value | |
-: 3368: ! [comma not printed for the last elements] | |
-: 3369: if (present(need_comma)) then | |
604: 3370: print_comma = need_comma | |
585: 3371: else | |
-: 3372: print_comma = .false. | |
19: 3373: end if | |
-: 3374: | |
-: 3375: !number of "tabs" to indent: | |
-: 3376: if (present(indent)) then | |
604: 3377: tab = indent | |
604: 3378: else | |
-: 3379: tab = 0 | |
#####: 3380: end if | |
-: 3381: !convert to number of spaces: | |
-: 3382: spaces = tab*spaces_per_tab | |
604: 3383: | |
-: 3384: !if this is an element in an array: | |
-: 3385: if (present(is_array_element)) then | |
604: 3386: is_array = is_array_element | |
94: 3387: else | |
-: 3388: is_array = .false. | |
510: 3389: end if | |
-: 3390: | |
-: 3391: !if the colon was the last thing written | |
-: 3392: if (present(colon)) then | |
604: 3393: s = '' | |
510: 3394: else | |
-: 3395: s = repeat(space, spaces) | |
94: 3396: end if | |
-: 3397: | |
-: 3398: select case (me%var_type) | |
604: 3399: | |
-: 3400: case (json_object) | |
-: 3401: | |
-: 3402: count = json_count(me) | |
67: 3403: | |
-: 3404: if (count==0) then !special case for empty object | |
134: 3405: | |
-: 3406: call write_it( s//start_object//end_object, comma=print_comma ) | |
4: 3407: | |
-: 3408: else | |
-: 3409: | |
-: 3410: call write_it( s//start_object ) | |
63: 3411: | |
-: 3412: !if an object is in an array, there is an extra tab: | |
-: 3413: if (is_array) then | |
63: 3414: tab = tab+1 | |
23: 3415: spaces = tab*spaces_per_tab | |
23: 3416: end if | |
-: 3417: | |
-: 3418: nullify(element) | |
63: 3419: element => me%children | |
63: 3420: do i = 1, count | |
554: 3421: | |
-: 3422: ! print the name | |
-: 3423: if (allocated(element%name)) then | |
491: 3424: call write_it(repeat(space, spaces)//quotation_mark//& | |
982: 3425: element%name//quotation_mark//colon_char//space,& | |
-: 3426: advance=.false.) | |
1473: 3427: else | |
-: 3428: call throw_exception('Error in json_value_print:'//& | |
-: 3429: ' element%name not allocated') | |
#####: 3430: nullify(element) | |
#####: 3431: return | |
#####: 3432: end if | |
-: 3433: | |
-: 3434: ! recursive print of the element | |
-: 3435: call json_value_print(element, iunit=iunit, indent=tab + 1, & | |
-: 3436: need_comma=i<count, colon=.true., str=str) | |
491: 3437: | |
-: 3438: ! get the next child the list: | |
-: 3439: element => element%next | |
491: 3440: | |
-: 3441: end do | |
-: 3442: | |
-: 3443: ! [one fewer tab if it isn't an array element] | |
-: 3444: if (.not. is_array) s = repeat(space, max(0,spaces-spaces_per_tab)) | |
63: 3445: call write_it( s//end_object, comma=print_comma ) | |
63: 3446: nullify(element) | |
63: 3447: | |
-: 3448: end if | |
-: 3449: | |
-: 3450: case (json_array) | |
-: 3451: | |
-: 3452: count = json_count(me) | |
36: 3453: | |
-: 3454: if (count==0) then !special case for empty array | |
72: 3455: | |
-: 3456: call write_it( s//start_array//end_array, comma=print_comma ) | |
4: 3457: | |
-: 3458: else | |
-: 3459: | |
-: 3460: call write_it( start_array ) | |
32: 3461: | |
-: 3462: nullify(element) | |
32: 3463: element => me%children | |
32: 3464: do i = 1, count | |
126: 3465: | |
-: 3466: ! recursive print of the element | |
-: 3467: call json_value_print(element, iunit=iunit, indent=tab,& | |
-: 3468: need_comma=i<count, is_array_element=.true., str=str) | |
94: 3469: | |
-: 3470: ! get the next child the list: | |
-: 3471: element => element%next | |
94: 3472: | |
-: 3473: end do | |
-: 3474: | |
-: 3475: !indent the closing array character: | |
-: 3476: call write_it( repeat(space, max(0,spaces-spaces_per_tab))//end_array,& | |
64: 3477: comma=print_comma ) | |
96: 3478: nullify(element) | |
32: 3479: | |
-: 3480: end if | |
-: 3481: | |
-: 3482: case (json_null) | |
-: 3483: | |
-: 3484: call write_it( s//null_str, comma=print_comma ) | |
4: 3485: | |
-: 3486: case (json_string) | |
-: 3487: | |
-: 3488: if (allocated(me%str_value)) then | |
376: 3489: call write_it( s//quotation_mark// & | |
-: 3490: trim(me%str_value)//quotation_mark, comma=print_comma ) | |
188: 3491: else | |
-: 3492: call throw_exception('Error in json_value_print:'//& | |
-: 3493: ' me%value_string not allocated') | |
#####: 3494: return | |
#####: 3495: end if | |
-: 3496: | |
-: 3497: case (json_logical) | |
-: 3498: | |
-: 3499: if (me%log_value) then | |
20: 3500: call write_it( s//true_str, comma=print_comma ) | |
6: 3501: else | |
-: 3502: call write_it( s//false_str, comma=print_comma ) | |
4: 3503: end if | |
-: 3504: | |
-: 3505: case (json_integer) | |
-: 3506: | |
-: 3507: call integer_to_string(me%int_value,tmp) | |
261: 3508: | |
-: 3509: call write_it( s//trim(tmp), comma=print_comma ) | |
261: 3510: | |
-: 3511: case (json_double) | |
-: 3512: | |
-: 3513: call real_to_string(me%dbl_value,tmp) | |
38: 3514: | |
-: 3515: call write_it( s//trim(tmp), comma=print_comma ) | |
38: 3516: | |
-: 3517: case default | |
-: 3518: | |
-: 3519: call throw_exception('Error in json_value_print: unknown data type') | |
604: 3520: | |
-: 3521: end select | |
-: 3522: | |
-: 3523: !cleanup: | |
-: 3524: if (allocated(s)) deallocate(s) | |
604: 3525: | |
-: 3526: end if | |
-: 3527: | |
-: 3528: contains | |
-: 3529: | |
-: 3530: ! | |
-: 3531: ! write the string to the file (or the output string) | |
-: 3532: ! | |
-: 3533: subroutine write_it(s,advance,comma) | |
1190: 3534: | |
-: 3535: implicit none | |
-: 3536: | |
-: 3537: character(kind=CK,len=*),intent(in) :: s !string to print | |
-: 3538: logical(LK),intent(in),optional :: advance !to add line break or not | |
-: 3539: logical(LK),intent(in),optional :: comma !print comma after the string | |
-: 3540: | |
-: 3541: logical(LK) :: add_line_break, add_comma | |
-: 3542: character(kind=CK,len=:),allocatable :: s2 | |
1190: 3543: | |
-: 3544: if (present(comma)) then | |
1190: 3545: add_comma = comma | |
604: 3546: else | |
-: 3547: add_comma = .false. !default is not to add comma | |
586: 3548: end if | |
-: 3549: | |
-: 3550: if (present(advance)) then | |
1190: 3551: add_line_break = advance | |
491: 3552: else | |
-: 3553: add_line_break = .true. !default is to advance | |
699: 3554: end if | |
-: 3555: | |
-: 3556: !string to print: | |
-: 3557: s2 = s | |
1190: 3558: if (add_comma) s2 = s2 // delimiter | |
1190: 3559: | |
-: 3560: if (write_file) then | |
1190: 3561: | |
-: 3562: if (add_line_break) then | |
895: 3563: write(iunit,fmt='(A)') s2 | |
546: 3564: else | |
-: 3565: write(iunit,fmt='(A)',advance='NO') s2 | |
349: 3566: end if | |
-: 3567: | |
-: 3568: else !write string | |
-: 3569: | |
-: 3570: str = str // s2 | |
295: 3571: if (add_line_break) str = str // newline | |
295: 3572: | |
-: 3573: end if | |
-: 3574: | |
-: 3575: !cleanup: | |
-: 3576: if (allocated(s2)) deallocate(s2) | |
1190: 3577: | |
-: 3578: end subroutine write_it | |
2380: 3579: | |
-: 3580: end subroutine json_value_print | |
-: 3581:!***************************************************************************************** | |
-: 3582: | |
-: 3583:!***************************************************************************************** | |
-: 3584:!> | |
-: 3585:! Returns the [[json_value]] pointer given the path string. | |
-: 3586:! | |
-: 3587:!# Example | |
-: 3588:! | |
-: 3589:!```fortran | |
-: 3590:! type(json_value),pointer :: dat,p | |
-: 3591:! logical :: found | |
-: 3592:! !... | |
-: 3593:! call json_get(dat,'data(2).version',p,found) | |
-: 3594:!``` | |
-: 3595:! | |
-: 3596:!# Notes | |
-: 3597:! The following special characters are used to denote paths: | |
-: 3598:! | |
-: 3599:!``` | |
-: 3600:! $ - root | |
-: 3601:! @ - this | |
-: 3602:! . - child object member | |
-: 3603:! [] or () - child array element | |
-: 3604:!``` | |
-: 3605:! | |
-: 3606:! Thus, if any of these characters are present in the name key, | |
-: 3607:! this routine cannot be used to get the value. | |
-: 3608:! In that case, the [[json_get_child]] routines would need to be used. | |
-: 3609: | |
-: 3610: subroutine json_get_by_path(me, path, p, found) | |
57: 3611: | |
-: 3612: implicit none | |
-: 3613: | |
-: 3614: type(json_value),pointer,intent(in) :: me | |
-: 3615: character(kind=CK,len=*),intent(in) :: path | |
-: 3616: type(json_value),pointer,intent(out) :: p | |
-: 3617: logical(LK),intent(out),optional :: found !! true if it was found | |
-: 3618: | |
-: 3619: character(kind=CK,len=1),parameter :: start_array_alt = '(' | |
-: 3620: character(kind=CK,len=1),parameter :: end_array_alt = ')' | |
-: 3621: | |
-: 3622: integer(IK) :: i,length,child_i | |
-: 3623: character(kind=CK,len=1) :: c | |
-: 3624: logical(LK) :: array | |
-: 3625: type(json_value),pointer :: tmp | |
-: 3626: | |
-: 3627: if (.not. exception_thrown) then | |
57: 3628: | |
-: 3629: nullify(p) | |
57: 3630: | |
-: 3631: ! default to assuming relative to this | |
-: 3632: p => me | |
57: 3633: | |
-: 3634: child_i = 1 | |
57: 3635: | |
-: 3636: array = .false. | |
57: 3637: | |
-: 3638: length = len_trim(path) | |
57: 3639: | |
-: 3640: do i=1, length | |
813: 3641: | |
-: 3642: c = path(i:i) | |
756: 3643: | |
-: 3644: select case (c) | |
-: 3645: case (CK_'$') | |
-: 3646: | |
-: 3647: ! root | |
-: 3648: do while (associated (p%parent)) | |
1: 3649: p => p%parent | |
#####: 3650: end do | |
-: 3651: child_i = i + 1 | |
1: 3652: | |
-: 3653: case (CK_'@') | |
-: 3654: | |
-: 3655: ! this | |
-: 3656: p => me | |
#####: 3657: child_i = i + 1 | |
#####: 3658: | |
-: 3659: case (CK_'.') | |
-: 3660: | |
-: 3661: ! get child member from p | |
-: 3662: if (child_i < i) then | |
38: 3663: nullify(tmp) | |
18: 3664: call json_get_child(p, path(child_i:i-1), tmp) | |
18: 3665: p => tmp | |
18: 3666: nullify(tmp) | |
18: 3667: else | |
-: 3668: child_i = i + 1 | |
20: 3669: cycle | |
20: 3670: end if | |
-: 3671: | |
-: 3672: if (.not. associated(p)) then | |
18: 3673: call throw_exception('Error in json_get_by_path:'//& | |
-: 3674: ' Error getting child member.') | |
#####: 3675: exit | |
#####: 3676: end if | |
-: 3677: | |
-: 3678: child_i = i+1 | |
18: 3679: | |
-: 3680: case (start_array,start_array_alt) | |
-: 3681: | |
-: 3682: !....Modified to allow for 'var[3]' style syntax | |
-: 3683: !Note: jmozmoz/fson has a slightly different version of this... | |
-: 3684: | |
-: 3685: ! start looking for the array element index | |
-: 3686: array = .true. | |
29: 3687: | |
-: 3688: ! get child member from p | |
-: 3689: if (child_i < i) then | |
29: 3690: nullify(tmp) | |
29: 3691: call json_get_child(p, path(child_i:i-1), tmp) | |
29: 3692: p => tmp | |
29: 3693: nullify(tmp) | |
29: 3694: else | |
-: 3695: child_i = i + 1 | |
#####: 3696: cycle | |
#####: 3697: end if | |
-: 3698: if (.not. associated(p)) then | |
29: 3699: call throw_exception('Error in json_get_by_path:'//& | |
-: 3700: ' Error getting array element') | |
#####: 3701: exit | |
#####: 3702: end if | |
-: 3703: child_i = i + 1 | |
29: 3704: | |
-: 3705: case (end_array,end_array_alt) | |
-: 3706: | |
-: 3707: if (.not.array) then | |
29: 3708: call throw_exception('Error in json_get_by_path: Unexpected ]') | |
#####: 3709: exit | |
#####: 3710: end if | |
-: 3711: array = .false. | |
29: 3712: child_i = string_to_integer(path(child_i:i-1)) | |
29: 3713: | |
-: 3714: nullify(tmp) | |
29: 3715: call json_get_child(p, child_i, tmp) | |
29: 3716: p => tmp | |
29: 3717: nullify(tmp) | |
29: 3718: | |
-: 3719: child_i= i + 1 | |
785: 3720: | |
-: 3721: end select | |
-: 3722: | |
-: 3723: end do | |
-: 3724: | |
-: 3725: if (exception_thrown) then | |
57: 3726: | |
-: 3727: if (present(found)) then | |
1: 3728: found = .false. | |
#####: 3729: call json_clear_exceptions() | |
#####: 3730: end if | |
-: 3731: | |
-: 3732: else | |
-: 3733: | |
-: 3734: ! grab the last child if present in the path | |
-: 3735: if (child_i <= length) then | |
56: 3736: nullify(tmp) | |
47: 3737: call json_get_child(p, path(child_i:i-1), tmp) | |
47: 3738: p => tmp | |
47: 3739: nullify(tmp) | |
47: 3740: end if | |
-: 3741: if (associated(p)) then | |
56: 3742: if (present(found)) found = .true. !everything seems to be ok | |
52: 3743: else | |
-: 3744: call throw_exception('Error in json_get_by_path:'//& | |
-: 3745: ' variable not found: '//trim(path)) | |
4: 3746: if (present(found)) then | |
4: 3747: found = .false. | |
3: 3748: call json_clear_exceptions() | |
3: 3749: end if | |
-: 3750: end if | |
-: 3751: | |
-: 3752: end if | |
-: 3753: | |
-: 3754: else | |
-: 3755: if (present(found)) found = .false. | |
#####: 3756: end if | |
-: 3757: | |
-: 3758: end subroutine json_get_by_path | |
114: 3759:!***************************************************************************************** | |
-: 3760: | |
-: 3761:!***************************************************************************************** | |
-: 3762:!> | |
-: 3763:! Alternate version of [[json_get_by_path]] where "path" is kind=CDK. | |
-: 3764: | |
-: 3765: subroutine wrap_json_get_by_path(me, path, p, found) | |
1: 3766: | |
-: 3767: implicit none | |
-: 3768: | |
-: 3769: type(json_value),pointer,intent(in) :: me | |
-: 3770: character(kind=CDK,len=*),intent(in) :: path | |
-: 3771: type(json_value),pointer,intent(out) :: p | |
-: 3772: logical(LK),intent(out),optional :: found | |
-: 3773: | |
-: 3774: call json_get_by_path(me, to_unicode(path), p, found) | |
1: 3775: | |
-: 3776: end subroutine wrap_json_get_by_path | |
2: 3777:!***************************************************************************************** | |
-: 3778: | |
-: 3779:!***************************************************************************************** | |
-: 3780:!> | |
-: 3781:! Convert a string into an integer. | |
-: 3782:! | |
-: 3783:!# History | |
-: 3784:! * Jacob Williams : 12/10/2013 : Rewrote routine. Added error checking. | |
-: 3785:! * Modified by Izaak Beekman | |
-: 3786:! | |
-: 3787:!@note Replacement for the parse_integer function in the original code. | |
-: 3788: | |
-: 3789: function string_to_integer(str) result(ival) | |
49916: 3790: | |
-: 3791: implicit none | |
-: 3792: | |
-: 3793: character(kind=CK,len=*),intent(in) :: str | |
-: 3794: integer(IK) :: ival | |
-: 3795: | |
-: 3796: character(kind=CDK,len=:),allocatable :: digits | |
49916: 3797: integer(IK) :: ndigits_digits,ndigits,ierr | |
-: 3798: | |
-: 3799: if (.not. exception_thrown) then | |
49916: 3800: | |
-: 3801: ! Compute how many digits we need to read | |
-: 3802: ndigits = 2*len_trim(str) | |
49916: 3803: ndigits_digits = floor(log10(real(ndigits)))+1 | |
49916: 3804: allocate(character(kind=CDK,len=ndigits_digits) :: digits) | |
49916: 3805: write(digits,'(I0)') ndigits !gfortran will have a runtime error with * edit descriptor here | |
49916: 3806: ! gfortran bug: '*' edit descriptor for ISO_10646 strings does bad stuff. | |
-: 3807: read(str,'(I'//trim(digits)//')',iostat=ierr) ival !string to integer | |
49916: 3808: | |
-: 3809: if (ierr/=0) then !if there was an error | |
49916: 3810: ival = 0 | |
#####: 3811: call throw_exception('Error in string_to_integer:'//& | |
-: 3812: ' string cannot be converted to an integer: '//trim(str)) | |
#####: 3813: end if | |
-: 3814: | |
-: 3815: else | |
-: 3816: ival = 0 | |
#####: 3817: end if | |
-: 3818: | |
-: 3819: end function string_to_integer | |
99832: 3820:!***************************************************************************************** | |
-: 3821: | |
-: 3822:!***************************************************************************************** | |
-: 3823:!> author: Jacob Williams | |
-: 3824:! date: 1/19/2014 | |
-: 3825:! | |
-: 3826:! Convert a string into a double. | |
-: 3827: | |
-: 3828: function string_to_double(str) result(rval) | |
19933: 3829: | |
-: 3830: implicit none | |
-: 3831: | |
-: 3832: real(RK) :: rval | |
-: 3833: character(kind=CK,len=*),intent(in) :: str | |
-: 3834: | |
-: 3835: integer(IK) :: ierr | |
-: 3836: | |
-: 3837: if (.not. exception_thrown) then | |
19933: 3838: | |
-: 3839: read(str,fmt=real_fmt,iostat=ierr) rval !string to double | |
19933: 3840: | |
-: 3841: if (ierr/=0) then !if there was an error | |
19933: 3842: rval = 0.0_RK | |
#####: 3843: call throw_exception('Error in string_to_double:'//& | |
-: 3844: ' string cannot be converted to a double: '//trim(str)) | |
#####: 3845: end if | |
-: 3846: | |
-: 3847: end if | |
-: 3848: | |
-: 3849: end function string_to_double | |
39866: 3850:!***************************************************************************************** | |
-: 3851: | |
-: 3852:!***************************************************************************************** | |
-: 3853:!> | |
-: 3854:! Get an integer value from a [[json_value]]. | |
-: 3855: | |
-: 3856: subroutine json_get_integer(me, value) | |
5: 3857: | |
-: 3858: implicit none | |
-: 3859: | |
-: 3860: type(json_value),pointer,intent(in) :: me | |
-: 3861: integer(IK),intent(out) :: value | |
-: 3862: | |
-: 3863: value = 0 | |
5: 3864: if ( exception_thrown ) return | |
5: 3865: | |
-: 3866: select case(me%var_type) | |
5: 3867: case (json_integer) | |
-: 3868: value = me%int_value | |
5: 3869: case (json_double) | |
-: 3870: value = int(me%dbl_value) | |
#####: 3871: case (json_logical) | |
-: 3872: if (me%log_value) then | |
#####: 3873: value = 1 | |
#####: 3874: else | |
-: 3875: value = 0 | |
#####: 3876: end if | |
-: 3877: case default | |
-: 3878: call throw_exception('Error in get_integer:'//& | |
-: 3879: ' Unable to resolve value to integer: '//me%name) | |
5: 3880: end select | |
-: 3881: | |
-: 3882: end subroutine json_get_integer | |
-: 3883:!***************************************************************************************** | |
-: 3884: | |
-: 3885:!***************************************************************************************** | |
-: 3886:!> | |
-: 3887:! Get an integer value from a [[json_value]], given the path string. | |
-: 3888: | |
-: 3889: subroutine json_get_integer_with_path(me, path, value, found) | |
4: 3890: | |
-: 3891: implicit none | |
-: 3892: | |
-: 3893: type(json_value),pointer,intent(in) :: me | |
-: 3894: character(kind=CK,len=*),intent(in) :: path | |
-: 3895: integer(IK),intent(out) :: value | |
-: 3896: logical(LK),intent(out),optional :: found | |
-: 3897: | |
-: 3898: type(json_value),pointer :: p | |
-: 3899: | |
-: 3900: value = 0 | |
4: 3901: if ( exception_thrown ) then | |
4: 3902: if ( present(found) ) found = .false. | |
#####: 3903: return | |
#####: 3904: end if | |
-: 3905: | |
-: 3906: nullify(p) | |
4: 3907: | |
-: 3908: call json_get_by_path(me=me, path=path, p=p) | |
4: 3909: | |
-: 3910: if (.not. associated(p)) then | |
4: 3911: call throw_exception('Error in json_get_integer:'//& | |
-: 3912: ' Unable to resolve path: '// trim(path)) | |
1: 3913: else | |
-: 3914: call json_get_integer(p,value) | |
3: 3915: nullify(p) | |
3: 3916: end if | |
-: 3917: if ( exception_thrown ) then | |
4: 3918: if ( present(found) ) then | |
1: 3919: found = .false. | |
1: 3920: call json_clear_exceptions() | |
1: 3921: end if | |
-: 3922: else | |
-: 3923: if ( present(found) ) found = .true. | |
3: 3924: end if | |
-: 3925: | |
-: 3926: end subroutine json_get_integer_with_path | |
4: 3927:!***************************************************************************************** | |
-: 3928: | |
-: 3929:!***************************************************************************************** | |
-: 3930:!> | |
-: 3931:! Alternate version of [[json_get_integer_with_path]], where "path" is kind=CDK. | |
-: 3932: | |
-: 3933: subroutine wrap_json_get_integer_with_path(me, path, value, found) | |
#####: 3934: | |
-: 3935: implicit none | |
-: 3936: | |
-: 3937: type(json_value),pointer,intent(in) :: me | |
-: 3938: character(kind=CDK,len=*),intent(in) :: path | |
-: 3939: integer(IK),intent(out) :: value | |
-: 3940: logical(LK),intent(out),optional :: found | |
-: 3941: | |
-: 3942: call json_get_integer_with_path(me, to_unicode(path), value, found) | |
#####: 3943: | |
-: 3944: end subroutine wrap_json_get_integer_with_path | |
#####: 3945:!***************************************************************************************** | |
-: 3946: | |
-: 3947:!***************************************************************************************** | |
-: 3948:!> author: Jacob Williams | |
-: 3949:! date: 5/14/2014 | |
-: 3950:! | |
-: 3951:! Get an integer vector from a [[json_value]]. | |
-: 3952: | |
-: 3953: subroutine json_get_integer_vec(me, vec) | |
#####: 3954: | |
-: 3955: implicit none | |
-: 3956: | |
-: 3957: type(json_value),pointer :: me | |
-: 3958: integer(IK),dimension(:),allocatable,intent(out) :: vec | |
-: 3959: | |
-: 3960: logical(LK) :: initialized | |
-: 3961: | |
-: 3962: initialized = .false. | |
#####: 3963: | |
-: 3964: if (allocated(vec)) deallocate(vec) | |
#####: 3965: | |
-: 3966: !the callback function is called for each element of the array: | |
-: 3967: call json_get(me, array_callback=get_int_from_array) | |
#####: 3968: | |
-: 3969: contains | |
-: 3970: | |
-: 3971: ! callback function for integer | |
-: 3972: subroutine get_int_from_array(element, i, count) | |
#####: 3973: implicit none | |
-: 3974: | |
-: 3975: type(json_value),pointer,intent(in) :: element | |
-: 3976: integer(IK),intent(in) :: i !index | |
-: 3977: integer(IK),intent(in) :: count !size of array | |
-: 3978: | |
-: 3979: !size the output array: | |
-: 3980: if (.not. initialized) then | |
#####: 3981: allocate(vec(count)) | |
#####: 3982: initialized = .true. | |
#####: 3983: end if | |
-: 3984: | |
-: 3985: !populate the elements: | |
-: 3986: call json_get(element, value=vec(i)) | |
#####: 3987: | |
-: 3988: end subroutine get_int_from_array | |
#####: 3989: | |
-: 3990: end subroutine json_get_integer_vec | |
-: 3991:!***************************************************************************************** | |
-: 3992: | |
-: 3993:!***************************************************************************************** | |
-: 3994:!> | |
-: 3995:! Get an integer vector from a [[json_value]], given the path string. | |
-: 3996: | |
-: 3997: subroutine json_get_integer_vec_with_path(me, path, vec, found) | |
1: 3998: | |
-: 3999: implicit none | |
-: 4000: | |
-: 4001: type(json_value),pointer :: me | |
-: 4002: character(kind=CK,len=*),intent(in) :: path | |
-: 4003: integer(IK),dimension(:),allocatable,intent(out) :: vec | |
-: 4004: logical(LK),intent(out),optional :: found | |
-: 4005: | |
-: 4006: logical(LK) :: initialized | |
-: 4007: | |
-: 4008: initialized = .false. | |
1: 4009: | |
-: 4010: call json_get(me, path=path, array_callback=get_int_from_array, found=found) | |
2: 4011: | |
-: 4012: ! need to duplicate callback function, no other way | |
-: 4013: contains | |
-: 4014: | |
-: 4015: ! callback function for integer | |
-: 4016: subroutine get_int_from_array(element, i, count) | |
2: 4017: implicit none | |
-: 4018: | |
-: 4019: type(json_value),pointer,intent(in) :: element | |
-: 4020: integer(IK),intent(in) :: i !index | |
-: 4021: integer(IK),intent(in) :: count !size of array | |
-: 4022: | |
-: 4023: !size the output array: | |
-: 4024: if (.not. initialized) then | |
2: 4025: allocate(vec(count)) | |
1: 4026: initialized = .true. | |
1: 4027: end if | |
-: 4028: | |
-: 4029: !populate the elements: | |
-: 4030: call json_get(element, value=vec(i)) | |
2: 4031: | |
-: 4032: end subroutine get_int_from_array | |
2: 4033: | |
-: 4034: end subroutine json_get_integer_vec_with_path | |
-: 4035:!***************************************************************************************** | |
-: 4036: | |
-: 4037:!***************************************************************************************** | |
-: 4038:!> | |
-: 4039:! Alternate version of [[json_get_integer_vec_with_path]], where "path" is kind=CDK | |
-: 4040: | |
-: 4041: subroutine wrap_json_get_integer_vec_with_path(me, path, vec, found) | |
#####: 4042: | |
-: 4043: implicit none | |
-: 4044: | |
-: 4045: type(json_value),pointer :: me | |
-: 4046: character(kind=CDK,len=*),intent(in) :: path | |
-: 4047: integer(IK),dimension(:),allocatable,intent(out) :: vec | |
-: 4048: logical(LK),intent(out),optional :: found | |
-: 4049: | |
-: 4050: call json_get_integer_vec_with_path(me,path=to_unicode(path),vec=vec,found=found) | |
#####: 4051: | |
-: 4052: end subroutine wrap_json_get_integer_vec_with_path | |
#####: 4053:!***************************************************************************************** | |
-: 4054: | |
-: 4055:!***************************************************************************************** | |
-: 4056:!> | |
-: 4057:! Get a double value from a [[json_value]]. | |
-: 4058: | |
-: 4059: subroutine json_get_double(me, value) | |
15: 4060: | |
-: 4061: implicit none | |
-: 4062: | |
-: 4063: type(json_value),pointer :: me | |
-: 4064: real(RK),intent(out) :: value | |
-: 4065: | |
-: 4066: value = 0.0_RK | |
15: 4067: if ( exception_thrown ) return | |
15: 4068: | |
-: 4069: select case (me%var_type) | |
15: 4070: case (json_integer) | |
-: 4071: value = me%int_value | |
#####: 4072: case (json_double) | |
-: 4073: value = me%dbl_value | |
15: 4074: case (json_logical) | |
-: 4075: if (me%log_value) then | |
#####: 4076: value = 1.0_RK | |
#####: 4077: else | |
-: 4078: value = 0.0_RK | |
#####: 4079: end if | |
-: 4080: case default | |
-: 4081: | |
-: 4082: call throw_exception('Error in json_get_double:'//& | |
-: 4083: ' Unable to resolve value to double: '//me%name) | |
15: 4084: | |
-: 4085: end select | |
-: 4086: | |
-: 4087: end subroutine json_get_double | |
-: 4088:!***************************************************************************************** | |
-: 4089: | |
-: 4090:!***************************************************************************************** | |
-: 4091:!> | |
-: 4092:! Get a double value from a [[json_value]], given the path. | |
-: 4093: | |
-: 4094: subroutine json_get_double_with_path(me, path, value, found) | |
3: 4095: | |
-: 4096: implicit none | |
-: 4097: | |
-: 4098: type(json_value),pointer :: me | |
-: 4099: character(kind=CK,len=*),intent(in) :: path | |
-: 4100: real(RK),intent(out) :: value | |
-: 4101: logical(LK),intent(out),optional :: found | |
-: 4102: | |
-: 4103: type(json_value),pointer :: p | |
-: 4104: | |
-: 4105: value = 0.0_RK | |
3: 4106: if ( exception_thrown ) then | |
3: 4107: if ( present(found) ) found = .false. | |
#####: 4108: return | |
#####: 4109: end if | |
-: 4110: | |
-: 4111: nullify(p) | |
3: 4112: | |
-: 4113: call json_get_by_path(me=me, path=path, p=p) | |
3: 4114: | |
-: 4115: if (.not. associated(p)) then | |
3: 4116: | |
-: 4117: call throw_exception('Error in json_get_double:'//& | |
-: 4118: ' Unable to resolve path: '//trim(path)) | |
#####: 4119: | |
-: 4120: else | |
-: 4121: | |
-: 4122: call json_get_double(p,value) | |
3: 4123: nullify(p) | |
3: 4124: | |
-: 4125: end if | |
-: 4126: | |
-: 4127: if (exception_thrown) then | |
3: 4128: if (present(found)) then | |
#####: 4129: found = .false. | |
#####: 4130: call json_clear_exceptions() | |
#####: 4131: end if | |
-: 4132: else | |
-: 4133: if (present(found)) found = .true. | |
3: 4134: end if | |
-: 4135: | |
-: 4136: end subroutine json_get_double_with_path | |
3: 4137:!***************************************************************************************** | |
-: 4138: | |
-: 4139:!***************************************************************************************** | |
-: 4140:!> | |
-: 4141:! Alternate version of [[json_get_double_with_path]], where "path" is kind=CDK | |
-: 4142: | |
-: 4143: subroutine wrap_json_get_double_with_path(me, path, value, found) | |
#####: 4144: | |
-: 4145: implicit none | |
-: 4146: | |
-: 4147: type(json_value),pointer :: me | |
-: 4148: character(kind=CDK,len=*),intent(in) :: path | |
-: 4149: real(RK),intent(out) :: value | |
-: 4150: logical(LK),intent(out),optional :: found | |
-: 4151: | |
-: 4152: call json_get_double_with_path(me,to_unicode(path),value,found) | |
#####: 4153: | |
-: 4154: end subroutine wrap_json_get_double_with_path | |
#####: 4155:!***************************************************************************************** | |
-: 4156: | |
-: 4157:!***************************************************************************************** | |
-: 4158:!> author: Jacob Williams | |
-: 4159:! date: 5/14/2014 | |
-: 4160:! | |
-: 4161:! Get a double vector from a [[json_value]]. | |
-: 4162: | |
-: 4163: subroutine json_get_double_vec(me, vec) | |
#####: 4164: | |
-: 4165: implicit none | |
-: 4166: | |
-: 4167: type(json_value),pointer :: me | |
-: 4168: real(RK),dimension(:),allocatable,intent(out) :: vec | |
-: 4169: | |
-: 4170: logical(LK) :: initialized | |
-: 4171: | |
-: 4172: initialized = .false. | |
#####: 4173: | |
-: 4174: if (allocated(vec)) deallocate(vec) | |
#####: 4175: | |
-: 4176: !the callback function is called for each element of the array: | |
-: 4177: call json_get(me, array_callback=get_double_from_array) | |
#####: 4178: | |
-: 4179: contains | |
-: 4180: | |
-: 4181: ! callback function for double | |
-: 4182: subroutine get_double_from_array(element, i, count) | |
#####: 4183: implicit none | |
-: 4184: | |
-: 4185: type(json_value),pointer,intent(in) :: element | |
-: 4186: integer(IK),intent(in) :: i !index | |
-: 4187: integer(IK),intent(in) :: count !size of array | |
-: 4188: | |
-: 4189: !size the output array: | |
-: 4190: if (.not. initialized) then | |
#####: 4191: allocate(vec(count)) | |
#####: 4192: initialized = .true. | |
#####: 4193: end if | |
-: 4194: | |
-: 4195: !populate the elements: | |
-: 4196: call json_get(element, value=vec(i)) | |
#####: 4197: | |
-: 4198: end subroutine get_double_from_array | |
#####: 4199: | |
-: 4200: end subroutine json_get_double_vec | |
-: 4201:!***************************************************************************************** | |
-: 4202: | |
-: 4203:!***************************************************************************************** | |
-: 4204:!> | |
-: 4205:! Get a double vector from a [[json_value]], given the path. | |
-: 4206: | |
-: 4207: subroutine json_get_double_vec_with_path(me, path, vec, found) | |
4: 4208: | |
-: 4209: implicit none | |
-: 4210: | |
-: 4211: type(json_value),pointer :: me | |
-: 4212: character(kind=CK,len=*),intent(in) :: path | |
-: 4213: real(RK),dimension(:),allocatable,intent(out) :: vec | |
-: 4214: logical(LK),intent(out),optional :: found | |
-: 4215: | |
-: 4216: logical(LK) :: initialized | |
-: 4217: | |
-: 4218: initialized = .false. | |
4: 4219: | |
-: 4220: if (allocated(vec)) deallocate(vec) | |
4: 4221: | |
-: 4222: !the callback function is called for each element of the array: | |
-: 4223: call json_get(me, path=path, array_callback=get_double_from_array, found=found) | |
8: 4224: | |
-: 4225: contains | |
-: 4226: | |
-: 4227: ! callback function for double | |
-: 4228: subroutine get_double_from_array(element, i, count) | |
12: 4229: implicit none | |
-: 4230: | |
-: 4231: type(json_value),pointer,intent(in) :: element | |
-: 4232: integer(IK),intent(in) :: i !index | |
-: 4233: integer(IK),intent(in) :: count !size of array | |
-: 4234: | |
-: 4235: !size the output array: | |
-: 4236: if (.not. initialized) then | |
12: 4237: allocate(vec(count)) | |
4: 4238: initialized = .true. | |
4: 4239: end if | |
-: 4240: | |
-: 4241: !populate the elements: | |
-: 4242: call json_get(element, value=vec(i)) | |
12: 4243: | |
-: 4244: end subroutine get_double_from_array | |
12: 4245: | |
-: 4246: end subroutine json_get_double_vec_with_path | |
-: 4247:!***************************************************************************************** | |
-: 4248: | |
-: 4249:!***************************************************************************************** | |
-: 4250:!> | |
-: 4251:! Alternate version of [[json_get_double_vec_with_path]], where "path" is kind=CDK | |
-: 4252: | |
-: 4253: subroutine wrap_json_get_double_vec_with_path(me, path, vec, found) | |
#####: 4254: | |
-: 4255: implicit none | |
-: 4256: | |
-: 4257: type(json_value),pointer :: me | |
-: 4258: character(kind=CDK,len=*),intent(in) :: path | |
-: 4259: real(RK),dimension(:),allocatable,intent(out) :: vec | |
-: 4260: logical(LK),intent(out),optional :: found | |
-: 4261: | |
-: 4262: call json_get_double_vec_with_path(me, to_unicode(path), vec, found) | |
#####: 4263: | |
-: 4264: end subroutine wrap_json_get_double_vec_with_path | |
#####: 4265:!***************************************************************************************** | |
-: 4266: | |
-: 4267:!***************************************************************************************** | |
-: 4268:!> | |
-: 4269:! Get a logical value from a [[json_value]]. | |
-: 4270: | |
-: 4271: subroutine json_get_logical(me, value) | |
2: 4272: | |
-: 4273: implicit none | |
-: 4274: | |
-: 4275: type(json_value),pointer,intent(in) :: me | |
-: 4276: logical(LK) :: value | |
-: 4277: | |
-: 4278: value = .false. | |
2: 4279: if ( exception_thrown ) return | |
2: 4280: | |
-: 4281: select case (me%var_type) | |
2: 4282: case (json_integer) | |
-: 4283: value = (me%int_value > 0) | |
#####: 4284: case (json_logical) | |
-: 4285: value = me % log_value | |
2: 4286: case default | |
-: 4287: call throw_exception('Error in json_get_logical:'//& | |
-: 4288: ' Unable to resolve value to logical: '//me%name) | |
2: 4289: end select | |
-: 4290: | |
-: 4291: end subroutine json_get_logical | |
-: 4292:!***************************************************************************************** | |
-: 4293: | |
-: 4294:!***************************************************************************************** | |
-: 4295:!> | |
-: 4296:! Get a logical value from a [[json_value]], given the path. | |
-: 4297: | |
-: 4298: subroutine json_get_logical_with_path(me, path, value, found) | |
2: 4299: | |
-: 4300: implicit none | |
-: 4301: | |
-: 4302: type(json_value),pointer,intent(in) :: me | |
-: 4303: character(kind=CK,len=*),intent(in) :: path | |
-: 4304: logical(LK) :: value | |
-: 4305: logical(LK),intent(out),optional :: found | |
-: 4306: | |
-: 4307: type(json_value),pointer :: p | |
-: 4308: | |
-: 4309: value = .false. | |
2: 4310: if ( exception_thrown) then | |
2: 4311: if ( present(found) ) found = .false. | |
#####: 4312: return | |
#####: 4313: end if | |
-: 4314: | |
-: 4315: nullify(p) | |
2: 4316: | |
-: 4317: call json_get_by_path(me=me, path=path, p=p) | |
2: 4318: | |
-: 4319: if (.not. associated(p)) then | |
2: 4320: | |
-: 4321: call throw_exception('Error in json_get_logical:'//& | |
-: 4322: ' Unable to resolve path: '//trim(path)) | |
#####: 4323: | |
-: 4324: else | |
-: 4325: | |
-: 4326: call json_get_logical(p,value) | |
2: 4327: nullify(p) | |
2: 4328: | |
-: 4329: end if | |
-: 4330: | |
-: 4331: if (exception_thrown) then | |
2: 4332: if (present(found)) then | |
#####: 4333: found = .false. | |
#####: 4334: call json_clear_exceptions() | |
#####: 4335: end if | |
-: 4336: else | |
-: 4337: if (present(found)) found = .true. | |
2: 4338: end if | |
-: 4339: | |
-: 4340: end subroutine json_get_logical_with_path | |
2: 4341:!***************************************************************************************** | |
-: 4342: | |
-: 4343:!***************************************************************************************** | |
-: 4344:!> | |
-: 4345:! Alternate version of [[json_get_logical_with_path]], where "path" is kind=CDK | |
-: 4346: | |
-: 4347: subroutine wrap_json_get_logical_with_path(me, path, value, found) | |
1: 4348: | |
-: 4349: implicit none | |
-: 4350: | |
-: 4351: type(json_value),pointer,intent(in) :: me | |
-: 4352: character(kind=CDK,len=*),intent(in) :: path | |
-: 4353: logical(LK) :: value | |
-: 4354: logical(LK),intent(out),optional :: found | |
-: 4355: | |
-: 4356: call json_get_logical_with_path(me,to_unicode(path),value,found) | |
1: 4357: | |
-: 4358: end subroutine wrap_json_get_logical_with_path | |
2: 4359:!***************************************************************************************** | |
-: 4360: | |
-: 4361:!***************************************************************************************** | |
-: 4362:!> author: Jacob Williams | |
-: 4363:! date: 5/14/2014 | |
-: 4364:! | |
-: 4365:! Get a logical vector from [[json_value]]. | |
-: 4366: | |
-: 4367: subroutine json_get_logical_vec(me, vec) | |
#####: 4368: | |
-: 4369: implicit none | |
-: 4370: | |
-: 4371: type(json_value),pointer,intent(in) :: me | |
-: 4372: logical(LK),dimension(:),allocatable,intent(out) :: vec | |
-: 4373: | |
-: 4374: logical(LK) :: initialized | |
-: 4375: | |
-: 4376: initialized = .false. | |
#####: 4377: | |
-: 4378: if (allocated(vec)) deallocate(vec) | |
#####: 4379: | |
-: 4380: !the callback function is called for each element of the array: | |
-: 4381: call json_get(me, array_callback=get_logical_from_array) | |
#####: 4382: | |
-: 4383: contains | |
-: 4384: | |
-: 4385: ! callback function for logical | |
-: 4386: subroutine get_logical_from_array(element, i, count) | |
#####: 4387: implicit none | |
-: 4388: | |
-: 4389: type(json_value),pointer,intent(in) :: element | |
-: 4390: integer(IK),intent(in) :: i !index | |
-: 4391: integer(IK),intent(in) :: count !size of array | |
-: 4392: | |
-: 4393: !size the output array: | |
-: 4394: if (.not. initialized) then | |
#####: 4395: allocate(vec(count)) | |
#####: 4396: initialized = .true. | |
#####: 4397: end if | |
-: 4398: | |
-: 4399: !populate the elements: | |
-: 4400: call json_get(element, value=vec(i)) | |
#####: 4401: | |
-: 4402: end subroutine get_logical_from_array | |
#####: 4403: | |
-: 4404: end subroutine json_get_logical_vec | |
-: 4405:!***************************************************************************************** | |
-: 4406: | |
-: 4407:!***************************************************************************************** | |
-: 4408:!> | |
-: 4409:! Get a logical vector from a [[json_value]], given the path. | |
-: 4410: | |
-: 4411: subroutine json_get_logical_vec_with_path(me, path, vec, found) | |
#####: 4412: | |
-: 4413: implicit none | |
-: 4414: | |
-: 4415: type(json_value),pointer,intent(in) :: me | |
-: 4416: character(kind=CK,len=*),intent(in) :: path | |
-: 4417: logical(LK),dimension(:),allocatable,intent(out) :: vec | |
-: 4418: logical(LK),intent(out),optional :: found | |
-: 4419: | |
-: 4420: logical(LK) :: initialized | |
-: 4421: | |
-: 4422: initialized = .false. | |
#####: 4423: | |
-: 4424: if (allocated(vec)) deallocate(vec) | |
#####: 4425: | |
-: 4426: !the callback function is called for each element of the array: | |
-: 4427: call json_get(me, path=path, array_callback=get_logical_from_array, found=found) | |
#####: 4428: | |
-: 4429: contains | |
-: 4430: | |
-: 4431: ! callback function for logical | |
-: 4432: subroutine get_logical_from_array(element, i, count) | |
#####: 4433: implicit none | |
-: 4434: | |
-: 4435: type(json_value),pointer,intent(in) :: element | |
-: 4436: integer(IK),intent(in) :: i !index | |
-: 4437: integer(IK),intent(in) :: count !size of array | |
-: 4438: | |
-: 4439: !size the output array: | |
-: 4440: if (.not. initialized) then | |
#####: 4441: allocate(vec(count)) | |
#####: 4442: initialized = .true. | |
#####: 4443: end if | |
-: 4444: | |
-: 4445: !populate the elements: | |
-: 4446: call json_get(element, value=vec(i)) | |
#####: 4447: | |
-: 4448: end subroutine get_logical_from_array | |
#####: 4449: | |
-: 4450: end subroutine json_get_logical_vec_with_path | |
-: 4451:!***************************************************************************************** | |
-: 4452: | |
-: 4453:!***************************************************************************************** | |
-: 4454:!> | |
-: 4455:! Alternate version of [[json_get_logical_vec_with_path]], where "path" is kind=CDK | |
-: 4456: | |
-: 4457: subroutine wrap_json_get_logical_vec_with_path(me, path, vec, found) | |
#####: 4458: | |
-: 4459: implicit none | |
-: 4460: | |
-: 4461: type(json_value),pointer,intent(in) :: me | |
-: 4462: character(kind=CDK,len=*),intent(in) :: path | |
-: 4463: logical(LK),dimension(:),allocatable,intent(out) :: vec | |
-: 4464: logical(LK),intent(out),optional :: found | |
-: 4465: | |
-: 4466: call json_get_logical_vec_with_path(me,to_unicode(path),vec,found) | |
#####: 4467: | |
-: 4468: end subroutine wrap_json_get_logical_vec_with_path | |
#####: 4469:!***************************************************************************************** | |
-: 4470: | |
-: 4471:!***************************************************************************************** | |
-: 4472:!> | |
-: 4473:! Get a character string from a [[json_value]]. | |
-: 4474: | |
-: 4475: subroutine json_get_string(me, value) | |
36: 4476: | |
-: 4477: implicit none | |
-: 4478: | |
-: 4479: type(json_value),pointer,intent(in) :: me | |
-: 4480: character(kind=CK,len=:),allocatable,intent(out) :: value | |
-: 4481: | |
-: 4482: character(kind=CK ,len=:),allocatable :: s,pre,post | |
36: 4483: integer(IK) :: j,jprev,n | |
-: 4484: character(kind=CK,len=1) :: c | |
-: 4485: | |
-: 4486: value = '' | |
36: 4487: if ( exception_thrown) return | |
36: 4488: | |
-: 4489: select case (me%var_type) | |
36: 4490: | |
-: 4491: case (json_string) | |
-: 4492: | |
-: 4493: if (allocated(me%str_value)) then | |
72: 4494: | |
-: 4495: !get the value as is: | |
-: 4496: s = me%str_value | |
36: 4497: | |
-: 4498: ! Now, have to remove the escape characters: | |
-: 4499: ! | |
-: 4500: ! '\"' quotation mark | |
-: 4501: ! '\\' reverse solidus | |
-: 4502: ! '\/' solidus | |
-: 4503: ! '\b' backspace | |
-: 4504: ! '\f' formfeed | |
-: 4505: ! '\n' newline (LF) | |
-: 4506: ! '\r' carriage return (CR) | |
-: 4507: ! '\t' horizontal tab | |
-: 4508: ! '\uXXXX' 4 hexadecimal digits | |
-: 4509: ! | |
-: 4510: | |
-: 4511: !initialize: | |
-: 4512: n = len(s) | |
36: 4513: j = 1 | |
36: 4514: | |
-: 4515: do | |
88: 4516: | |
-: 4517: jprev = j !initialize | |
124: 4518: j = index(s(j:n),backslash) !look for an escape character | |
124: 4519: | |
-: 4520: if (j>0) then !an escape character was found | |
124: 4521: | |
-: 4522: !index in full string of the escape character: | |
-: 4523: j = j + (jprev-1) | |
94: 4524: | |
-: 4525: if (j<n) then | |
94: 4526: | |
-: 4527: !save the bit before the escape character: | |
-: 4528: if (j>1) then | |
94: 4529: pre = s( 1 : j-1 ) | |
88: 4530: else | |
-: 4531: pre = '' | |
6: 4532: end if | |
-: 4533: | |
-: 4534: !character after the escape character: | |
-: 4535: c = s( j+1 : j+1 ) | |
94: 4536: | |
-: 4537: if (any(c == [quotation_mark,backslash,slash, & | |
94: 4538: to_unicode(['b','f','n','r','t'])])) then | |
-: 4539: | |
-: 4540: !save the bit after the escape characters: | |
-: 4541: if (j+2<n) then | |
43: 4542: post = s(j+2:n) | |
42: 4543: else | |
-: 4544: post = '' | |
1: 4545: end if | |
-: 4546: | |
-: 4547: select case(c) | |
38: 4548: case (quotation_mark,backslash,slash) | |
-: 4549: !use c as is | |
-: 4550: case (CK_'b') | |
-: 4551: c = bspace | |
1: 4552: case (CK_'f') | |
-: 4553: c = formfeed | |
1: 4554: case (CK_'n') | |
-: 4555: c = newline | |
1: 4556: case (CK_'r') | |
-: 4557: c = carriage_return | |
1: 4558: case (CK_'t') | |
-: 4559: c = horizontal_tab | |
44: 4560: end select | |
-: 4561: | |
-: 4562: s = pre//c//post | |
43: 4563: | |
-: 4564: n = n-1 !backslash character has been | |
43: 4565: ! removed from the string | |
-: 4566: | |
-: 4567: else if (c == 'u') then !expecting 4 hexadecimal digits after | |
51: 4568: !the escape character [\uXXXX] | |
-: 4569: | |
-: 4570: !for now, we are just printing them as is | |
-: 4571: ![not checking to see if it is a valid hex value] | |
-: 4572: | |
-: 4573: if (j+5<=n) then | |
51: 4574: j=j+4 | |
51: 4575: else | |
-: 4576: call throw_exception('Error in json_get_string:'//& | |
-: 4577: ' Invalid hexadecimal sequence'//& | |
-: 4578: ' in string: '//trim(c)) | |
#####: 4579: exit | |
#####: 4580: end if | |
-: 4581: | |
-: 4582: else | |
-: 4583: !unknown escape character | |
-: 4584: call throw_exception('Error in json_get_string:'//& | |
-: 4585: ' unknown escape sequence in string "'//& | |
-: 4586: trim(s)//'" ['//backslash//c//']') | |
#####: 4587: exit | |
#####: 4588: end if | |
-: 4589: | |
-: 4590: j=j+1 !go to the next character | |
94: 4591: | |
-: 4592: if (j>=n) exit !finished | |
94: 4593: | |
-: 4594: else | |
-: 4595: !an escape character is the last character in | |
-: 4596: ! the string [this may not be valid syntax, | |
-: 4597: ! but just keep it] | |
-: 4598: exit | |
#####: 4599: end if | |
-: 4600: | |
-: 4601: else | |
-: 4602: exit !no more escape characters in the string | |
30: 4603: end if | |
-: 4604: | |
-: 4605: end do | |
-: 4606: | |
-: 4607: if (exception_thrown) then | |
36: 4608: if (allocated(value)) deallocate(value) | |
#####: 4609: else | |
-: 4610: value = s | |
36: 4611: end if | |
-: 4612: | |
-: 4613: else | |
-: 4614: call throw_exception('Error in json_get_string:'//& | |
-: 4615: ' me%value not allocated') | |
#####: 4616: end if | |
-: 4617: | |
-: 4618: case default | |
-: 4619: call throw_exception('Error in json_get_string:'//& | |
-: 4620: ' Unable to resolve value to characters: '//me%name) | |
36: 4621: | |
-: 4622: ! Note: for the other cases, we could do val to string conversions. | |
-: 4623: | |
-: 4624: end select | |
-: 4625: | |
-: 4626: !cleanup: | |
-: 4627: if (allocated(s)) deallocate(s) | |
36: 4628: if (allocated(pre)) deallocate(pre) | |
36: 4629: if (allocated(post)) deallocate(post) | |
36: 4630: | |
-: 4631: end subroutine json_get_string | |
36: 4632:!***************************************************************************************** | |
-: 4633: | |
-: 4634:!***************************************************************************************** | |
-: 4635:!> | |
-: 4636:! Get a character string from a [[json_value]], given the path. | |
-: 4637: | |
-: 4638: subroutine json_get_string_with_path(me, path, value, found) | |
46: 4639: | |
-: 4640: implicit none | |
-: 4641: | |
-: 4642: type(json_value),pointer,intent(in) :: me | |
-: 4643: character(kind=CK,len=*),intent(in) :: path | |
-: 4644: character(kind=CK,len=:),allocatable,intent(out) :: value | |
-: 4645: logical(LK),intent(out),optional :: found | |
-: 4646: | |
-: 4647: type(json_value),pointer :: p | |
-: 4648: | |
-: 4649: value = '' | |
23: 4650: if ( exception_thrown ) then | |
23: 4651: if ( present(found) ) found = .false. | |
#####: 4652: return | |
#####: 4653: end if | |
-: 4654: | |
-: 4655: nullify(p) | |
23: 4656: | |
-: 4657: call json_get_by_path(me=me, path=path, p=p) | |
23: 4658: | |
-: 4659: if (.not. associated(p)) then | |
45: 4660: call throw_exception('Error in json_get_string:'//& | |
-: 4661: ' Unable to resolve path: '//trim(path)) | |
1: 4662: | |
-: 4663: else | |
-: 4664: | |
-: 4665: call json_get_string(p,value) | |
22: 4666: nullify(p) | |
22: 4667: | |
-: 4668: end if | |
-: 4669: | |
-: 4670: if (allocated(value) .and. .not. exception_thrown) then | |
23: 4671: if (present(found)) found = .true. | |
22: 4672: else | |
-: 4673: if (present(found)) then | |
1: 4674: found = .false. | |
1: 4675: call json_clear_exceptions() | |
1: 4676: end if | |
-: 4677: end if | |
-: 4678: | |
-: 4679: !cleanup: | |
-: 4680: if (associated(p)) nullify(p) | |
23: 4681: | |
-: 4682: end subroutine json_get_string_with_path | |
46: 4683:!***************************************************************************************** | |
-: 4684: | |
-: 4685:!***************************************************************************************** | |
-: 4686:!> | |
-: 4687:! Alternate version of [[json_get_string_with_path]], where "path" is kind=CDK | |
-: 4688: | |
-: 4689: subroutine wrap_json_get_string_with_path(me, path, value, found) | |
#####: 4690: | |
-: 4691: implicit none | |
-: 4692: | |
-: 4693: type(json_value),pointer,intent(in) :: me | |
-: 4694: character(kind=CDK,len=*),intent(in) :: path | |
-: 4695: character(kind=CK,len=:),allocatable,intent(out) :: value | |
-: 4696: logical(LK),intent(out),optional :: found | |
-: 4697: | |
-: 4698: call json_get_string_with_path(me,to_unicode(path),value,found) | |
#####: 4699: | |
-: 4700: end subroutine wrap_json_get_string_with_path | |
#####: 4701:!***************************************************************************************** | |
-: 4702: | |
-: 4703:!***************************************************************************************** | |
-: 4704:!> author: Jacob Williams | |
-: 4705:! date: 5/14/2014 | |
-: 4706:! | |
-: 4707:! Get a string vector from a [[json_file]]. | |
-: 4708: | |
-: 4709: subroutine json_get_string_vec(me, vec) | |
1: 4710: | |
-: 4711: implicit none | |
-: 4712: | |
-: 4713: type(json_value),pointer,intent(in) :: me | |
-: 4714: character(kind=CK,len=*),dimension(:),allocatable,intent(out) :: vec | |
-: 4715: | |
-: 4716: logical(LK) :: initialized | |
-: 4717: | |
-: 4718: initialized = .false. | |
1: 4719: | |
-: 4720: if (allocated(vec)) deallocate(vec) | |
1: 4721: | |
-: 4722: !the callback function is called for each element of the array: | |
-: 4723: call json_get(me, array_callback=get_chars_from_array) | |
2: 4724: | |
-: 4725: contains | |
-: 4726: | |
-: 4727: ! callback function for chars | |
-: 4728: subroutine get_chars_from_array(element, i, count) | |
3: 4729: | |
-: 4730: implicit none | |
-: 4731: | |
-: 4732: type(json_value),pointer,intent(in) :: element | |
-: 4733: integer(IK),intent(in) :: i !index | |
-: 4734: integer(IK),intent(in) :: count !size of array | |
-: 4735: | |
-: 4736: character(kind=CK,len=:),allocatable :: cval | |
3: 4737: | |
-: 4738: !size the output array: | |
-: 4739: if (.not. initialized) then | |
3: 4740: allocate(vec(count)) | |
1: 4741: initialized = .true. | |
1: 4742: end if | |
-: 4743: | |
-: 4744: !populate the elements: | |
-: 4745: call json_get(element, value=cval) | |
3: 4746: if (allocated(cval)) then | |
3: 4747: vec(i) = cval | |
3: 4748: deallocate(cval) | |
3: 4749: else | |
-: 4750: vec(i) = '' | |
#####: 4751: end if | |
-: 4752: | |
-: 4753: end subroutine get_chars_from_array | |
3: 4754: | |
-: 4755: end subroutine json_get_string_vec | |
-: 4756:!***************************************************************************************** | |
-: 4757: | |
-: 4758:!***************************************************************************************** | |
-: 4759:!> | |
-: 4760:! Get a string vector from a [[json_file]], given the path. | |
-: 4761: | |
-: 4762: subroutine json_get_string_vec_with_path(me, path, vec, found) | |
2: 4763: | |
-: 4764: implicit none | |
-: 4765: | |
-: 4766: type(json_value),pointer,intent(in) :: me | |
-: 4767: character(kind=CK,len=*),intent(in) :: path | |
-: 4768: character(kind=CK,len=*),dimension(:),allocatable,intent(out) :: vec | |
-: 4769: logical(LK),intent(out),optional :: found | |
-: 4770: | |
-: 4771: logical(LK) :: initialized | |
-: 4772: | |
-: 4773: initialized = .false. | |
2: 4774: | |
-: 4775: if (allocated(vec)) deallocate(vec) | |
2: 4776: | |
-: 4777: !the callback function is called for each element of the array: | |
-: 4778: call json_get(me, path=path, array_callback=get_chars_from_array, found=found) | |
4: 4779: | |
-: 4780: contains | |
-: 4781: | |
-: 4782: ! callback function for chars | |
-: 4783: subroutine get_chars_from_array(element, i, count) | |
10: 4784: | |
-: 4785: implicit none | |
-: 4786: | |
-: 4787: type(json_value),pointer,intent(in) :: element | |
-: 4788: integer(IK),intent(in) :: i !index | |
-: 4789: integer(IK),intent(in) :: count !size of array | |
-: 4790: | |
-: 4791: character(kind=CK,len=:),allocatable :: cval | |
10: 4792: | |
-: 4793: !size the output array: | |
-: 4794: if (.not. initialized) then | |
10: 4795: allocate(vec(count)) | |
2: 4796: initialized = .true. | |
2: 4797: end if | |
-: 4798: | |
-: 4799: !populate the elements: | |
-: 4800: call json_get(element, value=cval) | |
10: 4801: if (allocated(cval)) then | |
10: 4802: vec(i) = cval | |
10: 4803: deallocate(cval) | |
10: 4804: else | |
-: 4805: vec(i) = '' | |
#####: 4806: end if | |
-: 4807: | |
-: 4808: end subroutine get_chars_from_array | |
10: 4809: | |
-: 4810: end subroutine json_get_string_vec_with_path | |
-: 4811:!***************************************************************************************** | |
-: 4812: | |
-: 4813:!***************************************************************************************** | |
-: 4814:!> | |
-: 4815:! Alternate version of [[json_get_string_vec_with_path]], where "path" is kind=CDK | |
-: 4816: | |
-: 4817: subroutine wrap_json_get_string_vec_with_path(me, path, vec, found) | |
1: 4818: | |
-: 4819: implicit none | |
-: 4820: | |
-: 4821: type(json_value),pointer,intent(in) :: me | |
-: 4822: character(kind=CDK,len=*),intent(in) :: path | |
-: 4823: character(kind=CK,len=*),dimension(:),allocatable,intent(out) :: vec | |
-: 4824: logical(LK),intent(out),optional :: found | |
-: 4825: | |
-: 4826: call json_get_string_vec_with_path(me,to_unicode(path),vec,found) | |
1: 4827: | |
-: 4828: end subroutine wrap_json_get_string_vec_with_path | |
2: 4829:!***************************************************************************************** | |
-: 4830: | |
-: 4831:!***************************************************************************************** | |
-: 4832:!> | |
-: 4833:! This routine calls the user-supplied [[array_callback_func]] subroutine | |
-: 4834:! for each element in the array. | |
-: 4835:! | |
-: 4836:!@note For integer, double, logical, and character arrays, | |
-: 4837:! higher-level routines are provided (see [[json_get]]), so | |
-: 4838:! this routine does not have to be used for those cases. | |
-: 4839: | |
-: 4840: subroutine json_get_array(me, array_callback) | |
8: 4841: | |
-: 4842: implicit none | |
-: 4843: | |
-: 4844: type(json_value),pointer,intent(in) :: me | |
-: 4845: procedure(array_callback_func) :: array_callback | |
-: 4846: | |
-: 4847: type(json_value),pointer :: element | |
-: 4848: integer(IK) :: i, count | |
-: 4849: | |
-: 4850: if ( exception_thrown ) return | |
8: 4851: | |
-: 4852: nullify(element) | |
8: 4853: | |
-: 4854: select case (me%var_type) | |
8: 4855: case (json_array) | |
-: 4856: count = json_count(me) | |
8: 4857: element => me%children | |
8: 4858: do i = 1, count ! callback for each child | |
35: 4859: call array_callback(element, i, count) | |
27: 4860: element => element%next | |
27: 4861: end do | |
-: 4862: case default | |
-: 4863: | |
-: 4864: call throw_exception('Error in json_get_array:'//& | |
-: 4865: ' Resolved value is not an array ') | |
8: 4866: | |
-: 4867: end select | |
-: 4868: | |
-: 4869: !cleanup: | |
-: 4870: if (associated(element)) nullify(element) | |
8: 4871: | |
-: 4872: end subroutine json_get_array | |
-: 4873:!***************************************************************************************** | |
-: 4874: | |
-: 4875:!***************************************************************************************** | |
-: 4876:!> | |
-: 4877:! This routine calls the user-supplied array_callback subroutine | |
-: 4878:! for each element in the array (specified by the path). | |
-: 4879: | |
-: 4880: subroutine json_get_array_with_path(me, path, array_callback, found) | |
7: 4881: | |
-: 4882: implicit none | |
-: 4883: | |
-: 4884: type(json_value),pointer,intent(in) :: me | |
-: 4885: character(kind=CK,len=*),intent(in) :: path | |
-: 4886: procedure(array_callback_func) :: array_callback | |
-: 4887: logical(LK),intent(out),optional :: found | |
-: 4888: | |
-: 4889: type(json_value),pointer :: p | |
-: 4890: | |
-: 4891: if ( exception_thrown ) then | |
7: 4892: if ( present(found) ) found = .false. | |
#####: 4893: return | |
#####: 4894: end if | |
-: 4895: | |
-: 4896: nullify(p) | |
7: 4897: | |
-: 4898: ! resolve the path to the value | |
-: 4899: call json_get_by_path(me=me, path=path, p=p) | |
7: 4900: | |
-: 4901: if (.not. associated(p)) then | |
7: 4902: call throw_exception('Error in json_get_array:'//& | |
-: 4903: ' Unable to resolve path: '//trim(path)) | |
#####: 4904: else | |
-: 4905: call json_get_array(me=p,array_callback=array_callback) | |
7: 4906: nullify(p) | |
7: 4907: end if | |
-: 4908: if ( exception_thrown ) then | |
7: 4909: if ( present(found) ) then | |
#####: 4910: found = .false. | |
#####: 4911: call json_clear_exceptions() | |
#####: 4912: end if | |
-: 4913: else | |
-: 4914: if ( present(found) ) found = .true. | |
7: 4915: end if | |
-: 4916: | |
-: 4917: end subroutine json_get_array_with_path | |
7: 4918:!***************************************************************************************** | |
-: 4919: | |
-: 4920:!***************************************************************************************** | |
-: 4921:!> | |
-: 4922:! Alternate version of [[json_get_array_with_path]], where "path" is kind=CDK | |
-: 4923: | |
-: 4924: subroutine wrap_json_get_array_with_path(me, path, array_callback, found) | |
#####: 4925: | |
-: 4926: implicit none | |
-: 4927: | |
-: 4928: type(json_value),pointer,intent(in) :: me | |
-: 4929: character(kind=CDK,len=*),intent(in) :: path | |
-: 4930: procedure(array_callback_func) :: array_callback | |
-: 4931: logical(LK),intent(out),optional :: found | |
-: 4932: | |
-: 4933: call json_get_array_with_path(me, to_unicode(path), array_callback, found) | |
#####: 4934: | |
-: 4935: end subroutine wrap_json_get_array_with_path | |
#####: 4936:!***************************************************************************************** | |
-: 4937: | |
-: 4938:!***************************************************************************************** | |
-: 4939:!> | |
-: 4940:! Parse the JSON file and populate the [[json_value]] tree. | |
-: 4941:! | |
-: 4942:!# Inputs | |
-: 4943:! | |
-: 4944:! The inputs can be: | |
-: 4945:! | |
-: 4946:! * file and unit : the specified unit is used to read JSON from file. | |
-: 4947:! [note if unit is already open, then the filename is ignored] | |
-: 4948:! * file : JSON is read from file using internal unit number | |
-: 4949:! | |
-: 4950:!# Example | |
-: 4951:! | |
-: 4952:!```fortran | |
-: 4953:! type(json_value),pointer :: p | |
-: 4954:! call json_parse(file='myfile.json', p=p) | |
-: 4955:!``` | |
-: 4956:! | |
-: 4957:!# History | |
-: 4958:! * Jacob Williams : 01/13/2015 : added read from string option. | |
-: 4959:! * Izaak Beekman : 03/08/2015 : moved read from string to separate | |
-: 4960:! subroutine, and error annotation | |
-: 4961:! to separate subroutine. | |
-: 4962:! | |
-: 4963:!@note When calling this routine, any exceptions thrown from previous | |
-: 4964:! calls will automatically be cleared. | |
-: 4965: | |
-: 4966: subroutine json_parse_file(file, p, unit) | |
10: 4967: | |
-: 4968: implicit none | |
-: 4969: | |
-: 4970: character(kind=CDK,len=*),intent(in) :: file !! JSON file name | |
-: 4971: type(json_value),pointer :: p !! output structure | |
-: 4972: integer(IK),intent(in),optional :: unit !! file unit number (/= 0) | |
-: 4973: | |
-: 4974: integer(IK) :: iunit, istat | |
-: 4975: logical(LK) :: is_open | |
-: 4976: | |
-: 4977: !clear any exceptions and initialize: | |
-: 4978: call json_initialize() | |
10: 4979: | |
-: 4980: if ( present(unit) ) then | |
10: 4981: | |
-: 4982: if (unit==0) then | |
#####: 4983: call throw_exception('Error in json_parse_file: unit number must not be 0.') | |
#####: 4984: return | |
#####: 4985: end if | |
-: 4986: | |
-: 4987: iunit = unit | |
#####: 4988: | |
-: 4989: !check to see if the file is already open | |
-: 4990: ! if it is, then use it, otherwise open the file with the name given. | |
-: 4991: inquire(unit=iunit, opened=is_open, iostat=istat) | |
#####: 4992: if (istat==0 .and. .not. is_open) then | |
#####: 4993: ! open the file | |
-: 4994: open ( unit = iunit, & | |
-: 4995: file = file, & | |
-: 4996: status = 'OLD', & | |
-: 4997: action = 'READ', & | |
-: 4998: form = form_spec, & | |
-: 4999: access = access_spec, & | |
-: 5000: iostat = istat & | |
-: 5001: FILE_ENCODING ) | |
#####: 5002: else | |
-: 5003: !if the file is already open, then we need to make sure | |
-: 5004: ! that it is open with the correct form/access/etc... | |
-: 5005: end if | |
-: 5006: | |
-: 5007: else | |
-: 5008: | |
-: 5009: ! open the file with a new unit number: | |
-: 5010: open ( newunit = iunit, & | |
-: 5011: file = file, & | |
-: 5012: status = 'OLD', & | |
-: 5013: action = 'READ', & | |
-: 5014: form = form_spec, & | |
-: 5015: access = access_spec, & | |
-: 5016: iostat = istat & | |
-: 5017: FILE_ENCODING ) | |
10: 5018: | |
-: 5019: end if | |
-: 5020: | |
-: 5021: if (istat==0) then | |
10: 5022: | |
-: 5023: ! create the value and associate the pointer | |
-: 5024: call json_value_create(p) | |
10: 5025: | |
-: 5026: ! Note: the name of the root json_value doesn't really matter, | |
-: 5027: ! but we'll allocate something here just in case. | |
-: 5028: p%name = trim(file) !use the file name | |
10: 5029: | |
-: 5030: ! parse as a value | |
-: 5031: call parse_value(unit=iunit, str=CK_'', value=p) | |
10: 5032: if (exception_thrown) call annotate_invalid_json(iunit,CK_'') | |
10: 5033: | |
-: 5034: ! close the file if necessary | |
-: 5035: close(unit=iunit, iostat=istat) | |
10: 5036: | |
-: 5037: else | |
-: 5038: | |
-: 5039: call throw_exception('Error in json_parse_file: Error opening file: '//trim(file)) | |
#####: 5040: nullify(p) | |
#####: 5041: | |
-: 5042: end if | |
-: 5043: | |
-: 5044: end subroutine json_parse_file | |
10: 5045:!***************************************************************************************** | |
-: 5046: | |
-: 5047:!***************************************************************************************** | |
-: 5048:!> | |
-: 5049:! Parse the JSON string and populate the [[json_value]] tree. | |
-: 5050:! | |
-: 5051:!# See also | |
-: 5052:! * [[json_parse_file]] | |
-: 5053: | |
-: 5054: subroutine json_parse_string(p, str) | |
6: 5055: | |
-: 5056: implicit none | |
-: 5057: | |
-: 5058: type(json_value),pointer :: p !! output structure | |
-: 5059: character(kind=CK,len=*),intent(in) :: str !! string with JSON data | |
-: 5060: | |
-: 5061: integer(IK),parameter :: iunit = 0 !indicates that json data will be read from buffer | |
-: 5062: | |
-: 5063: if ( .not. exception_thrown ) then | |
6: 5064: | |
-: 5065: !clear any exceptions and initialize: | |
-: 5066: call json_initialize() | |
6: 5067: | |
-: 5068: ! create the value and associate the pointer | |
-: 5069: call json_value_create(p) | |
6: 5070: | |
-: 5071: ! Note: the name of the root json_value doesn't really matter, | |
-: 5072: ! but we'll allocate something here just in case. | |
-: 5073: p%name = '' | |
6: 5074: | |
-: 5075: ! parse as a value | |
-: 5076: call parse_value(unit=iunit, str=str, value=p) | |
6: 5077: | |
-: 5078: if (exception_thrown) call annotate_invalid_json(iunit,str) | |
6: 5079: | |
-: 5080: end if | |
-: 5081: | |
-: 5082: end subroutine json_parse_string | |
12: 5083:!***************************************************************************************** | |
-: 5084: | |
-: 5085:!***************************************************************************************** | |
-: 5086:!> | |
-: 5087:! Alternate version of [[json_parse_string]], where "str" is kind=CDK. | |
-: 5088: | |
-: 5089: subroutine wrap_json_parse_string(p, str) | |
3: 5090: | |
-: 5091: implicit none | |
-: 5092: | |
-: 5093: type(json_value),pointer :: p !! output structure | |
-: 5094: character(kind=CDK,len=*),intent(in) :: str !! string with JSON data | |
-: 5095: | |
-: 5096: call json_parse_string(p,to_unicode(str)) | |
3: 5097: | |
-: 5098: end subroutine wrap_json_parse_string | |
6: 5099:!***************************************************************************************** | |
-: 5100: | |
-: 5101:!***************************************************************************************** | |
-: 5102:!> | |
-: 5103:! Generate a warning message if there was an error parsing a JSON | |
-: 5104:! file or string. | |
-: 5105: | |
-: 5106: subroutine annotate_invalid_json(iunit,str) | |
3: 5107: | |
-: 5108: implicit none | |
-: 5109: | |
-: 5110: integer(IK),intent(in) :: iunit !! file unit number | |
-: 5111: character(kind=CK,len=*),intent(in) :: str !! string with JSON data | |
-: 5112: | |
-: 5113: character(kind=CK,len=:),allocatable :: line, arrow_str | |
3: 5114: character(kind=CK,len=10) :: line_str, char_str | |
-: 5115: integer(IK) :: i, i_nl_prev, i_nl | |
-: 5116: | |
-: 5117: ! | |
-: 5118: ! If there was an error reading the file, then | |
-: 5119: ! print the line where the error occurred: | |
-: 5120: ! | |
-: 5121: if (exception_thrown) then | |
3: 5122: | |
-: 5123: !the counters for the current line and the last character read: | |
-: 5124: call integer_to_string(line_count, line_str) | |
3: 5125: call integer_to_string(char_count, char_str) | |
3: 5126: | |
-: 5127: !draw the arrow string that points to the current character: | |
-: 5128: arrow_str = repeat('-',max( 0, char_count - 1) )//'^' | |
3: 5129: | |
-: 5130: if (line_count>0 .and. char_count>0) then | |
3: 5131: | |
-: 5132: if (iunit/=0) then | |
3: 5133: | |
-: 5134: if (use_unformatted_stream) then | |
-: 5135: call get_current_line_from_file_stream(iunit,line) | |
-: 5136: else | |
-: 5137: call get_current_line_from_file_sequential(iunit,line) | |
1: 5138: end if | |
-: 5139: | |
-: 5140: else | |
-: 5141: | |
-: 5142: !get the current line from the string: | |
-: 5143: ! [this is done by counting the newline characters] | |
-: 5144: i_nl_prev = 0 !index of previous newline character | |
1: 5145: i_nl = 2 !just in case line_count = 0 | |
1: 5146: do i=1,line_count | |
2: 5147: i_nl = index(str(i_nl_prev+1:),newline) | |
2: 5148: if (i_nl==0) then !last line - no newline character | |
2: 5149: i_nl = len(str)+1 | |
1: 5150: exit | |
1: 5151: end if | |
-: 5152: i_nl = i_nl + i_nl_prev !index of current newline character | |
1: 5153: i_nl_prev = i_nl !update for next iteration | |
1: 5154: end do | |
-: 5155: line = str(i_nl_prev+1 : i_nl-1) !extract current line | |
1: 5156: | |
-: 5157: end if | |
-: 5158: | |
-: 5159: else | |
-: 5160: !in this case, it was an empty line or file | |
-: 5161: line = '' | |
1: 5162: end if | |
-: 5163: | |
-: 5164: !create the error message: | |
-: 5165: err_message = err_message//newline//& | |
-: 5166: 'line: '//trim(adjustl(line_str))//', '//& | |
-: 5167: 'character: '//trim(adjustl(char_str))//newline//& | |
-: 5168: trim(line)//newline//arrow_str | |
3: 5169: | |
-: 5170: if (allocated(line)) deallocate(line) | |
3: 5171: | |
-: 5172: end if | |
-: 5173: | |
-: 5174: end subroutine annotate_invalid_json | |
6: 5175:!***************************************************************************************** | |
-: 5176: | |
-: 5177:!***************************************************************************************** | |
-: 5178:!> author: Jacob Williams | |
-: 5179:! | |
-: 5180:! Rewind the file to the beginning of the current line, and return this line. | |
-: 5181:! The file is assumed to be opened. | |
-: 5182:! This is the SEQUENTIAL version (see also [[get_current_line_from_file_stream]]). | |
-: 5183: | |
-: 5184: subroutine get_current_line_from_file_sequential(iunit,line) | |
1: 5185: | |
-: 5186: implicit none | |
-: 5187: | |
-: 5188: integer(IK),intent(in) :: iunit !! file unit number | |
-: 5189: character(kind=CK,len=:),allocatable,intent(out) :: line !! current line | |
-: 5190: | |
-: 5191: integer(IK),parameter :: n_chunk = 256 ! chunk size [arbitrary] | |
-: 5192: character(kind=CDK,len=*),parameter :: nfmt = '(A256)' ! corresponding format statement | |
-: 5193: | |
-: 5194: character(kind=CK,len=n_chunk) :: chunk | |
-: 5195: integer(IK) :: istat,isize | |
-: 5196: | |
-: 5197: !initialize: | |
-: 5198: line = '' | |
1: 5199: | |
-: 5200: !rewind to beginning of the current record: | |
-: 5201: backspace(iunit, iostat=istat) | |
1: 5202: | |
-: 5203: !loop to read in all the characters in the current record. | |
-: 5204: ![the line is read in chunks until the end of the line is reached] | |
-: 5205: if (istat==0) then | |
1: 5206: do | |
#####: 5207: isize=0 | |
1: 5208: read(iunit,fmt=nfmt,advance='NO',size=isize,iostat=istat) chunk | |
1: 5209: if (istat==0) then | |
1: 5210: line = line//chunk | |
#####: 5211: else | |
-: 5212: if (isize>0 .and. isize<=n_chunk) line = line//chunk(1:isize) | |
1: 5213: exit | |
1: 5214: end if | |
-: 5215: end do | |
-: 5216: end if | |
-: 5217: | |
-: 5218: end subroutine get_current_line_from_file_sequential | |
1: 5219:!***************************************************************************************** | |
-: 5220: | |
-: 5221:!***************************************************************************************** | |
-: 5222:!> author: Jacob Williams | |
-: 5223:! | |
-: 5224:! Rewind the file to the beginning of the current line, and return this line. | |
-: 5225:! The file is assumed to be opened. | |
-: 5226:! This is the STREAM version (see also [[get_current_line_from_file_sequential]]). | |
-: 5227: | |
-: 5228: subroutine get_current_line_from_file_stream(iunit,line) | |
#####: 5229: | |
-: 5230: implicit none | |
-: 5231: | |
-: 5232: integer(IK),intent(in) :: iunit !! file unit number | |
-: 5233: character(kind=CK,len=:),allocatable,intent(out) :: line !! current line | |
-: 5234: | |
-: 5235: integer(IK) :: istart,iend,ios | |
-: 5236: character(kind=CK,len=1) :: c | |
-: 5237: | |
-: 5238: !updated for the new STREAM version: | |
-: 5239: | |
-: 5240: istart = ipos | |
#####: 5241: do | |
#####: 5242: if (istart<=1) then | |
#####: 5243: istart = 1 | |
#####: 5244: exit | |
#####: 5245: end if | |
-: 5246: read(iunit,pos=istart,iostat=ios) c | |
#####: 5247: if (c==newline .or. ios/=0) then | |
#####: 5248: if (istart/=1) istart = istart - 1 | |
#####: 5249: exit | |
#####: 5250: end if | |
-: 5251: istart = istart-1 !rewind until the beginning of the line | |
#####: 5252: end do | |
-: 5253: iend = ipos | |
#####: 5254: do | |
#####: 5255: read(iunit,pos=iend,iostat=ios) c | |
#####: 5256: if (c==newline .or. ios/=0) exit | |
#####: 5257: iend=iend+1 | |
#####: 5258: end do | |
-: 5259: allocate( character(kind=CK,len=iend-istart+1) :: line ) | |
#####: 5260: read(iunit,pos=istart,iostat=ios) line | |
#####: 5261: | |
-: 5262: end subroutine get_current_line_from_file_stream | |
#####: 5263:!***************************************************************************************** | |
-: 5264: | |
-: 5265:!***************************************************************************************** | |
-: 5266:!> | |
-: 5267:! Core parsing routine. | |
-: 5268: | |
-: 5269: recursive subroutine parse_value(unit, str, value) | |
388371: 5270: | |
-: 5271: implicit none | |
-: 5272: | |
-: 5273: integer(IK),intent(in) :: unit !! file unit number | |
-: 5274: character(kind=CK,len=*),intent(in) :: str !! string containing JSON data (only used if unit=0) | |
-: 5275: type(json_value),pointer :: value !! JSON data that is extracted | |
-: 5276: | |
-: 5277: logical(LK) :: eof | |
-: 5278: character(kind=CK,len=1) :: c | |
-: 5279: character(kind=CK,len=:),allocatable :: tmp !this is a work-around for a bug | |
388371: 5280: ! in the gfortran 4.9 compiler. | |
-: 5281: | |
-: 5282: if (.not. exception_thrown) then | |
388371: 5283: | |
-: 5284: !the routine is being called incorrectly. | |
-: 5285: if (.not. associated(value)) then | |
388371: 5286: call throw_exception('Error in parse_value: value pointer not associated.') | |
#####: 5287: end if | |
-: 5288: | |
-: 5289: ! pop the next non whitespace character off the file | |
-: 5290: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
388371: 5291: | |
-: 5292: if (eof) then | |
388371: 5293: return | |
#####: 5294: else | |
-: 5295: select case (c) | |
-: 5296: case (start_object) | |
-: 5297: | |
-: 5298: ! start object | |
-: 5299: call to_object(value) !allocate class | |
39836: 5300: call parse_object(unit, str, value) | |
39836: 5301: | |
-: 5302: case (start_array) | |
-: 5303: | |
-: 5304: ! start array | |
-: 5305: call to_array(value) !allocate class | |
19927: 5306: call parse_array(unit, str, value) | |
19927: 5307: | |
-: 5308: case (end_array) | |
-: 5309: | |
-: 5310: ! end an empty array | |
-: 5311: call push_char(c) | |
3: 5312: nullify(value) | |
3: 5313: | |
-: 5314: case (quotation_mark) | |
-: 5315: | |
-: 5316: ! string | |
-: 5317: call to_string(value) !allocate class | |
248825: 5318: | |
-: 5319: select case (value%var_type) | |
497650: 5320: case (json_string) | |
-: 5321: call parse_string(unit, str, tmp) !write to a tmp variable because of | |
248825: 5322: value%str_value = tmp ! a bug in 4.9 gfortran compiler. | |
248825: 5323: deallocate(tmp) ! | |
746475: 5324: end select | |
-: 5325: | |
-: 5326: case (CK_'t') !true_str(1:1) gfortran bug work around | |
-: 5327: | |
-: 5328: !true | |
-: 5329: call parse_for_chars(unit, str, true_str(2:)) | |
5125: 5330: !allocate class and set value: | |
-: 5331: if (.not. exception_thrown) call to_logical(value,.true.) | |
5125: 5332: | |
-: 5333: case (CK_'f') !false_str(1:1) gfortran bug work around | |
-: 5334: | |
-: 5335: !false | |
-: 5336: call parse_for_chars(unit, str, false_str(2:)) | |
4831: 5337: !allocate class and set value: | |
-: 5338: if (.not. exception_thrown) call to_logical(value,.false.) | |
4831: 5339: | |
-: 5340: case (CK_'n') !null_str(1:1) gfortran bug work around | |
-: 5341: | |
-: 5342: !null | |
-: 5343: call parse_for_chars(unit, str, null_str(2:)) | |
4: 5344: if (.not. exception_thrown) call to_null(value) !allocate class | |
4: 5345: | |
-: 5346: case(CK_'-', CK_'0': CK_'9') | |
-: 5347: | |
-: 5348: call push_char(c) | |
69820: 5349: call parse_number(unit, str, value) | |
69820: 5350: | |
-: 5351: case default | |
-: 5352: | |
-: 5353: call throw_exception('Error in parse_value:'//& | |
-: 5354: ' Unexpected character while parsing value. "'//& | |
-: 5355: c//'"') | |
388371: 5356: | |
-: 5357: end select | |
-: 5358: end if | |
-: 5359: | |
-: 5360: end if | |
-: 5361: | |
-: 5362: end subroutine parse_value | |
776742: 5363:!***************************************************************************************** | |
-: 5364: | |
-: 5365:!***************************************************************************************** | |
-: 5366:!> author: Jacob Williams | |
-: 5367:! | |
-: 5368:! Allocate a [[json_value]] pointer and make it a logical(LK) variable. | |
-: 5369:! The pointer should not already be allocated. | |
-: 5370:! | |
-: 5371:!# Example | |
-: 5372:!```fortran | |
-: 5373:! type(json_value),pointer :: p | |
-: 5374:! call json_create(p,'value',.true.) | |
-: 5375:!``` | |
-: 5376: | |
-: 5377: subroutine json_value_create_logical(me,val,name) | |
1: 5378: | |
-: 5379: implicit none | |
-: 5380: | |
-: 5381: type(json_value),pointer :: me | |
-: 5382: character(kind=CK,len=*),intent(in) :: name !! variable name | |
-: 5383: logical(LK),intent(in) :: val !! variable value | |
-: 5384: | |
-: 5385: call json_value_create(me) | |
1: 5386: call to_logical(me,val,name) | |
1: 5387: | |
-: 5388: end subroutine json_value_create_logical | |
2: 5389:!***************************************************************************************** | |
-: 5390: | |
-: 5391:!***************************************************************************************** | |
-: 5392:!> author: Izaak Beekman | |
-: 5393:! | |
-: 5394:! Wrapper for [[json_value_create_logical]] so [[json_create_logical]] can | |
-: 5395:! be called with name of character kind 'DEFAULT' or 'ISO_10646' | |
-: 5396: | |
-: 5397: subroutine wrap_json_value_create_logical(me,val,name) | |
1: 5398: | |
-: 5399: implicit none | |
-: 5400: | |
-: 5401: type(json_value),pointer :: me | |
-: 5402: character(kind=CDK,len=*),intent(in) :: name | |
-: 5403: logical(LK),intent(in) :: val | |
-: 5404: | |
-: 5405: call json_value_create_logical(me,val,to_unicode(name)) | |
1: 5406: | |
-: 5407: end subroutine wrap_json_value_create_logical | |
2: 5408:!***************************************************************************************** | |
-: 5409: | |
-: 5410:!***************************************************************************************** | |
-: 5411:!> author: Jacob Williams | |
-: 5412:! | |
-: 5413:! Allocate a [[json_value]] pointer and make it an integer(IK) variable. | |
-: 5414:! The pointer should not already be allocated. | |
-: 5415:! | |
-: 5416:!# Example | |
-: 5417:!```fortran | |
-: 5418:! type(json_value),pointer :: p | |
-: 5419:! call json_create(p,'value',1) | |
-: 5420:!``` | |
-: 5421: | |
-: 5422: subroutine json_value_create_integer(me,val,name) | |
1: 5423: | |
-: 5424: implicit none | |
-: 5425: | |
-: 5426: type(json_value),pointer :: me | |
-: 5427: character(kind=CK,len=*),intent(in) :: name | |
-: 5428: integer(IK),intent(in) :: val | |
-: 5429: | |
-: 5430: call json_value_create(me) | |
1: 5431: call to_integer(me,val,name) | |
1: 5432: | |
-: 5433: end subroutine json_value_create_integer | |
2: 5434:!***************************************************************************************** | |
-: 5435: | |
-: 5436:!***************************************************************************************** | |
-: 5437:!> author: Izaak Beekman | |
-: 5438:! | |
-: 5439:! A wrapper procedure for [[json_value_create_integer]] so that [[json_create_integer]] | |
-: 5440:! may be called with either a 'DEFAULT' or 'ISO_10646' character kind 'name' | |
-: 5441:! actual argument. | |
-: 5442: | |
-: 5443: subroutine wrap_json_value_create_integer(me,val,name) | |
1: 5444: | |
-: 5445: implicit none | |
-: 5446: | |
-: 5447: type(json_value),pointer :: me | |
-: 5448: character(kind=CDK,len=*),intent(in) :: name | |
-: 5449: integer(IK),intent(in) :: val | |
-: 5450: | |
-: 5451: call json_value_create_integer(me,val,to_unicode(name)) | |
1: 5452: | |
-: 5453: end subroutine wrap_json_value_create_integer | |
2: 5454:!***************************************************************************************** | |
-: 5455: | |
-: 5456:!***************************************************************************************** | |
-: 5457:!> author: Jacob Williams | |
-: 5458:! | |
-: 5459:! Allocate a [[json_value]] pointer and make it a real(RK) variable. | |
-: 5460:! The pointer should not already be allocated. | |
-: 5461:! | |
-: 5462:!# Example | |
-: 5463:!```fortran | |
-: 5464:! type(json_value),pointer :: p | |
-: 5465:! call json_create(p,'value',1.0d0) | |
-: 5466:!``` | |
-: 5467: | |
-: 5468: subroutine json_value_create_double(me,val,name) | |
1: 5469: | |
-: 5470: implicit none | |
-: 5471: | |
-: 5472: type(json_value),pointer :: me | |
-: 5473: character(kind=CK,len=*),intent(in) :: name | |
-: 5474: real(RK),intent(in) :: val | |
-: 5475: | |
-: 5476: call json_value_create(me) | |
1: 5477: call to_double(me,val,name) | |
1: 5478: | |
-: 5479: end subroutine json_value_create_double | |
2: 5480:!***************************************************************************************** | |
-: 5481: | |
-: 5482:!***************************************************************************************** | |
-: 5483:!> author: Izaak Beekman | |
-: 5484:! | |
-: 5485:! A wrapper for [[json_value_create_double]] so that [[json_create_double]] may be | |
-: 5486:! called with an actual argument corresponding to the dummy argument, 'name' | |
-: 5487:! that may be of 'DEFAULT' or 'ISO_10646' character kind. | |
-: 5488: | |
-: 5489: subroutine wrap_json_value_create_double(me,val,name) | |
1: 5490: | |
-: 5491: implicit none | |
-: 5492: | |
-: 5493: type(json_value),pointer :: me | |
-: 5494: character(kind=CDK,len=*),intent(in) :: name | |
-: 5495: real(RK),intent(in) :: val | |
-: 5496: | |
-: 5497: call json_value_create_double(me,val,to_unicode(name)) | |
1: 5498: | |
-: 5499: end subroutine wrap_json_value_create_double | |
2: 5500:!***************************************************************************************** | |
-: 5501: | |
-: 5502:!***************************************************************************************** | |
-: 5503:!> author: Jacob Williams | |
-: 5504:! | |
-: 5505:! Allocate a json_value pointer and make it a string variable. | |
-: 5506:! The pointer should not already be allocated. | |
-: 5507:! | |
-: 5508:!# Example | |
-: 5509:!```fortran | |
-: 5510:! type(json_value),pointer :: p | |
-: 5511:! call json_create(p,'value','hello') | |
-: 5512:!``` | |
-: 5513: | |
-: 5514: subroutine json_value_create_string(me,val,name) | |
1: 5515: | |
-: 5516: implicit none | |
-: 5517: | |
-: 5518: type(json_value),pointer :: me | |
-: 5519: character(kind=CK,len=*),intent(in) :: name | |
-: 5520: character(kind=CK,len=*),intent(in) :: val | |
-: 5521: | |
-: 5522: call json_value_create(me) | |
1: 5523: call to_string(me,val,name) | |
1: 5524: | |
-: 5525: end subroutine json_value_create_string | |
2: 5526:!***************************************************************************************** | |
-: 5527: | |
-: 5528:!***************************************************************************************** | |
-: 5529:!> author: Izaak Beekman | |
-: 5530:! | |
-: 5531:! Wrap [[json_value_create_string]] so that [[json_create_string]] may be called with actual | |
-: 5532:! character string arguments for 'name' and 'val' that are BOTH of 'DEFAULT' or | |
-: 5533:! 'ISO_10646' character kind. | |
-: 5534: | |
-: 5535: subroutine wrap_json_value_create_string(me,val,name) | |
1: 5536: | |
-: 5537: implicit none | |
-: 5538: | |
-: 5539: type(json_value),pointer :: me | |
-: 5540: character(kind=CDK,len=*),intent(in) :: name | |
-: 5541: character(kind=CDK,len=*),intent(in) :: val | |
-: 5542: | |
-: 5543: call json_value_create_string(me,to_unicode(val),to_unicode(name)) | |
1: 5544: | |
-: 5545: end subroutine wrap_json_value_create_string | |
2: 5546:!***************************************************************************************** | |
-: 5547: | |
-: 5548:!***************************************************************************************** | |
-: 5549:!> author: Jacob Williams | |
-: 5550:! | |
-: 5551:! Allocate a json_value pointer and make it a null variable. | |
-: 5552:! The pointer should not already be allocated. | |
-: 5553:! | |
-: 5554:!# Example | |
-: 5555:!```fortran | |
-: 5556:! type(json_value),pointer :: p | |
-: 5557:! call json_create(p,'value') | |
-: 5558:!``` | |
-: 5559: | |
-: 5560: subroutine json_value_create_null(me,name) | |
1: 5561: | |
-: 5562: implicit none | |
-: 5563: | |
-: 5564: type(json_value),pointer :: me | |
-: 5565: character(kind=CK,len=*),intent(in) :: name | |
-: 5566: | |
-: 5567: call json_value_create(me) | |
1: 5568: call to_null(me,name) | |
1: 5569: | |
-: 5570: end subroutine json_value_create_null | |
2: 5571:!***************************************************************************************** | |
-: 5572: | |
-: 5573:!***************************************************************************************** | |
-: 5574:!> author: Izaak Beekman | |
-: 5575:! | |
-: 5576:! Wrap [[json_value_create_null]] so that [[json_create_null]] may be called with an actual | |
-: 5577:! argument corresponding to the dummy argument 'name' that is either of 'DEFAULT' or | |
-: 5578:! 'ISO_10646' character kind. | |
-: 5579: | |
-: 5580: subroutine wrap_json_value_create_null(me,name) | |
1: 5581: | |
-: 5582: implicit none | |
-: 5583: | |
-: 5584: type(json_value),pointer :: me | |
-: 5585: character(kind=CDK,len=*),intent(in) :: name | |
-: 5586: | |
-: 5587: call json_value_create_null(me,to_unicode(name)) | |
1: 5588: | |
-: 5589: end subroutine wrap_json_value_create_null | |
2: 5590:!***************************************************************************************** | |
-: 5591: | |
-: 5592:!***************************************************************************************** | |
-: 5593:!> author: Jacob Williams | |
-: 5594:! | |
-: 5595:! Allocate a [[json_value]] pointer and make it an object variable. | |
-: 5596:! The pointer should not already be allocated. | |
-: 5597:! | |
-: 5598:!# Example | |
-: 5599:!```fortran | |
-: 5600:! type(json_value),pointer :: p | |
-: 5601:! call json_create(p,'objectname') | |
-: 5602:!``` | |
-: 5603:! | |
-: 5604:!@note The name is not significant for the root structure or an array element. | |
-: 5605:! In those cases, an empty string can be used. | |
-: 5606: | |
-: 5607: subroutine json_value_create_object(me,name) | |
18: 5608: | |
-: 5609: implicit none | |
-: 5610: | |
-: 5611: type(json_value),pointer :: me | |
-: 5612: character(kind=CK,len=*),intent(in) :: name | |
-: 5613: | |
-: 5614: call json_value_create(me) | |
18: 5615: call to_object(me,name) | |
18: 5616: | |
-: 5617: end subroutine json_value_create_object | |
36: 5618:!***************************************************************************************** | |
-: 5619: | |
-: 5620:!***************************************************************************************** | |
-: 5621:!> author: Izaak Beekman | |
-: 5622:! | |
-: 5623:! Wrap [[json_value_create_object]] so that [[json_create_object]] may be called with an actual | |
-: 5624:! argument corresponding to the dummy argument 'name' that is of either 'DEFAULT' or | |
-: 5625:! 'ISO_10646' character kind. | |
-: 5626: | |
-: 5627: subroutine wrap_json_value_create_object(me,name) | |
18: 5628: | |
-: 5629: implicit none | |
-: 5630: | |
-: 5631: type(json_value),pointer :: me | |
-: 5632: character(kind=CDK,len=*),intent(in) :: name | |
-: 5633: | |
-: 5634: call json_value_create_object(me,to_unicode(name)) | |
18: 5635: | |
-: 5636: end subroutine wrap_json_value_create_object | |
36: 5637:!***************************************************************************************** | |
-: 5638: | |
-: 5639:!***************************************************************************************** | |
-: 5640:!> author: Jacob Williams | |
-: 5641:! | |
-: 5642:! Allocate a [[json_value]] pointer and make it an array variable. | |
-: 5643:! The pointer should not already be allocated. | |
-: 5644:! | |
-: 5645:!# Example | |
-: 5646:!```fortran | |
-: 5647:! type(json_value),pointer :: p | |
-: 5648:! call json_create(p,'arrayname') | |
-: 5649:!``` | |
-: 5650: | |
-: 5651: subroutine json_value_create_array(me,name) | |
2: 5652: | |
-: 5653: implicit none | |
-: 5654: | |
-: 5655: type(json_value),pointer :: me | |
-: 5656: character(kind=CK,len=*),intent(in) :: name | |
-: 5657: | |
-: 5658: call json_value_create(me) | |
2: 5659: call to_array(me,name) | |
2: 5660: | |
-: 5661: end subroutine json_value_create_array | |
4: 5662:!***************************************************************************************** | |
-: 5663: | |
-: 5664:!***************************************************************************************** | |
-: 5665:!> author: Izaak Beekman | |
-: 5666:! | |
-: 5667:! A wrapper for [[json_value_create_array]] so that [[json_create_array]] may be called with | |
-: 5668:! an actual argument, corresponding to the dummy argument 'name', that is either of | |
-: 5669:! 'DEFAULT' or 'ISO_10646' character kind. | |
-: 5670: | |
-: 5671: subroutine wrap_json_value_create_array(me,name) | |
2: 5672: | |
-: 5673: implicit none | |
-: 5674: | |
-: 5675: type(json_value),pointer :: me | |
-: 5676: character(kind=CDK,len=*),intent(in) :: name | |
-: 5677: | |
-: 5678: call json_value_create_array(me,to_unicode(name)) | |
2: 5679: | |
-: 5680: end subroutine wrap_json_value_create_array | |
4: 5681:!***************************************************************************************** | |
-: 5682: | |
-: 5683:!***************************************************************************************** | |
-: 5684:!> author: Jacob Williams | |
-: 5685:! | |
-: 5686:! Change the [[json_value]] variable to a logical. | |
-: 5687: | |
-: 5688: subroutine to_logical(me,val,name) | |
9964: 5689: | |
-: 5690: implicit none | |
-: 5691: | |
-: 5692: type(json_value),intent(inout) :: me | |
-: 5693: logical(LK),intent(in),optional :: val !! if the value is also to be set (if not present, then .false. is used). | |
-: 5694: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5695: | |
-: 5696: !set type and value: | |
-: 5697: call destroy_json_data(me) | |
9964: 5698: me%var_type = json_logical | |
9964: 5699: allocate(me%log_value) | |
9964: 5700: if (present(val)) then | |
9964: 5701: me%log_value = val | |
9964: 5702: else | |
-: 5703: me%log_value = .false. !default value | |
#####: 5704: end if | |
-: 5705: | |
-: 5706: !name: | |
-: 5707: if (present(name)) me%name = trim(name) | |
9964: 5708: | |
-: 5709: end subroutine to_logical | |
19928: 5710:!***************************************************************************************** | |
-: 5711: | |
-: 5712:!***************************************************************************************** | |
-: 5713:!> author: Jacob Williams | |
-: 5714:! | |
-: 5715:! Change the [[json_value]] variable to an integer. | |
-: 5716: | |
-: 5717: subroutine to_integer(me,val,name) | |
50001: 5718: | |
-: 5719: implicit none | |
-: 5720: | |
-: 5721: type(json_value),intent(inout) :: me | |
-: 5722: integer(IK),intent(in),optional :: val !! if the value is also to be set (if not present, then 0 is used). | |
-: 5723: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5724: | |
-: 5725: !set type and value: | |
-: 5726: call destroy_json_data(me) | |
50001: 5727: me%var_type = json_integer | |
50001: 5728: allocate(me%int_value) | |
50001: 5729: if (present(val)) then | |
50001: 5730: me%int_value = val | |
50001: 5731: else | |
-: 5732: me%int_value = 0 !default value | |
#####: 5733: end if | |
-: 5734: | |
-: 5735: !name: | |
-: 5736: if (present(name)) me%name = trim(name) | |
50001: 5737: | |
-: 5738: end subroutine to_integer | |
100002: 5739:!***************************************************************************************** | |
-: 5740: | |
-: 5741:!***************************************************************************************** | |
-: 5742:!> author: Jacob Williams | |
-: 5743:! | |
-: 5744:! Change the [[json_value]] variable to a double. | |
-: 5745: | |
-: 5746: subroutine to_double(me,val,name) | |
19958: 5747: | |
-: 5748: implicit none | |
-: 5749: | |
-: 5750: type(json_value),intent(inout) :: me | |
-: 5751: real(RK),intent(in),optional :: val !! if the value is also to be set (if not present, then 0.0_rk is used). | |
-: 5752: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5753: | |
-: 5754: !set type and value: | |
-: 5755: call destroy_json_data(me) | |
19958: 5756: me%var_type = json_double | |
19958: 5757: allocate(me%dbl_value) | |
19958: 5758: if (present(val)) then | |
19958: 5759: me%dbl_value = val | |
19958: 5760: else | |
-: 5761: me%dbl_value = 0.0_RK !default value | |
#####: 5762: end if | |
-: 5763: | |
-: 5764: !name: | |
-: 5765: if (present(name)) me%name = trim(name) | |
19958: 5766: | |
-: 5767: end subroutine to_double | |
39916: 5768:!***************************************************************************************** | |
-: 5769: | |
-: 5770:!***************************************************************************************** | |
-: 5771:!> author: Jacob Williams | |
-: 5772:! | |
-: 5773:! Change the [[json_value]] variable to a string. | |
-: 5774:! | |
-: 5775:!# Modified | |
-: 5776:! * Izaak Beekman : 02/24/2015 | |
-: 5777:! | |
-: 5778: | |
-: 5779: subroutine to_string(me,val,name) | |
248864: 5780: | |
-: 5781: implicit none | |
-: 5782: | |
-: 5783: type(json_value),intent(inout) :: me | |
-: 5784: character(kind=CK,len=*),intent(in),optional :: val !! if the value is also to be set (if not present, then '' is used). | |
-: 5785: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5786: | |
-: 5787: !set type and value: | |
-: 5788: call destroy_json_data(me) | |
248864: 5789: me%var_type = json_string | |
248864: 5790: if (present(val)) then | |
248864: 5791: me%str_value = val | |
39: 5792: else | |
-: 5793: me%str_value = '' !default value | |
248825: 5794: end if | |
-: 5795: | |
-: 5796: !name: | |
-: 5797: if (present(name)) me%name = trim(name) | |
248864: 5798: | |
-: 5799: end subroutine to_string | |
497728: 5800:!***************************************************************************************** | |
-: 5801: | |
-: 5802:!***************************************************************************************** | |
-: 5803:!> author: Jacob Williams | |
-: 5804:! | |
-: 5805:! Change the [[json_value]] variable to a null. | |
-: 5806: | |
-: 5807: subroutine to_null(me,name) | |
5: 5808: | |
-: 5809: implicit none | |
-: 5810: | |
-: 5811: type(json_value),intent(inout) :: me | |
-: 5812: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5813: | |
-: 5814: !set type and value: | |
-: 5815: call destroy_json_data(me) | |
5: 5816: me%var_type = json_null | |
5: 5817: | |
-: 5818: !name: | |
-: 5819: if (present(name)) me%name = trim(name) | |
5: 5820: | |
-: 5821: end subroutine to_null | |
10: 5822:!***************************************************************************************** | |
-: 5823: | |
-: 5824:!***************************************************************************************** | |
-: 5825:!> author: Jacob Williams | |
-: 5826:! | |
-: 5827:! Change the [[json_value]] variable to an object. | |
-: 5828: | |
-: 5829: subroutine to_object(me,name) | |
39854: 5830: | |
-: 5831: implicit none | |
-: 5832: | |
-: 5833: type(json_value),intent(inout) :: me | |
-: 5834: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5835: | |
-: 5836: !set type and value: | |
-: 5837: call destroy_json_data(me) | |
39854: 5838: me%var_type = json_object | |
39854: 5839: | |
-: 5840: !name: | |
-: 5841: if (present(name)) me%name = trim(name) | |
39854: 5842: | |
-: 5843: end subroutine to_object | |
79708: 5844:!***************************************************************************************** | |
-: 5845: | |
-: 5846:!***************************************************************************************** | |
-: 5847:!> author: Jacob Williams | |
-: 5848:! | |
-: 5849:! Change the [[json_value]] variable to an array. | |
-: 5850: | |
-: 5851: subroutine to_array(me,name) | |
19941: 5852: | |
-: 5853: implicit none | |
-: 5854: | |
-: 5855: type(json_value),intent(inout) :: me | |
-: 5856: character(kind=CK,len=*),intent(in),optional :: name !! if the name is also to be changed. | |
-: 5857: | |
-: 5858: !set type and value: | |
-: 5859: call destroy_json_data(me) | |
19941: 5860: me%var_type = json_array | |
19941: 5861: | |
-: 5862: !name: | |
-: 5863: if (present(name)) me%name = trim(name) | |
19941: 5864: | |
-: 5865: end subroutine to_array | |
39882: 5866:!***************************************************************************************** | |
-: 5867: | |
-: 5868:!***************************************************************************************** | |
-: 5869:!> | |
-: 5870:! Core parsing routine. | |
-: 5871: | |
-: 5872: recursive subroutine parse_object(unit, str, parent) | |
278850: 5873: | |
-: 5874: implicit none | |
-: 5875: | |
-: 5876: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 5877: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) | |
-: 5878: type(json_value),pointer :: parent !! the parsed object will be added as a child of this | |
-: 5879: | |
-: 5880: type(json_value),pointer :: pair | |
-: 5881: logical(LK) :: eof | |
-: 5882: character(kind=CK,len=1) :: c | |
-: 5883: character(kind=CK,len=:),allocatable :: tmp !! this is a work-around for a bug | |
278850: 5884: !! in the gfortran 4.9 compiler. | |
-: 5885: | |
-: 5886: if (.not. exception_thrown) then | |
278850: 5887: | |
-: 5888: !the routine is being called incorrectly. | |
-: 5889: if (.not. associated(parent)) then | |
278850: 5890: call throw_exception('Error in parse_object: parent pointer not associated.') | |
#####: 5891: end if | |
-: 5892: | |
-: 5893: nullify(pair) !probably not necessary | |
278850: 5894: | |
-: 5895: ! pair name | |
-: 5896: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
278850: 5897: if (eof) then | |
278850: 5898: call throw_exception('Error in parse_object:'//& | |
-: 5899: ' Unexpected end of file while parsing start of object.') | |
1: 5900: return | |
1: 5901: else if (end_object == c) then | |
278849: 5902: ! end of an empty object | |
-: 5903: return | |
3: 5904: else if (quotation_mark == c) then | |
557692: 5905: call json_value_create(pair) | |
278846: 5906: call parse_string(unit, str, tmp) !write to a tmp variable because of | |
278846: 5907: pair % name = tmp ! a bug in 4.9 gfortran compiler. | |
278846: 5908: deallocate(tmp) | |
278846: 5909: if (exception_thrown) then | |
278846: 5910: call json_destroy(pair) | |
#####: 5911: return | |
#####: 5912: end if | |
-: 5913: else | |
-: 5914: call throw_exception('Error in parse_object: Expecting string: "'//c//'"') | |
#####: 5915: return | |
#####: 5916: end if | |
-: 5917: | |
-: 5918: ! pair value | |
-: 5919: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
278846: 5920: if (eof) then | |
278846: 5921: call throw_exception('Error in parse_object:'//& | |
-: 5922: ' Unexpected end of file while parsing object member.') | |
#####: 5923: return | |
#####: 5924: else if (colon_char == c) then | |
278846: 5925: ! parse the value | |
-: 5926: call parse_value(unit, str, pair) | |
278845: 5927: if (exception_thrown) then | |
278845: 5928: call json_destroy(pair) | |
2: 5929: return | |
2: 5930: else | |
-: 5931: call json_add(parent, pair) | |
278843: 5932: end if | |
-: 5933: else | |
-: 5934: call throw_exception('Error in parse_object:'//& | |
-: 5935: ' Expecting : and then a value: '//c) | |
1: 5936: return | |
1: 5937: end if | |
-: 5938: | |
-: 5939: ! another possible pair | |
-: 5940: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
278843: 5941: if (eof) then | |
278843: 5942: call throw_exception('Error in parse_object: '//& | |
-: 5943: 'End of file encountered when parsing an object') | |
#####: 5944: return | |
#####: 5945: else if (delimiter == c) then | |
278843: 5946: ! read the next member | |
-: 5947: call parse_object(unit = unit, str=str, parent = parent) | |
239014: 5948: else if (end_object == c) then | |
39829: 5949: ! end of object | |
-: 5950: return | |
39829: 5951: else | |
-: 5952: call throw_exception('Error in parse_object: Expecting end of object: '//c) | |
#####: 5953: return | |
#####: 5954: end if | |
-: 5955: | |
-: 5956: end if | |
-: 5957: | |
-: 5958: end subroutine parse_object | |
557700: 5959:!***************************************************************************************** | |
-: 5960: | |
-: 5961:!***************************************************************************************** | |
-: 5962:!> | |
-: 5963:! Core parsing routine. | |
-: 5964: | |
-: 5965: recursive subroutine parse_array(unit, str, array) | |
19927: 5966: | |
-: 5967: implicit none | |
-: 5968: | |
-: 5969: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 5970: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) | |
-: 5971: type(json_value),pointer :: array | |
-: 5972: | |
-: 5973: type(json_value),pointer :: element | |
-: 5974: logical(LK) :: eof | |
-: 5975: character(kind=CK,len=1) :: c | |
-: 5976: | |
-: 5977: do | |
89583: 5978: | |
-: 5979: if (exception_thrown) exit | |
109510: 5980: | |
-: 5981: ! try to parse an element value | |
-: 5982: nullify(element) | |
109510: 5983: call json_value_create(element) | |
109510: 5984: call parse_value(unit, str, element) | |
109510: 5985: if (exception_thrown) then | |
109510: 5986: if (associated(element)) call json_destroy(element) | |
#####: 5987: exit | |
#####: 5988: end if | |
-: 5989: | |
-: 5990: ! parse value will disassociate an empty array value | |
-: 5991: if (associated(element)) call json_add(array, element) | |
109510: 5992: | |
-: 5993: ! popped the next character | |
-: 5994: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
109510: 5995: | |
-: 5996: if (eof) then | |
109510: 5997: ! The file ended before array was finished: | |
-: 5998: call throw_exception('Error in parse_array: '//& | |
-: 5999: 'End of file encountered when parsing an array.') | |
#####: 6000: exit | |
#####: 6001: else if (delimiter == c) then | |
109510: 6002: ! parse the next element | |
-: 6003: cycle | |
89583: 6004: else if (end_array == c) then | |
19927: 6005: ! end of array | |
-: 6006: exit | |
19926: 6007: else | |
-: 6008: call throw_exception('Error in parse_array: '//& | |
-: 6009: 'Unexpected character encountered when parsing array.') | |
1: 6010: exit | |
1: 6011: end if | |
-: 6012: | |
-: 6013: end do | |
-: 6014: | |
-: 6015: end subroutine parse_array | |
39854: 6016:!***************************************************************************************** | |
-: 6017: | |
-: 6018:!***************************************************************************************** | |
-: 6019:!> | |
-: 6020:! Parses a string while reading a JSON file. | |
-: 6021:! | |
-: 6022:!# History | |
-: 6023:! * Jacob Williams : 6/16/2014 : Added hex validation. | |
-: 6024: | |
-: 6025: subroutine parse_string(unit, str, string) | |
1055342: 6026: | |
-: 6027: implicit none | |
-: 6028: | |
-: 6029: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 6030: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) | |
-: 6031: character(kind=CK,len=:),allocatable,intent(out) :: string | |
-: 6032: | |
-: 6033: logical(LK) :: eof, is_hex, escape | |
-: 6034: character(kind=CK,len=1) :: c, last | |
-: 6035: character(kind=CK,len=4) :: hex | |
-: 6036: integer(IK) :: i | |
-: 6037: integer(IK) :: ip !! index to put next character, | |
-: 6038: !! to speed up by reducing the number of character string reallocations. | |
-: 6039: | |
-: 6040: !at least return a blank string if there is a problem: | |
-: 6041: string = repeat(space, chunk_size) | |
527671: 6042: | |
-: 6043: if (.not. exception_thrown) then | |
527671: 6044: | |
-: 6045: !initialize: | |
-: 6046: ip = 1 | |
527671: 6047: last = space | |
527671: 6048: is_hex = .false. | |
527671: 6049: escape = .false. | |
527671: 6050: i = 0 | |
527671: 6051: | |
-: 6052: do | |
8655574: 6053: | |
-: 6054: !get the next character from the file: | |
-: 6055: c = pop_char(unit, str=str, eof = eof, skip_ws = .false.) | |
9183245: 6056: | |
-: 6057: if (eof) then | |
9183245: 6058: | |
-: 6059: call throw_exception('Error in parse_string: Expecting end of string') | |
#####: 6060: return | |
#####: 6061: | |
-: 6062: else if (c==quotation_mark .and. last /= backslash) then | |
9183245: 6063: | |
-: 6064: if (is_hex) call throw_exception('Error in parse_string:'//& | |
527671: 6065: ' incomplete hex string: \u'//trim(hex)) | |
#####: 6066: exit | |
527671: 6067: | |
-: 6068: else | |
-: 6069: | |
-: 6070: !if the string is not big enough, then add another chunk: | |
-: 6071: if (ip>len(string)) string = string // repeat(space, chunk_size) | |
8655574: 6072: | |
-: 6073: !append to string: | |
-: 6074: string(ip:ip) = c | |
8655574: 6075: ip = ip + 1 | |
8655574: 6076: | |
-: 6077: !hex validation: | |
-: 6078: if (is_hex) then !accumulate the four characters after '\u' | |
8655574: 6079: | |
-: 6080: i=i+1 | |
444: 6081: hex(i:i) = c | |
444: 6082: if (i==4) then | |
444: 6083: if (valid_json_hex(hex)) then | |
111: 6084: i = 0 | |
111: 6085: hex = '' | |
111: 6086: is_hex = .false. | |
111: 6087: else | |
-: 6088: call throw_exception('Error in parse_string:'//& | |
-: 6089: ' invalid hex string: \u'//trim(hex)) | |
#####: 6090: exit | |
#####: 6091: end if | |
-: 6092: end if | |
-: 6093: | |
-: 6094: else | |
-: 6095: | |
-: 6096: !when the '\u' string is encountered, then | |
-: 6097: ! start accumulating the hex string (should be the next 4 characters) | |
-: 6098: if (escape) then | |
8655130: 6099: escape = .false. | |
20046: 6100: is_hex = (c=='u') !the next four characters are the hex string | |
20046: 6101: else | |
-: 6102: escape = (c==backslash) | |
8635084: 6103: end if | |
-: 6104: | |
-: 6105: end if | |
-: 6106: | |
-: 6107: !update for next char: | |
-: 6108: last = c | |
8655574: 6109: | |
-: 6110: end if | |
-: 6111: | |
-: 6112: end do | |
-: 6113: | |
-: 6114: !trim the string if necessary: | |
-: 6115: if (ip<len(string)+1) then | |
527671: 6116: if (ip==1) then | |
527563: 6117: string = '' | |
2: 6118: else | |
-: 6119: string = string(1:ip-1) | |
527561: 6120: end if | |
-: 6121: end if | |
-: 6122: | |
-: 6123: end if | |
-: 6124: | |
-: 6125: end subroutine parse_string | |
1055342: 6126:!***************************************************************************************** | |
-: 6127: | |
-: 6128:!***************************************************************************************** | |
-: 6129:!> | |
-: 6130:! Core parsing routine. | |
-: 6131: | |
-: 6132: subroutine parse_for_chars(unit, str, chars) | |
9960: 6133: | |
-: 6134: implicit none | |
-: 6135: | |
-: 6136: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 6137: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) | |
-: 6138: character(kind=CK,len=*),intent(in) :: chars !! the string to check for. | |
-: 6139: | |
-: 6140: integer(IK) :: i, length | |
-: 6141: logical(LK) :: eof | |
-: 6142: character(kind=CK,len=1) :: c | |
-: 6143: | |
-: 6144: if (.not. exception_thrown) then | |
9960: 6145: | |
-: 6146: length = len_trim(chars) | |
9960: 6147: | |
-: 6148: do i = 1, length | |
44671: 6149: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
34711: 6150: if (eof) then | |
34711: 6151: call throw_exception('Error in parse_for_chars:'//& | |
-: 6152: ' Unexpected end of file while parsing array.') | |
#####: 6153: return | |
#####: 6154: else if (c /= chars(i:i)) then | |
34711: 6155: call throw_exception('Error in parse_for_chars:'//& | |
-: 6156: ' Unexpected character.: "'//c//'" '//chars(i:i)) | |
#####: 6157: return | |
#####: 6158: end if | |
-: 6159: end do | |
-: 6160: | |
-: 6161: end if | |
-: 6162: | |
-: 6163: end subroutine parse_for_chars | |
9960: 6164:!***************************************************************************************** | |
-: 6165: | |
-: 6166:!***************************************************************************************** | |
-: 6167:!> author: Jacob Williams | |
-: 6168:! date: 1/20/2014 | |
-: 6169:! | |
-: 6170:! Read a numerical value from the file (or string). | |
-: 6171:! The routine will determine if it is an integer or a double, and | |
-: 6172:! allocate the type accordingly. | |
-: 6173:! | |
-: 6174:!@note Complete rewrite of the original FSON routine, which had some problems. | |
-: 6175: | |
-: 6176: subroutine parse_number(unit, str, value) | |
69820: 6177: | |
-: 6178: implicit none | |
-: 6179: | |
-: 6180: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 6181: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) | |
-: 6182: type(json_value),pointer :: value | |
-: 6183: | |
-: 6184: character(kind=CK,len=:),allocatable :: tmp | |
69820: 6185: character(kind=CK,len=1) :: c | |
-: 6186: logical(LK) :: eof | |
-: 6187: real(RK) :: rval | |
-: 6188: integer(IK) :: ival | |
-: 6189: logical(LK) :: first | |
-: 6190: logical(LK) :: is_integer | |
-: 6191: | |
-: 6192: !to speed up by reducing the number of character string reallocations: | |
-: 6193: integer(IK) :: ip !index to put next character | |
-: 6194: | |
-: 6195: if (.not. exception_thrown) then | |
69820: 6196: | |
-: 6197: tmp = repeat(space, chunk_size) | |
69820: 6198: ip = 1 | |
69820: 6199: first = .true. | |
69820: 6200: is_integer = .true. !assume it may be an integer, unless otherwise determined | |
69820: 6201: | |
-: 6202: !read one character at a time and accumulate the string: | |
-: 6203: do | |
277340: 6204: | |
-: 6205: !get the next character: | |
-: 6206: c = pop_char(unit, str=str, eof = eof, skip_ws = .true.) | |
347160: 6207: | |
-: 6208: if (eof) then | |
347160: 6209: call throw_exception('Error in parse_number:'//& | |
-: 6210: ' Unexpected end of file while parsing number.') | |
#####: 6211: return | |
#####: 6212: else | |
-: 6213: | |
-: 6214: select case (c) | |
-: 6215: case(CK_'-',CK_'+') !note: allowing a '+' as the first character here. | |
-: 6216: | |
-: 6217: if (is_integer .and. (.not. first)) is_integer = .false. | |
9787: 6218: | |
-: 6219: !add it to the string: | |
-: 6220: !tmp = tmp // c !...original | |
-: 6221: if (ip>len(tmp)) tmp = tmp // repeat(space, chunk_size) | |
9787: 6222: tmp(ip:ip) = c | |
9787: 6223: ip = ip + 1 | |
9787: 6224: | |
-: 6225: case(CK_'.',CK_'E',CK_'e') !can be present in real numbers | |
-: 6226: | |
-: 6227: if (is_integer) is_integer = .false. | |
19970: 6228: | |
-: 6229: !add it to the string: | |
-: 6230: !tmp = tmp // c !...original | |
-: 6231: if (ip>len(tmp)) tmp = tmp // repeat(space, chunk_size) | |
19970: 6232: tmp(ip:ip) = c | |
19970: 6233: ip = ip + 1 | |
19970: 6234: | |
-: 6235: case(CK_'0':CK_'9') !valid characters for numbers | |
-: 6236: | |
-: 6237: !add it to the string: | |
-: 6238: !tmp = tmp // c !...original | |
-: 6239: if (ip>len(tmp)) tmp = tmp // repeat(space, chunk_size) | |
247583: 6240: tmp(ip:ip) = c | |
247583: 6241: ip = ip + 1 | |
247583: 6242: | |
-: 6243: case default | |
-: 6244: | |
-: 6245: !push back the last character read: | |
-: 6246: call push_char(c) | |
69820: 6247: | |
-: 6248: !string to value: | |
-: 6249: if (is_integer) then | |
69820: 6250: ival = string_to_integer(tmp) | |
49887: 6251: call to_integer(value,ival) | |
49887: 6252: else | |
-: 6253: rval = string_to_double(tmp) | |
19933: 6254: call to_double(value,rval) | |
19933: 6255: end if | |
-: 6256: | |
-: 6257: exit !finished | |
416980: 6258: | |
-: 6259: end select | |
-: 6260: | |
-: 6261: end if | |
-: 6262: if (first) first = .false. | |
277340: 6263: | |
-: 6264: end do | |
-: 6265: | |
-: 6266: !cleanup: | |
-: 6267: if (allocated(tmp)) deallocate(tmp) | |
69820: 6268: | |
-: 6269: end if | |
-: 6270: | |
-: 6271: end subroutine parse_number | |
139640: 6272:!***************************************************************************************** | |
-: 6273: | |
-: 6274:!***************************************************************************************** | |
-: 6275:!> | |
-: 6276:! Get the next character from the file (or string). | |
-: 6277:! | |
-: 6278:!# See also | |
-: 6279:! * [[push_char]] | |
-: 6280:! | |
-: 6281:!@note This routine ignores non-printing ASCII characters (iachar<=31) that are in strings. | |
-: 6282: | |
-: 6283: recursive function pop_char(unit, str, eof, skip_ws) result(popped) | |
10899536: 6284: | |
-: 6285: implicit none | |
-: 6286: | |
-: 6287: character(kind=CK,len=1) :: popped !! the popped character. | |
-: 6288: integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) | |
-: 6289: character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) -- only used if unit=0 | |
-: 6290: logical(LK),intent(out) :: eof !! true if the end of the file has been reached. | |
-: 6291: logical(LK),intent(in),optional :: skip_ws !! to ignore whitespace. | |
-: 6292: | |
-: 6293: integer(IK) :: ios,str_len | |
-: 6294: character(kind=CK,len=1) :: c | |
-: 6295: logical(LK) :: ignore | |
-: 6296: | |
-: 6297: if (.not. exception_thrown) then | |
10899536: 6298: | |
-: 6299: eof = .false. | |
10899536: 6300: if (.not. present(skip_ws)) then | |
10899536: 6301: ignore = .false. | |
#####: 6302: else | |
-: 6303: ignore = skip_ws | |
10899536: 6304: end if | |
-: 6305: | |
-: 6306: do | |
2976960: 6307: | |
-: 6308: if (pushed_index > 0) then | |
13876496: 6309: | |
-: 6310: ! there is a character pushed back on, most likely from the number parsing | |
-: 6311: ! NOTE: this can only occur if reading from a file when use_unformatted_stream=.false. | |
-: 6312: c = pushed_char(pushed_index:pushed_index) | |
139643: 6313: pushed_index = pushed_index - 1 | |
139643: 6314: | |
-: 6315: else | |
-: 6316: | |
-: 6317: if (unit/=0) then !read from the file | |
13736853: 6318: | |
-: 6319: !read the next character: | |
-: 6320: if (use_unformatted_stream) then | |
-: 6321: read(unit=unit,pos=ipos,iostat=ios) c | |
-: 6322: else | |
-: 6323: read(unit=unit,fmt='(A1)',advance='NO',iostat=ios) c | |
6871798: 6324: end if | |
-: 6325: ipos = ipos + 1 | |
6871798: 6326: | |
-: 6327: !....note: maybe try read the file in chunks... | |
-: 6328: !.... or use asynchronous read with double buffering | |
-: 6329: ! (see Modern Fortran: Style and Usage) | |
-: 6330: | |
-: 6331: else !read from the string | |
-: 6332: | |
-: 6333: str_len = len(str) !length of the string | |
6865055: 6334: if (ipos<=str_len) then | |
6865055: 6335: c = str(ipos:ipos) | |
6865055: 6336: ios = 0 | |
6865055: 6337: else | |
-: 6338: ios = IOSTAT_END !end of the string | |
#####: 6339: end if | |
-: 6340: ipos = ipos + 1 | |
6865055: 6341: | |
-: 6342: end if | |
-: 6343: | |
-: 6344: char_count = char_count + 1 !character count in the current line | |
13736853: 6345: | |
-: 6346: if (IS_IOSTAT_END(ios)) then !end of file | |
13736853: 6347: | |
-: 6348: char_count = 0 | |
1: 6349: eof = .true. | |
1: 6350: exit | |
1: 6351: | |
-: 6352: elseif (IS_IOSTAT_EOR(ios) .or. c==newline) then !end of record | |
13736852: 6353: | |
-: 6354: char_count = 0 | |
448105: 6355: line_count = line_count + 1 | |
448105: 6356: cycle | |
448105: 6357: | |
-: 6358: end if | |
-: 6359: | |
-: 6360: end if | |
-: 6361: | |
-: 6362: if (any(c == control_chars)) then | |
13428390: 6363: | |
-: 6364: ! non printing ascii characters | |
-: 6365: cycle | |
#####: 6366: | |
-: 6367: else if (ignore .and. c == space) then | |
13428390: 6368: | |
-: 6369: cycle | |
-: 6370: | |
-: 6371: else | |
-: 6372: | |
-: 6373: popped = c | |
10899535: 6374: exit | |
10899535: 6375: | |
-: 6376: end if | |
-: 6377: | |
-: 6378: end do | |
-: 6379: | |
-: 6380: end if | |
-: 6381: | |
-: 6382: end function pop_char | |
21799072: 6383:!***************************************************************************************** | |
-: 6384: | |
-: 6385:!***************************************************************************************** | |
-: 6386:!> | |
-: 6387:! Core routine. | |
-: 6388:! | |
-: 6389:!# See also | |
-: 6390:! * [[pop_char]] | |
-: 6391:! | |
-: 6392:!# History | |
-: 6393:! * Jacob Williams : 5/3/2015 : replaced original version of this routine. | |
-: 6394: | |
-: 6395: subroutine push_char(c) | |
139643: 6396: | |
-: 6397: implicit none | |
-: 6398: | |
-: 6399: character(kind=CK,len=1),intent(in) :: c | |
-: 6400: | |
-: 6401: character(kind=CK,len=max_numeric_str_len) :: istr | |
-: 6402: | |
-: 6403: if (.not. exception_thrown) then | |
139643: 6404: | |
-: 6405: if (use_unformatted_stream) then | |
-: 6406: | |
-: 6407: !in this case, c is ignored, and we just | |
-: 6408: !decrement the stream position counter: | |
-: 6409: ipos = ipos - 1 | |
-: 6410: | |
-: 6411: else | |
-: 6412: | |
-: 6413: pushed_index = pushed_index + 1 | |
139643: 6414: | |
-: 6415: if (pushed_index>0 .and. pushed_index<=len(pushed_char)) then | |
139643: 6416: pushed_char(pushed_index:pushed_index) = c | |
139643: 6417: else | |
-: 6418: call integer_to_string(pushed_index,istr) | |
#####: 6419: call throw_exception('Error in push_char: '//& | |
-: 6420: 'invalid valid of pushed_index: '//trim(istr)) | |
#####: 6421: end if | |
-: 6422: | |
-: 6423: end if | |
-: 6424: | |
-: 6425: end if | |
-: 6426: | |
-: 6427: end subroutine push_char | |
139643: 6428:!***************************************************************************************** | |
-: 6429: | |
-: 6430:!***************************************************************************************** | |
-: 6431:!> author: Jacob Williams | |
-: 6432:! date: 12/4/2013 | |
-: 6433:! | |
-: 6434:! Convert an integer to a string. | |
-: 6435: | |
-: 6436: pure subroutine integer_to_string(ival,str) | |
267: 6437: | |
-: 6438: implicit none | |
-: 6439: | |
-: 6440: integer(IK),intent(in) :: ival !! integer value. | |
-: 6441: character(kind=CK,len=*),intent(out) :: str !! ival converted to a string. | |
-: 6442: | |
-: 6443: integer(IK) :: istat | |
-: 6444: | |
-: 6445: write(str,fmt=int_fmt,iostat=istat) ival | |
267: 6446: | |
-: 6447: if (istat==0) then | |
267: 6448: str = adjustl(str) | |
267: 6449: else | |
-: 6450: str = repeat(star,len(str)) | |
#####: 6451: end if | |
-: 6452: | |
-: 6453: end subroutine integer_to_string | |
534: 6454:!***************************************************************************************** | |
-: 6455: | |
-: 6456:!***************************************************************************************** | |
-: 6457:!> author: Jacob Williams | |
-: 6458:! date: 12/4/2013 | |
-: 6459:! | |
-: 6460:! Convert a real value to a string. | |
-: 6461:! | |
-: 6462:!# Modified | |
-: 6463:! * Izaak Beekman : 02/24/2015 : added the compact option. | |
-: 6464: | |
-: 6465: subroutine real_to_string(rval,str) | |
38: 6466: | |
-: 6467: implicit none | |
-: 6468: | |
-: 6469: real(RK),intent(in) :: rval !! real value. | |
-: 6470: character(kind=CK,len=*),intent(out) :: str !! rval converted to a string. | |
-: 6471: | |
-: 6472: integer(IK) :: istat | |
-: 6473: | |
-: 6474: !default format: | |
-: 6475: write(str,fmt=real_fmt,iostat=istat) rval | |
38: 6476: | |
-: 6477: if (istat==0) then | |
38: 6478: | |
-: 6479: !in this case, the default string will be compacted, | |
-: 6480: ! so that the same value is displayed with fewer characters. | |
-: 6481: if (compact_real) call compact_real_string(str) | |
38: 6482: | |
-: 6483: else | |
-: 6484: str = repeat(star,len(str)) | |
#####: 6485: end if | |
-: 6486: | |
-: 6487: end subroutine real_to_string | |
76: 6488:!***************************************************************************************** | |
-: 6489: | |
-: 6490:!***************************************************************************************** | |
-: 6491:!> author: Izaak Beekman | |
-: 6492:! date: 02/24/2015 | |
-: 6493:! | |
-: 6494:! Compact a string representing a real number, so that | |
-: 6495:! the same value is displayed with fewer characters. | |
-: 6496:! | |
-: 6497:!# See also | |
-: 6498:! * [[real_to_string]] | |
-: 6499: | |
-: 6500: subroutine compact_real_string(str) | |
38: 6501: | |
-: 6502: implicit none | |
-: 6503: | |
-: 6504: character(kind=CK,len=*),intent(inout) :: str !! string representation of a real number. | |
-: 6505: | |
-: 6506: character(kind=CK,len=len(str)) :: significand, expnt | |
38: 6507: character(kind=CK,len=2) :: separator | |
-: 6508: integer(IK) :: exp_start,decimal_pos,sig_trim,exp_trim,i | |
-: 6509: | |
-: 6510: str = adjustl(str) | |
38: 6511: exp_start = scan(str,CK_'eEdD') | |
38: 6512: if (exp_start == 0) exp_start = scan(str,CK_'-+',back=.true.) | |
38: 6513: decimal_pos = scan(str,CK_'.') | |
38: 6514: if (exp_start /= 0) separator = str(exp_start:exp_start) | |
38: 6515: | |
-: 6516: if ( exp_start < decimal_pos ) then !possibly signed, exponent-less float | |
38: 6517: | |
-: 6518: significand = str | |
#####: 6519: sig_trim = len(trim(significand)) | |
#####: 6520: do i = len(trim(significand)),decimal_pos+2,-1 !look from right to left at 0s | |
#####: 6521: !but save one after the decimal place | |
-: 6522: if (significand(i:i) == '0') then | |
#####: 6523: sig_trim = i-1 | |
#####: 6524: else | |
-: 6525: exit | |
#####: 6526: end if | |
-: 6527: end do | |
-: 6528: str = trim(significand(1:sig_trim)) | |
#####: 6529: | |
-: 6530: else if (exp_start > decimal_pos) then !float has exponent | |
38: 6531: | |
-: 6532: significand = str(1:exp_start-1) | |
38: 6533: sig_trim = len(trim(significand)) | |
38: 6534: do i = len(trim(significand)),decimal_pos+2,-1 !look from right to left at 0s | |
594: 6535: if (significand(i:i) == '0') then | |
562: 6536: sig_trim = i-1 | |
556: 6537: else | |
-: 6538: exit | |
6: 6539: end if | |
-: 6540: end do | |
-: 6541: expnt = adjustl(str(exp_start+1:)) | |
38: 6542: if (expnt(1:1) == '+' .or. expnt(1:1) == '-') then | |
38: 6543: separator = trim(adjustl(separator))//expnt(1:1) | |
38: 6544: exp_start = exp_start + 1 | |
38: 6545: expnt = adjustl(str(exp_start+1:)) | |
38: 6546: end if | |
-: 6547: exp_trim = 1 | |
38: 6548: do i = 1,(len(trim(expnt))-1) !look at exponent leading zeros saving last | |
152: 6549: if (expnt(i:i) == '0') then | |
114: 6550: exp_trim = i+1 | |
114: 6551: else | |
-: 6552: exit | |
#####: 6553: end if | |
-: 6554: end do | |
-: 6555: str = trim(adjustl(significand(1:sig_trim)))// & | |
-: 6556: trim(adjustl(separator))// & | |
-: 6557: trim(adjustl(expnt(exp_trim:))) | |
38: 6558: | |
-: 6559: !else ! mal-formed real, BUT this code should be unreachable | |
-: 6560: | |
-: 6561: end if | |
-: 6562: | |
-: 6563: end subroutine compact_real_string | |
76: 6564:!***************************************************************************************** | |
-: 6565: | |
-: 6566:!***************************************************************************************** | |
-: 6567:!> author: Jacob Williams | |
-: 6568:! date:6/14/2014 | |
-: 6569:! | |
-: 6570:! Returns true if the string is a valid 4-digit hex string. | |
-: 6571:! | |
-: 6572:!# Examples | |
-: 6573:!```fortran | |
-: 6574:! valid_json_hex('0000') !returns true | |
-: 6575:! valid_json_hex('ABC4') !returns true | |
-: 6576:! valid_json_hex('AB') !returns false (< 4 characters) | |
-: 6577:! valid_json_hex('WXYZ') !returns false (invalid characters) | |
-: 6578:!``` | |
-: 6579: | |
-: 6580: pure function valid_json_hex(str) result(valid) | |
111: 6581: | |
-: 6582: implicit none | |
-: 6583: | |
-: 6584: logical(LK) :: valid !! is str a value 4-digit hex string | |
-: 6585: character(kind=CK,len=*),intent(in) :: str !! the string to check. | |
-: 6586: | |
-: 6587: integer(IK) :: n,i | |
-: 6588: | |
-: 6589: !an array of the valid hex characters: | |
-: 6590: character(kind=CK,len=1),dimension(22),parameter :: valid_chars = & | |
-: 6591: [ (achar(i),i=48,57), & ! decimal digits | |
-: 6592: (achar(i),i=65,70), & ! capital A-F | |
-: 6593: (achar(i),i=97,102) ] ! lowercase a-f | |
-: 6594: | |
-: 6595: !initialize | |
-: 6596: valid = .false. | |
111: 6597: | |
-: 6598: !check all the characters in the string: | |
-: 6599: n = len(str) | |
111: 6600: if (n==4) then | |
111: 6601: do i=1,n | |
555: 6602: if (.not. any(str(i:i)==valid_chars)) return | |
444: 6603: end do | |
-: 6604: valid = .true. !all are in the set, so it is OK | |
111: 6605: end if | |
-: 6606: | |
-: 6607: end function valid_json_hex | |
222: 6608:!***************************************************************************************** | |
-: 6609: | |
-: 6610:!***************************************************************************************** | |
-: 6611:!> author: Izaak Beekman | |
-: 6612:! | |
-: 6613:! Convert string to unicode (CDK to CK). | |
-: 6614: | |
-: 6615: pure function to_uni(str) | |
21193: 6616: | |
-: 6617: implicit none | |
-: 6618: | |
-: 6619: character(kind=CDK,len=*), intent(in) :: str | |
-: 6620: character(kind=CK,len=len(str)) :: to_uni | |
-: 6621: | |
-: 6622: to_uni = str | |
21193: 6623: | |
-: 6624: end function to_uni | |
42386: 6625:!***************************************************************************************** | |
-: 6626: | |
-: 6627:!***************************************************************************************** | |
-: 6628:!> author: Izaak Beekman | |
-: 6629:! | |
-: 6630:! Convert array of strings to unicode (CDK to CK). | |
-: 6631:! | |
-: 6632:!@note JW: may be able to remove this by making [[to_uni]] PURE ELEMENTAL ? | |
-: 6633: | |
-: 6634: pure function to_uni_vec(str) | |
194: 6635: | |
-: 6636: implicit none | |
-: 6637: | |
-: 6638: character(kind=CDK,len=*), dimension(:), intent(in) :: str | |
-: 6639: character(kind=CK,len=len(str)), dimension(size(str)) :: to_uni_vec | |
-: 6640: | |
-: 6641: to_uni_vec = str | |
97: 6642: | |
-: 6643: end function to_uni_vec | |
194: 6644:!***************************************************************************************** | |
-: 6645: | |
-: 6646:!***************************************************************************************** | |
-: 6647:!> author: Izaak Beekman | |
-: 6648:! | |
-: 6649:! CK//CDK operator. | |
-: 6650: | |
-: 6651: function ucs4_join_default(ucs4_str,def_str) result(res) | |
58: 6652: | |
-: 6653: implicit none | |
-: 6654: | |
-: 6655: character(kind=CK, len=*), intent(in) :: ucs4_str | |
-: 6656: character(kind=CDK,len=*), intent(in) :: def_str | |
-: 6657: character(kind=CK,len=(len(ucs4_str)+len(def_str))) :: res | |
-: 6658: | |
-: 6659: res = ucs4_str//to_unicode(def_str) | |
29: 6660: | |
-: 6661: end function ucs4_join_default | |
58: 6662:!***************************************************************************************** | |
-: 6663: | |
-: 6664:!***************************************************************************************** | |
-: 6665:!> author: Izaak Beekman | |
-: 6666:! | |
-: 6667:! CDK//CK operator. | |
-: 6668: | |
-: 6669: function default_join_ucs4(def_str,ucs4_str) result(res) | |
292: 6670: | |
-: 6671: implicit none | |
-: 6672: | |
-: 6673: character(kind=CDK,len=*), intent(in) :: def_str | |
-: 6674: character(kind=CK, len=*), intent(in) :: ucs4_str | |
-: 6675: character(kind=CK,len=(len(def_str)+len(ucs4_str))) :: res | |
-: 6676: | |
-: 6677: res = to_unicode(def_str)//ucs4_str | |
146: 6678: | |
-: 6679: end function default_join_ucs4 | |
292: 6680:!***************************************************************************************** | |
-: 6681: | |
-: 6682:!***************************************************************************************** | |
-: 6683:!> author: Izaak Beekman | |
-: 6684:! | |
-: 6685:! CK==CDK operator. | |
-: 6686: | |
-: 6687: function ucs4_comp_default(ucs4_str,def_str) result(res) | |
20822: 6688: | |
-: 6689: implicit none | |
-: 6690: | |
-: 6691: character(kind=CK, len=*), intent(in) :: ucs4_str | |
-: 6692: character(kind=CDK,len=*), intent(in) :: def_str | |
-: 6693: logical(LK) :: res | |
-: 6694: | |
-: 6695: res = ( ucs4_str == to_unicode(def_str) ) | |
20822: 6696: | |
-: 6697: end function ucs4_comp_default | |
41644: 6698:!***************************************************************************************** | |
-: 6699: | |
-: 6700:!***************************************************************************************** | |
-: 6701:!> author: Izaak Beekman | |
-: 6702:! | |
-: 6703:! CDK==CK operator. | |
-: 6704: | |
-: 6705: function default_comp_ucs4(def_str,ucs4_str) result(res) | |
#####: 6706: | |
-: 6707: implicit none | |
-: 6708: | |
-: 6709: character(kind=CDK,len=*), intent(in) :: def_str | |
-: 6710: character(kind=CK, len=*), intent(in) :: ucs4_str | |
-: 6711: logical(LK) :: res | |
-: 6712: | |
-: 6713: res = ( to_unicode(def_str) == ucs4_str) | |
#####: 6714: | |
-: 6715: end function default_comp_ucs4 | |
#####: 6716:!***************************************************************************************** | |
-: 6717: | |
-: 6718:!***************************************************************************************** | |
-: 6719:!> author: Jacob Williams | |
-: 6720:! | |
-: 6721:! Print any error message, and then clear the exceptions. | |
-: 6722:! | |
-: 6723:!@note This routine is used by the unit tests. | |
-: 6724:! It was originally in json_example.f90, and was | |
-: 6725:! moved here 2/26/2015 by Izaak Beekman. | |
-: 6726: | |
-: 6727: subroutine json_print_error_message(io_unit) | |
3: 6728: | |
-: 6729: implicit none | |
-: 6730: | |
-: 6731: integer, intent(in), optional :: io_unit | |
-: 6732: | |
-: 6733: character(kind=CK,len=:),allocatable :: error_msg | |
3: 6734: logical :: status_ok | |
-: 6735: | |
-: 6736: !get error message: | |
-: 6737: call json_check_for_errors(status_ok, error_msg) | |
3: 6738: | |
-: 6739: !print it if there is one: | |
-: 6740: if (.not. status_ok) then | |
3: 6741: if (present(io_unit)) then | |
3: 6742: write(io_unit,'(A)') error_msg | |
3: 6743: else | |
-: 6744: write(*,'(A)') error_msg | |
#####: 6745: end if | |
-: 6746: deallocate(error_msg) | |
3: 6747: call json_clear_exceptions() | |
3: 6748: end if | |
-: 6749: | |
-: 6750: end subroutine json_print_error_message | |
3: 6751:!***************************************************************************************** | |
-: 6752: | |
-: 6753:!***************************************************************************************** | |
-: 6754: end module json_module | |
#####: 6755:!***************************************************************************************** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fix it with: