Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add format_string routine to format other types to strings #444

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e3829b4
add:
zoziha Jun 25, 2021
da2881c
remove a redundant comma in doc
St-Maxwell Jun 26, 2021
c622a5b
fix format_string routines update its doc.
zoziha Jun 26, 2021
193f07f
Expand unit testing for more cases
awvwgk Jun 26, 2021
7f6c3c6
Merge pull request #1 from awvwgk/format_string
St-Maxwell Jun 26, 2021
41c5783
Try to make default formatter tests compiler independent
awvwgk Jun 26, 2021
785902c
fix test_strings_format_string.f90 for [this problem](https://github.…
zoziha Jun 26, 2021
39d5d13
Merge branch 'zoziha/feature/format_string' of https://github.com/St-…
zoziha Jun 26, 2021
99954bb
update test_string_format_string.f90
zoziha Jun 26, 2021
f9f7755
Make invalid logical example more compiler agnostic
awvwgk Jun 26, 2021
e7ce1e7
update format_string example in stdlib_string.md(doc)
zoziha Jun 27, 2021
65ab05d
improved aesthetics to make code consistent with stdlib's format
aman-godara Jun 27, 2021
34fa3cd
improved aesthetics of test file and documentation
aman-godara Jun 28, 2021
7ae89fb
Merge pull request #2 from Aman-Godara/format_string
zoziha Jun 28, 2021
1fe6a07
renamed strings_format_string to string_format_string
aman-godara Jul 1, 2021
f155525
Merge pull request #3 from Aman-Godara/format_string
St-Maxwell Jul 1, 2021
f1bc676
Merge branch 'master' into zoziha/feature/format_string
zoziha Jul 2, 2021
835de22
Fix manual Makefile build
awvwgk Jul 3, 2021
b05cbae
rename `format_string` to `format_to_string`;
zoziha Jul 5, 2021
e646fc5
Merge branch 'master' into zoziha/feature/format_string
zoziha Jul 5, 2021
c717724
Merge `stdlib_ascii(module):to_string(interface)` to `stdlib_strings(…
zoziha Aug 3, 2021
7fa847a
Merge branch 'master' into merge_tostring
zoziha Aug 3, 2021
bdc33f5
Some clean works for `to_string` func.
zoziha Aug 4, 2021
f3c17a0
Fix `test_string_to_string.f90`: `merge` -> `optval`
zoziha Aug 11, 2021
ce272d7
Merge branch 'master' into zoziha/feature/format_string
zoziha Aug 11, 2021
527daed
Consistent indentation in Makefile
milancurcic Aug 19, 2021
32f9837
Improve `to_string`: add support for `format` like `'f6.2'`.
zoziha Aug 22, 2021
3e31220
Merge branch 'zoziha/feature/format_string' of https://github.com/St-…
zoziha Aug 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 1 addition & 39 deletions doc/specs/stdlib_ascii.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,42 +212,4 @@ program demo_reverse
implicit none
print'(a)', reverse("Hello, World!") ! returns "!dlroW ,olleH"
end program demo_reverse
```

### `to_string`

#### Status

Experimental

#### Description

Create a character string representing the value of the provided variable.

#### Syntax

`res = [[stdlib_ascii(module):to_string(interface)]] (string)`

#### Class

Pure function.

#### Argument

`val`: shall be an intrinsic integer or logical type. It is an `intent(in)` argument.

#### Result value

The result is an intrinsic character type.

#### Example

```fortran
program demo_string_value
use stdlib_ascii, only : to_string
implicit none
print'(a)', to_string(-3) ! returns "-3"
print'(a)', to_string(.true.) ! returns "T"
print'(a)', to_string(42) ! returns "42"
end program demo_string_value
```
```
66 changes: 66 additions & 0 deletions doc/specs/stdlib_strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,69 @@ program demo_count

end program demo_count
```

<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `to_string`

#### Description

Format or transfer a `integer/real/complex/logical` scalar as a string.
Input a wrong `format` that cause the internal-IO to fail, the result value is a string of `[*]`.

#### Syntax

`string = [[stdlib_strings(module):to_string(interface)]] (value [, format])`

#### Status

Experimental

#### Class

Pure function.

#### Argument

- `value`: Shall be an `integer/real/complex/logical` scalar.
This is an `intent(in)` argument.
- `format`: Shall be a `character(len=*)` scalar like `'(F6.2)'`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zoziha @awvwgk Suggestion for docs improvement, to go together with #444 (comment).

Suggested change
- `format`: Shall be a `character(len=*)` scalar like `'(F6.2)'`.
- `format`: Shall be a `character(len=*)` scalar that contains the edit descriptor to format `value` into a string,
for example `'(F6.2)'` or `'(f6.2)'`. `to_string` will automatically enclose `format` in a set of parentheses,
so passing `F6.2` or `f6.2` as `format` is possible as well.

This is an `intent(in)` and `optional` argument.

#### Result value

The result is an `allocatable` length `character` scalar with up to `128` cached `character` length.

#### Example

```fortran
program demo_to_string
use stdlib_strings, only: to_string
implicit none

!> Example for `complex` type
print *, to_string((1, 1)) !! "(1.00000000,1.00000000)"
print *, to_string((1, 1), '(F6.2)') !! "( 1.00, 1.00)"
print *, to_string((1000, 1), '(ES0.2)'), to_string((1000, 1), '(SP,F6.3)')
!! "(1.00E+3,1.00)""(******,+1.000)"
!! Too narrow formatter for real number
!! Normal demonstration(`******` from Fortran Standard)

!> Example for `integer` type
print *, to_string(-3) !! "-3"
print *, to_string(42, '(I4)') !! " 42"
print *, to_string(1, '(I0.4)'), to_string(2, '(B4)') !! "0001"" 10"

!> Example for `real` type
print *, to_string(1.) !! "1.00000000"
print *, to_string(1., '(F6.2)') !! " 1.00"
print *, to_string(1., '(SP,ES9.2)'), to_string(1, '(F7.3)') !! "+1.00E+00""[*]"
!! 1 wrong demonstration (`[*]` from `to_string`)

!> Example for `logical` type
print *, to_string(.true.) !! "T"
print *, to_string(.true., '(L2)') !! " T"
print *, to_string(.true., 'L2'), to_string(.false., '(I5)') !! "[*]""[*]"
!! 2 wrong demonstrations(`[*]` from `to_string`)

end program demo_to_string
```
4 changes: 3 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ set(fppFiles
stdlib_math_logspace.fypp
stdlib_math_arange.fypp
stdlib_string_type.fypp
stdlib_string_type_constructor.fypp
stdlib_strings_to_string.fypp
stdlib_strings.fypp
)


Expand All @@ -52,7 +55,6 @@ set(SRC
stdlib_error.f90
stdlib_kinds.f90
stdlib_logger.f90
stdlib_strings.f90
stdlib_system.F90
stdlib_specialfunctions.f90
stdlib_specialfunctions_legendre.f90
Expand Down
112 changes: 59 additions & 53 deletions src/Makefile.manual
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SRCFYPP =\
SRCFYPP = \
stdlib_ascii.fypp \
stdlib_bitsets_64.fypp \
stdlib_bitsets_large.fypp \
Expand Down Expand Up @@ -27,10 +27,13 @@ SRCFYPP =\
stdlib_stats_moment_scalar.fypp \
stdlib_stats_var.fypp \
stdlib_math.fypp \
stdlib_math_linspace.fypp \
stdlib_math_logspace.fypp \
stdlib_math_linspace.fypp \
stdlib_math_logspace.fypp \
stdlib_stats_distribution_PRNG.fypp \
stdlib_string_type.fypp
stdlib_string_type.fypp \
stdlib_string_type_constructor.fypp \
stdlib_strings.fypp \
stdlib_strings_to_string.fypp

SRC = f18estop.f90 \
stdlib_error.f90 \
Expand All @@ -40,7 +43,6 @@ SRC = f18estop.f90 \
stdlib_kinds.f90 \
stdlib_logger.f90 \
stdlib_quadrature_gauss.f90 \
stdlib_strings.f90 \
$(SRCGEN)

LIB = libstdlib.a
Expand Down Expand Up @@ -77,85 +79,89 @@ stdlib_error.o: stdlib_optval.o
stdlib_specialfunctions.o: stdlib_kinds.o
stdlib_specialfunctions_legendre.o: stdlib_kinds.o stdlib_specialfunctions.o
stdlib_io.o: \
stdlib_ascii.o \
stdlib_error.o \
stdlib_optval.o \
stdlib_kinds.o
stdlib_ascii.o \
stdlib_error.o \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_ascii.o
stdlib_linalg.o: \
stdlib_kinds.o
stdlib_kinds.o
stdlib_linalg_diag.o: \
stdlib_linalg.o \
stdlib_kinds.o
stdlib_linalg.o \
stdlib_kinds.o
stdlib_logger.o: stdlib_ascii.o stdlib_optval.o
stdlib_optval.o: stdlib_kinds.o
stdlib_quadrature.o: stdlib_kinds.o

stdlib_quadrature_gauss.o: stdlib_kinds.o stdlib_quadrature.o

stdlib_quadrature_simps.o: \
stdlib_quadrature.o \
stdlib_error.o \
stdlib_kinds.o
stdlib_quadrature.o \
stdlib_error.o \
stdlib_kinds.o
stdlib_quadrature_trapz.o: \
stdlib_quadrature.o \
stdlib_error.o \
stdlib_kinds.o
stdlib_quadrature.o \
stdlib_error.o \
stdlib_kinds.o
stdlib_sorting.o: \
stdlib_kinds.o \
stdlib_string_type.o
stdlib_kinds.o \
stdlib_string_type.o
stdlib_sorting_ord_sort.o: \
stdlib_sorting.o
stdlib_sorting.o
stdlib_sorting_sort.o: \
stdlib_sorting.o
stdlib_sorting.o
stdlib_sorting_sort_index.o: \
stdlib_sorting.o
stdlib_sorting.o
stdlib_stats.o: \
stdlib_kinds.o
stdlib_kinds.o
stdlib_stats_corr.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_stats_cov.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_stats_mean.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_stats_median.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_sorting.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_sorting.o \
stdlib_stats.o
stdlib_stats_moment.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_stats_moment_all.o: \
stdlib_stats_moment.o
stdlib_stats_moment.o
stdlib_stats_moment_mask.o: \
stdlib_stats_moment.o
stdlib_stats_moment.o
stdlib_stats_moment_scalar.o: \
stdlib_stats_moment.o
stdlib_stats_moment.o
stdlib_stats_var.o: \
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_optval.o \
stdlib_kinds.o \
stdlib_stats.o
stdlib_stats_distribution_PRNG.o: \
stdlib_kinds.o \
stdlib_error.o
stdlib_kinds.o \
stdlib_error.o
stdlib_string_type.o: stdlib_ascii.o \
stdlib_kinds.o
stdlib_string_type_constructor.o: stdlib_string_type.o \
stdlib_strings_to_string.o \
stdlib_strings.o
stdlib_strings.o: stdlib_ascii.o \
stdlib_string_type.o \
stdlib_optval.o
stdlib_optval.o \
stdlib_kinds.o
stdlib_strings_to_string.o: stdlib_strings.o
stdlib_math.o: stdlib_kinds.o \
stdlib_optval.o
stdlib_math_linspace.o: \
stdlib_math.o
stdlib_math.o
stdlib_math_logspace.o: \
stdlib_math_linspace.o
stdlib_math_linspace.o
stdlib_math_arange.o: \
stdlib_math.o
stdlib_linalg_outer_product.o: stdlib_linalg.o
60 changes: 0 additions & 60 deletions src/stdlib_ascii.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,6 @@ module stdlib_ascii

! Character conversion functions
public :: to_lower, to_upper, to_title, to_sentence, reverse
public :: to_string

!> Version: experimental
!>
!> Create a character string representing the value of the provided variable.
interface to_string
#:for kind in INT_KINDS
module procedure :: to_string_integer_${kind}$
#:endfor
#:for kind in LOG_KINDS
module procedure :: to_string_logical_${kind}$
#:endfor
end interface to_string

! All control characters in the ASCII table (see www.asciitable.com).
character(len=1), public, parameter :: NUL = achar(int(z'00')) !! Null
Expand Down Expand Up @@ -362,51 +349,4 @@ contains

end function reverse

#:for kind in INT_KINDS
!> Represent an integer of kind ${kind}$ as character sequence
pure function to_string_integer_${kind}$(val) result(string)
integer, parameter :: ik = ${kind}$
integer(ik), intent(in) :: val
character(len=:), allocatable :: string
integer, parameter :: buffer_len = range(val)+2
character(len=buffer_len) :: buffer
integer :: pos
integer(ik) :: n
character(len=1), parameter :: numbers(0:9) = &
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

if (val == 0_ik) then
string = numbers(0)
return
end if

n = abs(val)
buffer = ""

pos = buffer_len + 1
do while (n > 0_ik)
pos = pos - 1
buffer(pos:pos) = numbers(mod(n, 10_ik))
n = n/10_ik
end do
if (val < 0_ik) then
pos = pos - 1
buffer(pos:pos) = '-'
end if

string = buffer(pos:)
end function to_string_integer_${kind}$
#:endfor

#:for kind in LOG_KINDS
!> Represent an logical of kind ${kind}$ as character sequence
pure function to_string_logical_${kind}$(val) result(string)
integer, parameter :: ik = ${kind}$
logical(ik), intent(in) :: val
character(len=1) :: string

string = merge("T", "F", val)
end function to_string_logical_${kind}$
#:endfor

end module stdlib_ascii
Loading