@@ -64,6 +64,9 @@ module json_string_utilities
64
64
public :: real_to_string
65
65
public :: string_to_integer
66
66
public :: string_to_real
67
+ #ifdef C_STR2REAL
68
+ public :: string_to_real_c
69
+ #endif
67
70
public :: valid_json_hex
68
71
public :: to_unicode
69
72
public :: escape_string
@@ -234,6 +237,7 @@ subroutine string_to_real(str,use_quiet_nan,rval,status_ok)
234
237
integer (IK) :: ierr ! ! read iostat error code
235
238
236
239
read (str,fmt=* ,iostat= ierr) rval
240
+
237
241
status_ok = (ierr== 0 )
238
242
if (.not. status_ok) then
239
243
rval = 0.0_RK
@@ -253,6 +257,135 @@ subroutine string_to_real(str,use_quiet_nan,rval,status_ok)
253
257
end subroutine string_to_real
254
258
! *****************************************************************************************
255
259
260
+ #ifdef C_STR2REAL
261
+ ! *****************************************************************************************
262
+ ! > author: Jacob Williams
263
+ ! date: 11/05/2021
264
+ !
265
+ ! Convert a string into a `real(RK)`.
266
+ ! This version uses `strtof`, `strtod`, or `strtold` from C.
267
+ ! It will fall back to using `read(fmt=*)` if any errors.
268
+ !
269
+ ! # History
270
+ ! * Jacob Williams : 11/05/2021 : created by modification of [[string_to_real]].
271
+
272
+ subroutine string_to_real_c (str ,use_quiet_nan ,rval ,status_ok )
273
+
274
+ use iso_c_binding, only: c_double, c_float, c_long_double, &
275
+ c_char, c_ptr, c_null_ptr, c_long, &
276
+ c_null_char
277
+
278
+ implicit none
279
+
280
+ character (kind= CK,len=* ),intent (in ) :: str ! ! the string to convert to a real
281
+ logical (LK),intent (in ) :: use_quiet_nan ! ! if true, return NaN's as `ieee_quiet_nan`.
282
+ ! ! otherwise, use `ieee_signaling_nan`.
283
+ real (RK),intent (out ) :: rval ! ! `str` converted to a real value
284
+ logical (LK),intent (out ) :: status_ok ! ! true if there were no errors
285
+
286
+ integer (IK) :: ierr ! ! read iostat error code
287
+ type (c_ptr) :: endptr ! ! pointer arg to `strtof`, etc.
288
+
289
+ interface
290
+ function strtof ( str , endptr ) result(d) bind(C, name= " strtof" )
291
+ ! ! <stdlib.h> :: float strtof(const char *str, char **endptr)
292
+ import
293
+ character (kind= c_char,len= 1 ),dimension (* ),intent (in ) :: str
294
+ type (c_ptr), intent (inout ) :: endptr
295
+ real (c_float) :: d
296
+ end function strtof
297
+ function strtod ( str , endptr ) result(d) bind(C, name= " strtod" )
298
+ ! ! <stdlib.h> :: double strtod(const char *str, char **endptr)
299
+ import
300
+ character (kind= c_char,len= 1 ),dimension (* ),intent (in ) :: str
301
+ type (c_ptr), intent (inout ) :: endptr
302
+ real (c_double) :: d
303
+ end function strtod
304
+ function strtold ( str , endptr ) result(d) bind(C, name= " strtold" )
305
+ ! ! <stdlib.h> :: long double strtold(const char *str, char **endptr)
306
+ import
307
+ character (kind= c_char,len= 1 ),dimension (* ),intent (in ) :: str
308
+ type (c_ptr), intent (inout ) :: endptr
309
+ real (c_long_double) :: d
310
+ end function strtold
311
+ end interface
312
+
313
+ #ifdef USE_UCS4
314
+ ! if using unicode, don't try to call the C routines
315
+ ! [not sure they will work? need to test this... what if c_char /= CK?]
316
+ call string_to_real(str,use_quiet_nan,rval,status_ok)
317
+ return
318
+ #endif
319
+
320
+ endptr = c_null_ptr ! indicates it is not used
321
+
322
+ #ifdef REAL32
323
+
324
+ ! single precision
325
+
326
+ if (RK == c_float) then
327
+ rval = strtof( str// C_NULL_CHAR, endptr )
328
+ if (rval== 0.0_RK ) then
329
+ read (str,fmt=* ,iostat= ierr) rval ! not efficient - might really be 0.0
330
+ else
331
+ ierr = 0
332
+ end if
333
+ else
334
+ read (str,fmt=* ,iostat= ierr) rval
335
+ end if
336
+
337
+ #elif REAL128
338
+
339
+ ! quad precision
340
+
341
+ if (RK == c_long_double) then
342
+ rval = strtold( str// C_NULL_CHAR, endptr )
343
+ if (rval== 0.0_RK ) then
344
+ read (str,fmt=* ,iostat= ierr) rval ! not efficient - might really be 0.0
345
+ else
346
+ ierr = 0
347
+ end if
348
+ else
349
+ read (str,fmt=* ,iostat= ierr) rval
350
+ end if
351
+
352
+ #else
353
+
354
+ ! double precision
355
+
356
+ if (RK == c_double) then
357
+ rval = strtod( str// C_NULL_CHAR, endptr )
358
+ if (rval== 0.0_RK ) then
359
+ read (str,fmt=* ,iostat= ierr) rval ! not efficient - might really be 0.0
360
+ else
361
+ ierr = 0
362
+ end if
363
+ else
364
+ read (str,fmt=* ,iostat= ierr) rval
365
+ end if
366
+
367
+ #endif
368
+
369
+ status_ok = (ierr== 0 )
370
+ if (.not. status_ok) then
371
+ rval = 0.0_RK
372
+ else
373
+ if (ieee_support_nan(rval)) then
374
+ if (ieee_is_nan(rval)) then
375
+ ! make sure to return the correct NaN
376
+ if (use_quiet_nan) then
377
+ rval = ieee_value(rval,ieee_quiet_nan)
378
+ else
379
+ rval = ieee_value(rval,ieee_signaling_nan)
380
+ end if
381
+ end if
382
+ end if
383
+ end if
384
+
385
+ end subroutine string_to_real_c
386
+ ! *****************************************************************************************
387
+ #endif
388
+
256
389
! *****************************************************************************************
257
390
! > author: Izaak Beekman
258
391
! date: 02/24/2015
0 commit comments