@@ -2,6 +2,7 @@ module pcre_api |
| 2 | !> PCRE2 library bindings for Perl-compatible regular expressions | 2 | !> PCRE2 library bindings for Perl-compatible regular expressions |
| 3 | !> Uses iso_c_binding for C interoperability with libpcre2-8 | 3 | !> Uses iso_c_binding for C interoperability with libpcre2-8 |
| 4 | use, intrinsic :: iso_c_binding | 4 | use, intrinsic :: iso_c_binding |
| | 5 | + use ferp_kinds, only: pattern_len |
| 5 | implicit none | 6 | implicit none |
| 6 | private | 7 | private |
| 7 | | 8 | |
@@ -159,27 +160,32 @@ contains |
| 159 | logical, intent(in), optional :: ignore_case | 160 | logical, intent(in), optional :: ignore_case |
| 160 | integer, intent(out) :: ierr | 161 | integer, intent(out) :: ierr |
| 161 | | 162 | |
| 162 | - character(len=len_trim(pattern)+1, kind=c_char) :: c_pattern | 163 | + integer :: plen |
| | 164 | + character(len=:), allocatable :: c_pattern |
| 163 | integer(c_int) :: options, errorcode | 165 | integer(c_int) :: options, errorcode |
| 164 | - integer(c_size_t) :: erroroffset, pattern_len | 166 | + integer(c_size_t) :: erroroffset, pcre_pattern_len |
| 165 | | 167 | |
| 166 | ierr = 0 | 168 | ierr = 0 |
| 167 | re%compiled = .false. | 169 | re%compiled = .false. |
| 168 | re%error_code = 0 | 170 | re%error_code = 0 |
| 169 | re%error_msg = '' | 171 | re%error_msg = '' |
| 170 | | 172 | |
| | 173 | + ! Get actual pattern length (preserving whitespace patterns) |
| | 174 | + plen = pattern_len(pattern) |
| | 175 | + |
| 171 | ! Set options - enable UTF-8 and Unicode properties by default | 176 | ! Set options - enable UTF-8 and Unicode properties by default |
| 172 | options = ior(PCRE2_UTF, PCRE2_UCP) | 177 | options = ior(PCRE2_UTF, PCRE2_UCP) |
| 173 | if (present(ignore_case)) then | 178 | if (present(ignore_case)) then |
| 174 | if (ignore_case) options = ior(options, PCRE2_CASELESS) | 179 | if (ignore_case) options = ior(options, PCRE2_CASELESS) |
| 175 | end if | 180 | end if |
| 176 | | 181 | |
| 177 | - ! Prepare pattern as C string | 182 | + ! Prepare pattern as C string (use exact length, not trim) |
| 178 | - c_pattern = trim(pattern) // c_null_char | 183 | + allocate(character(len=plen+1) :: c_pattern) |
| 179 | - pattern_len = int(len_trim(pattern), c_size_t) | 184 | + c_pattern = pattern(1:plen) // c_null_char |
| | 185 | + pcre_pattern_len = int(plen, c_size_t) |
| 180 | | 186 | |
| 181 | ! Compile pattern | 187 | ! Compile pattern |
| 182 | - re%code = pcre2_compile_8(c_pattern, pattern_len, options, & | 188 | + re%code = pcre2_compile_8(c_pattern, pcre_pattern_len, options, & |
| 183 | errorcode, erroroffset, c_null_ptr) | 189 | errorcode, erroroffset, c_null_ptr) |
| 184 | | 190 | |
| 185 | if (.not. c_associated(re%code)) then | 191 | if (.not. c_associated(re%code)) then |