Skip to content

Commit 5ac33e6

Browse files
filesystem: FS_ERROR helper functions (fortran-lang#1015)
2 parents 5eb711a + a2fadac commit 5ac33e6

13 files changed

+914
-16
lines changed

doc/specs/stdlib_system.md

Lines changed: 262 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ The result is a real value representing the elapsed time in seconds, measured fr
174174

175175
### Syntax
176176

177-
`delta_t = ` [[stdlib_system(module):elapsed(subroutine)]] `(process)`
177+
`delta_t = ` [[stdlib_system(module):elapsed(interface)]] `(process)`
178178

179179
### Arguments
180180

@@ -212,7 +212,7 @@ in case of process hang or delay.
212212

213213
### Syntax
214214

215-
`call ` [[stdlib_system(module):wait(subroutine)]] `(process [, max_wait_time])`
215+
`call ` [[stdlib_system(module):wait(interface)]] `(process [, max_wait_time])`
216216

217217
### Arguments
218218

@@ -243,7 +243,7 @@ This is especially useful for monitoring asynchronous processes and retrieving t
243243

244244
### Syntax
245245

246-
`call ` [[stdlib_system(module):update(subroutine)]] `(process)`
246+
`call ` [[stdlib_system(module):update(interface)]] `(process)`
247247

248248
### Arguments
249249

@@ -269,7 +269,7 @@ This interface is useful when a process needs to be forcefully stopped, for exam
269269

270270
### Syntax
271271

272-
`call ` [[stdlib_system(module):kill(subroutine)]] `(process, success)`
272+
`call ` [[stdlib_system(module):kill(interface)]] `(process, success)`
273273

274274
### Arguments
275275

@@ -298,7 +298,7 @@ It ensures that the requested sleep duration is honored on both Windows and Unix
298298

299299
### Syntax
300300

301-
`call ` [[stdlib_system(module):sleep(subroutine)]] `(millisec)`
301+
`call ` [[stdlib_system(module):sleep(interface)]] `(millisec)`
302302

303303
### Arguments
304304

@@ -324,7 +324,7 @@ This function is highly efficient and works during the compilation phase, avoidi
324324

325325
### Syntax
326326

327-
`result = ` [[stdlib_system(module):is_windows(function)]] `()`
327+
`result = ` [[stdlib_system(module):is_windows(interface)]] `()`
328328

329329
### Return Value
330330

@@ -359,7 +359,7 @@ If the OS cannot be identified, the function returns `OS_UNKNOWN`.
359359

360360
### Syntax
361361

362-
`os = [[stdlib_system(module):get_runtime_os(function)]]()`
362+
`os = ` [[stdlib_system(module):get_runtime_os(function)]] `()`
363363

364364
### Class
365365

@@ -396,7 +396,7 @@ This caching mechanism ensures negligible overhead for repeated calls, unlike `g
396396

397397
### Syntax
398398

399-
`os = [[stdlib_system(module):OS_TYPE(function)]]()`
399+
`os = ` [[stdlib_system(module):OS_TYPE(function)]]`()`
400400

401401
### Class
402402

@@ -418,6 +418,85 @@ Returns one of the `integer` `OS_*` parameters representing the OS type, from th
418418

419419
---
420420

421+
## `FS_ERROR` - Helper function for error handling
422+
423+
### Status
424+
425+
Experimental
426+
427+
### Description
428+
429+
A helper function for returning the `type(state_type)` with the flag `STDLIB_FS_ERROR` set.
430+
431+
### Syntax
432+
433+
`err = FS_ERROR([a1,a2,a3,a4...... a20])`
434+
435+
### Class
436+
Pure Function
437+
438+
### Arguments
439+
440+
`a1,a2,a3.....a20`(optional): They are of type `class(*), dimension(..), optional, intent(in)`.
441+
An arbitrary list of `integer`, `real`, `complex`, `character` or `string_type` variables. Numeric variables may be provided as either scalars or rank-1 (array) inputs.
442+
443+
### Behavior
444+
445+
Formats all the arguments into a nice error message, utilizing the constructor of [[stdlib_system(module):state_type(type)]]
446+
447+
### Return values
448+
449+
`type(state_type)`
450+
451+
### Example
452+
453+
```fortran
454+
{!example/system/example_fs_error.f90!}
455+
```
456+
457+
---
458+
459+
## `FS_ERROR_CODE` - Helper function for error handling (with error code)
460+
461+
### Status
462+
463+
Experimental
464+
465+
### Description
466+
467+
A helper function for returning the `type(state_type)` with the flag `STDLIB_FS_ERROR` set.
468+
It also formats and prefixes the `code` passed to it as the first argument.
469+
470+
### Syntax
471+
472+
`err = FS_ERROR_CODE(code [, a1,a2,a3,a4...... a19])`
473+
474+
### Class
475+
Pure Function
476+
477+
### Arguments
478+
479+
`code`: An `integer` code.
480+
481+
`a1,a2,a3.....a19`(optional): They are of type `class(*), dimension(..), optional, intent(in)`.
482+
An arbitrary list of `integer`, `real`, `complex`, `character` or `string_type` variables. Numeric variables may be provided as either scalars or rank-1 (array) inputs.
483+
484+
### Behavior
485+
486+
Formats all the arguments into a nice error message, utilizing the constructor of [[stdlib_system(module):state_type(type)]]
487+
488+
### Return values
489+
490+
`type(state_type)`
491+
492+
### Example
493+
494+
```fortran
495+
{!example/system/example_fs_error.f90!}
496+
```
497+
498+
---
499+
421500
## `is_directory` - Test if a path is a directory
422501

423502
### Status
@@ -431,7 +510,7 @@ It is designed to work across multiple platforms. On Windows, paths with both fo
431510

432511
### Syntax
433512

434-
`result = [[stdlib_system(module):is_directory(function)]] (path)`
513+
`result = ` [[stdlib_system(module):is_directory(function)]]`(path)`
435514

436515
### Class
437516

@@ -471,7 +550,7 @@ It reads as an empty file. The null device's path varies by operating system:
471550

472551
### Syntax
473552

474-
`path = [[stdlib_system(module):null_device(function)]]()`
553+
`path = ` [[stdlib_system(module):null_device(function)]]`()`
475554

476555
### Class
477556

@@ -506,7 +585,7 @@ The function provides an optional error-handling mechanism via the `state_type`
506585

507586
### Syntax
508587

509-
`call [[stdlib_system(module):delete_file(subroutine)]] (path [, err])`
588+
`call ` [[stdlib_system(module):delete_file(subroutine)]]` (path [, err])`
510589

511590
### Class
512591
Subroutine
@@ -532,3 +611,175 @@ The file is removed from the filesystem if the operation is successful. If the o
532611
```fortran
533612
{!example/system/example_delete_file.f90!}
534613
```
614+
615+
## `join_path` - Joins the provided paths according to the OS
616+
617+
### Status
618+
619+
Experimental
620+
621+
### Description
622+
623+
This interface joins the paths provided to it according to the platform specific path-separator.
624+
i.e `\` for windows and `/` for others
625+
626+
### Syntax
627+
628+
`res = ` [[stdlib_system(module):join_path(interface)]] ` (p1, p2)`
629+
630+
`res = ` [[stdlib_system(module):join_path(interface)]] ` (p)`
631+
632+
### Class
633+
Pure function
634+
635+
### Arguments
636+
637+
`p1, p2`: Shall be a character string or `type(string_type)`. It is an `intent(in)` argument.
638+
or
639+
`p`: Shall be a list of character strings or list of `type(string_type)`. It is an `intent(in)` argument.
640+
641+
### Return values
642+
643+
The resultant path, either a character string or `type(string_type)`.
644+
645+
## `operator(/)`
646+
647+
Alternative syntax to`join_path` using an overloaded operator. Join two paths according to the platform specific path-separator.
648+
649+
### Status
650+
651+
Experimental
652+
653+
### Syntax
654+
655+
`p = lval / rval`
656+
657+
### Class
658+
659+
Pure function.
660+
661+
### Arguments
662+
663+
`lval`: A character string or `type(string_type)`. It is an `intent(in)` argument.
664+
665+
`rval`: A character string or `type(string_type)`. It is an `intent(in)` argument.
666+
667+
### Result value
668+
669+
The result is an `allocatable` character string or `type(string_type)`
670+
671+
#### Example
672+
673+
```fortran
674+
{!example/system/example_path_join.f90!}
675+
```
676+
677+
## `split_path` - splits a path immediately following the last separator
678+
679+
### Status
680+
681+
Experimental
682+
683+
### Description
684+
685+
This subroutine splits a path immediately following the last separator after removing the trailing separators
686+
splitting it into most of the times a directory and a file name.
687+
688+
### Syntax
689+
690+
`call `[[stdlib_system(module):split_path(interface)]]`(p, head, tail)`
691+
692+
### Class
693+
Subroutine
694+
695+
### Arguments
696+
697+
`p`: A character string or `type(string_type)` containing the path to be split. It is an `intent(in)` argument.
698+
`head`: The first part of the path. Either a character string or `type(string_type)`. It is an `intent(out)` argument.
699+
`tail`: The rest part of the path. Either a character string or `type(string_type)`. It is an `intent(out)` argument.
700+
701+
### Behavior
702+
703+
- If `p` is empty, `head` is set to `.` and `tail` is left empty.
704+
- If `p` consists entirely of path-separators, `head` is set to the path-separator and `tail` is left empty.
705+
- `head` ends with a path-separator if and only if `p` appears to be a root directory or child of one.
706+
707+
### Return values
708+
709+
The splitted path. `head` and `tail`.
710+
711+
### Example
712+
713+
```fortran
714+
{!example/system/example_path_split_path.f90!}
715+
```
716+
717+
## `base_name` - The last part of a path
718+
719+
### Status
720+
721+
Experimental
722+
723+
### Description
724+
725+
This function returns the last part of a path after removing trailing path separators.
726+
727+
### Syntax
728+
729+
`res = ` [[stdlib_system(module):base_name(interface)]]`(p)`
730+
731+
### Class
732+
Function
733+
734+
### Arguments
735+
736+
`p`: the path, a character string or `type(string_type)`. It is an `intent(in)` argument.
737+
738+
### Behavior
739+
740+
- The `tail` of `[[stdlib_system(module):split_path(interface)]]` is exactly what is returned. Same Behavior.
741+
742+
### Return values
743+
744+
A character string or `type(string_type)`.
745+
746+
### Example
747+
748+
```fortran
749+
{!example/system/example_path_base_name.f90!}
750+
```
751+
752+
## `dir_name` - Everything except the last part of the path
753+
754+
### Status
755+
756+
Experimental
757+
758+
### Description
759+
760+
This function returns everything except the last part of a path.
761+
762+
### Syntax
763+
764+
`res = ` [[stdlib_system(module):dir_name(interface)]]`(p)`
765+
766+
### Class
767+
Function
768+
769+
### Arguments
770+
771+
`p`: the path, a character string or `type(string_type)`. It is an `intent(in)` argument.
772+
773+
### Behavior
774+
775+
- The `head` of `[[stdlib_system(module):split_path(interface)]]` is exactly what is returned. Same Behavior.
776+
777+
### Return values
778+
779+
A character string or `type(string_type)`.
780+
781+
### Example
782+
783+
```fortran
784+
{!example/system/example_path_dir_name.f90!}
785+
```

example/system/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ ADD_EXAMPLE(process_5)
1111
ADD_EXAMPLE(process_6)
1212
ADD_EXAMPLE(process_7)
1313
ADD_EXAMPLE(sleep)
14+
ADD_EXAMPLE(fs_error)
15+
ADD_EXAMPLE(path_join)
16+
ADD_EXAMPLE(path_split_path)
17+
ADD_EXAMPLE(path_base_name)
18+
ADD_EXAMPLE(path_dir_name)
19+

example/system/example_fs_error.f90

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
! Demonstrate usage of `FS_ERROR`, `FS_ERROR_CODE`
2+
program example_fs_error
3+
use stdlib_system, only: FS_ERROR, FS_ERROR_CODE
4+
use stdlib_error, only: state_type, STDLIB_FS_ERROR
5+
implicit none
6+
7+
type(state_type) :: err0, err1
8+
9+
err0 = FS_ERROR("Could not create directory", "`temp.dir`", "- Already exists")
10+
11+
if (err0%state == STDLIB_FS_ERROR) then
12+
! Error encountered: Filesystem Error: Could not create directory `temp.dir` - Already exists
13+
print *, err0%print()
14+
end if
15+
16+
err1 = FS_ERROR_CODE(1, "Could not create directory", "`temp.dir`", "- Already exists")
17+
18+
if (err1%state == STDLIB_FS_ERROR) then
19+
! Error encountered: Filesystem Error: code - 1, Could not create directory `temp.dir` - Already exists
20+
print *, err1%print()
21+
end if
22+
23+
end program example_fs_error

0 commit comments

Comments
 (0)