Line data Source code
1 : !> HSD - Human-friendly Structured Data for Fortran
2 : !>
3 : !> This is the main public API module for the HSD library.
4 : !> It re-exports all necessary types and procedures for working with HSD data.
5 : !>
6 : !> The API is organized into several focused submodules:
7 : !> - hsd_accessors: Data retrieval (hsd_get, hsd_get_or, hsd_get_matrix)
8 : !> - hsd_mutators: Data modification (hsd_set)
9 : !> - hsd_query: Navigation and tree operations (hsd_get_child, hsd_merge, hsd_clone)
10 : !> - hsd_validation: Data validation (hsd_require, hsd_validate_*)
11 : !> - hsd_schema: Declarative schema validation
12 : !>
13 : !> ## Thread Safety
14 : !>
15 : !> The HSD library is designed for single-threaded use but supports certain
16 : !> concurrent access patterns:
17 : !>
18 : !> - **Thread-safe**: Parsing different files concurrently, reading from a
19 : !> shared tree (read-only), validating with a shared schema
20 : !> - **NOT thread-safe**: Modifying a shared tree, using shared iterators,
21 : !> parsing to the same tree
22 : !>
23 : !> For detailed thread safety information, see docs/thread_safety.md
24 : !>
25 : !> ## Example usage
26 : !>
27 : !> ```fortran
28 : !> use hsd
29 : !> type(hsd_table) :: root
30 : !> type(hsd_error_t), allocatable :: error
31 : !> integer :: value
32 : !>
33 : !> call hsd_load("input.hsd", root, error)
34 : !> if (allocated(error)) then
35 : !> call error%print()
36 : !> stop 1
37 : !> end if
38 : !>
39 : !> call hsd_get(root, "some/path/to/value", value)
40 : !> ```
41 : module hsd
42 : ! Core infrastructure
43 : use hsd_constants, only: dp, sp
44 : use hsd_error, only: hsd_error_t, hsd_stat, &
45 : HSD_STAT_OK, HSD_STAT_SYNTAX_ERROR, HSD_STAT_UNCLOSED_TAG, &
46 : HSD_STAT_UNCLOSED_ATTRIB, HSD_STAT_UNCLOSED_QUOTE, HSD_STAT_ORPHAN_TEXT, &
47 : HSD_STAT_INCLUDE_CYCLE, HSD_STAT_INCLUDE_DEPTH, HSD_STAT_FILE_NOT_FOUND, &
48 : HSD_STAT_IO_ERROR, HSD_STAT_TYPE_ERROR, HSD_STAT_NOT_FOUND
49 : use hsd_types, only: hsd_node, hsd_table, hsd_value, hsd_node_ptr, hsd_iterator, &
50 : new_table, new_value, &
51 : VALUE_TYPE_NONE, VALUE_TYPE_STRING, VALUE_TYPE_INTEGER, &
52 : VALUE_TYPE_REAL, VALUE_TYPE_LOGICAL, VALUE_TYPE_ARRAY, VALUE_TYPE_COMPLEX
53 : use hsd_parser, only: hsd_parse, hsd_parse_string
54 : use hsd_formatter, only: hsd_dump, hsd_dump_to_string
55 : use hsd_visitor, only: hsd_visitor_t, hsd_accept
56 :
57 : ! Specialized API modules
58 : use hsd_accessors, only: hsd_get, hsd_get_or, hsd_get_matrix
59 : use hsd_mutators, only: hsd_set
60 : use hsd_query, only: hsd_get_child, hsd_get_table, hsd_has_child, &
61 : hsd_remove_child, hsd_get_type, hsd_is_table, hsd_is_value, hsd_is_array, &
62 : hsd_child_count, hsd_get_keys, hsd_get_attrib, hsd_has_attrib, &
63 : hsd_merge, hsd_clone
64 : use hsd_validation, only: hsd_require, hsd_validate_range, hsd_validate_one_of, &
65 : hsd_get_with_unit
66 : use hsd_schema, only: hsd_schema_t, hsd_field_def_t, &
67 : FIELD_REQUIRED, FIELD_OPTIONAL, &
68 : FIELD_TYPE_ANY, FIELD_TYPE_STRING, FIELD_TYPE_INTEGER, &
69 : FIELD_TYPE_REAL, FIELD_TYPE_LOGICAL, FIELD_TYPE_TABLE, &
70 : FIELD_TYPE_ARRAY, FIELD_TYPE_COMPLEX, HSD_STAT_SCHEMA_ERROR, &
71 : schema_init, schema_destroy, schema_add_field, schema_add_field_enum, &
72 : schema_validate, schema_validate_strict
73 :
74 : implicit none (type, external)
75 : private
76 :
77 : ! Re-export public types and constants
78 : public :: dp, sp
79 : public :: hsd_error_t, hsd_stat
80 : public :: HSD_STAT_OK, HSD_STAT_SYNTAX_ERROR, HSD_STAT_UNCLOSED_TAG
81 : public :: HSD_STAT_UNCLOSED_ATTRIB, HSD_STAT_UNCLOSED_QUOTE, HSD_STAT_ORPHAN_TEXT
82 : public :: HSD_STAT_INCLUDE_CYCLE, HSD_STAT_INCLUDE_DEPTH, HSD_STAT_FILE_NOT_FOUND
83 : public :: HSD_STAT_IO_ERROR, HSD_STAT_TYPE_ERROR, HSD_STAT_NOT_FOUND
84 : public :: hsd_node, hsd_table, hsd_value, hsd_node_ptr, hsd_iterator
85 : public :: new_table, new_value
86 : public :: VALUE_TYPE_NONE, VALUE_TYPE_STRING, VALUE_TYPE_INTEGER
87 : public :: VALUE_TYPE_REAL, VALUE_TYPE_LOGICAL, VALUE_TYPE_ARRAY
88 : public :: VALUE_TYPE_COMPLEX
89 :
90 : ! Re-export I/O procedures
91 : public :: hsd_load, hsd_load_string
92 : public :: hsd_dump, hsd_dump_to_string
93 :
94 : ! Re-export data accessors (from hsd_accessors)
95 : public :: hsd_get, hsd_get_or, hsd_get_matrix
96 :
97 : ! Re-export data mutators (from hsd_mutators)
98 : public :: hsd_set
99 :
100 : ! Re-export query operations (from hsd_query)
101 : public :: hsd_get_child, hsd_get_table, hsd_has_child
102 : public :: hsd_remove_child
103 : public :: hsd_get_type, hsd_is_table, hsd_is_value, hsd_is_array
104 : public :: hsd_child_count, hsd_get_keys
105 : public :: hsd_get_attrib, hsd_has_attrib
106 : public :: hsd_merge, hsd_clone
107 :
108 : ! Re-export validation (from hsd_validation)
109 : public :: hsd_require, hsd_validate_range, hsd_validate_one_of
110 : public :: hsd_get_with_unit
111 :
112 : ! Re-export schema validation (from hsd_schema)
113 : public :: hsd_schema_t, hsd_field_def_t
114 : public :: FIELD_REQUIRED, FIELD_OPTIONAL
115 : public :: FIELD_TYPE_ANY, FIELD_TYPE_STRING, FIELD_TYPE_INTEGER
116 : public :: FIELD_TYPE_REAL, FIELD_TYPE_LOGICAL, FIELD_TYPE_TABLE
117 : public :: FIELD_TYPE_ARRAY, FIELD_TYPE_COMPLEX, HSD_STAT_SCHEMA_ERROR
118 : public :: schema_init, schema_destroy, schema_add_field, schema_add_field_enum
119 : public :: schema_validate, schema_validate_strict
120 :
121 : ! Re-export visitor pattern
122 : public :: hsd_visitor_t, hsd_accept
123 :
124 : contains
125 :
126 : !> Load HSD from a file (convenience wrapper)
127 34 : subroutine hsd_load(filename, root, error)
128 : character(len=*), intent(in) :: filename
129 : type(hsd_table), intent(out) :: root
130 : type(hsd_error_t), allocatable, intent(out), optional :: error
131 :
132 17 : call hsd_parse(filename, root, error)
133 :
134 34 : end subroutine hsd_load
135 :
136 : !> Load HSD from a string (convenience wrapper)
137 3100 : subroutine hsd_load_string(source, root, error, filename)
138 : character(len=*), intent(in) :: source
139 : type(hsd_table), intent(out) :: root
140 : type(hsd_error_t), allocatable, intent(out), optional :: error
141 : character(len=*), intent(in), optional :: filename
142 :
143 1550 : call hsd_parse_string(source, root, error, filename)
144 :
145 1567 : end subroutine hsd_load_string
146 :
147 : end module hsd
|