Skip to content

Commit 4c1e40f

Browse files
committed
bugfix: character class including only one space [ ]
1 parent 5668149 commit 4c1e40f

File tree

7 files changed

+38
-21
lines changed

7 files changed

+38
-21
lines changed

project/fortran-regex.depend

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# depslib dependency file v1.0
2-
1671301959 source:/Users/federico/code/fortran-regex/src/regex.f90
2+
1671311068 source:/Users/federico/code/fortran-regex/src/regex.f90
33

44
1671276031 source:/Users/federico/code/fortran-regex/test/test_1.f90
55

project/regex_module.mod

80 Bytes
Binary file not shown.

project/regex_test_1.mod

77 Bytes
Binary file not shown.

project/regex_test_2.mod

43 Bytes
Binary file not shown.

src/regex.f90

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ module regex_module
7373
integer :: type = UNUSED
7474

7575
! Single or multi-character pattern
76-
character(kind=RCK,len=MAX_CHAR_CLASS_LEN) :: ccl = repeat(' ',MAX_CHAR_CLASS_LEN)
77-
76+
character(kind=RCK,len=:), allocatable :: ccl
7877
contains
7978

8079
procedure :: print => print_pattern
@@ -112,8 +111,9 @@ module regex_module
112111
! Clean up a pattern
113112
elemental subroutine pat_destroy(this)
114113
class(regex_pattern), intent(inout) :: this
114+
integer :: ierr
115115
this%type = UNUSED
116-
this%ccl = repeat(' ',MAX_CHAR_CLASS_LEN)
116+
deallocate(this%ccl,stat=ierr)
117117
end subroutine pat_destroy
118118

119119
! Number of rules in the current pattern
@@ -147,19 +147,17 @@ end subroutine write_pattern
147147

148148
elemental subroutine destroy(this)
149149
class(regex_op), intent(inout) :: this
150-
integer :: i,ierr
150+
integer :: i
151151
do i=1,MAX_REGEXP_OBJECTS
152-
this%pattern(i)%type = UNUSED
153-
this%pattern(i)%ccl = ''
152+
call this%pattern(i)%destroy()
154153
end do
155154
end subroutine destroy
156155

157156
subroutine finalize(this)
158157
type(regex_op), intent(inout) :: this
159-
integer :: i,ierr
158+
integer :: i
160159
do i=1,MAX_REGEXP_OBJECTS
161-
this%pattern(i)%type = UNUSED
162-
this%pattern(i)%ccl = ''
160+
call this%pattern(i)%destroy()
163161
end do
164162
end subroutine finalize
165163

@@ -237,7 +235,7 @@ logical function matchcharclass(c,str) result(match)
237235
i = 0
238236

239237
! All characters in the charclass contents
240-
loop: do while (i<len_trim(str))
238+
loop: do while (i<len(str))
241239

242240
i = i+1
243241

@@ -266,7 +264,7 @@ logical function matchcharclass(c,str) result(match)
266264
! Character match
267265
if (c==DASH) then
268266
! If this is a range, the character must be in this range, that we evaluate with the ASCII collating sequence
269-
match = i<=0 .or. i+1>len_trim(str)
267+
match = i<=0 .or. i+1>len(str)
270268
else
271269
match = .true.
272270
end if
@@ -408,11 +406,12 @@ subroutine new_from_pattern(this,pattern)
408406

409407
! Local variables
410408
character(len=MAX_CHAR_CLASS_LEN,kind=RCK) :: ccl_buf ! size of buffer for chars in all char-classes in the expression. */
411-
integer :: loc,i,j,lenp
409+
integer :: loc,i,j,lenp,lenc
412410
character(kind=RCK) :: c
413411

414412
! Initialize class
415413
call this%destroy()
414+
ccl_buf = repeat(SPACE,MAX_CHAR_CLASS_LEN)
416415

417416
if (DEBUG) print "('[regex] parsing pattern: <',a,'>')", trim(pattern)
418417

@@ -487,6 +486,7 @@ subroutine new_from_pattern(this,pattern)
487486

488487
! Remove any escape characters
489488
loc = index(pattern(i+1:),']')
489+
lenc = loc-1
490490
if (loc>0) then
491491
ccl_buf = pattern(i+1:i+loc-1)
492492
i = i+loc
@@ -512,8 +512,10 @@ subroutine new_from_pattern(this,pattern)
512512
end if
513513
end if
514514

515-
! Terminate string
516-
this%pattern(j)%ccl = trim(ccl_buf)
515+
! Ensure there are no spaces
516+
517+
allocate(character(len=lenc,kind=RCK) :: this%pattern(j)%ccl)
518+
this%pattern(j)%ccl = ccl_buf(:lenc)
517519

518520
case default
519521

test/test_2.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,6 @@ logical function run_test2() result(success)
506506

507507
integer, parameter :: NTEST = 10
508508
integer :: bufsize,i,length,index,bufsizes(NTEST)
509-
character(kind=RCK) :: saved
510509

511510
print *
512511
print *, "Testing pathological pattern '.+nonexisting.+' to force worst-case asymptotic performance:"

test/tests.f90

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ program tests
1919
call add_test(run_test1(valid,pattern,trim(str),length))
2020
end do
2121

22-
! Test #2
23-
call add_test(run_test2())
24-
2522
! Test #3
2623
call add_test(test_invalid())
2724
call add_test(test_main())
25+
call add_test(test_bracket_space())
26+
27+
! Test #2
28+
call add_test(run_test2())
2829

2930
if (nfailed<=0) then
3031
print *, 'SUCCESS! all tests passed.'
@@ -35,8 +36,6 @@ program tests
3536
end if
3637

3738

38-
39-
4039
contains
4140

4241
subroutine add_test(successful_test)
@@ -73,10 +72,27 @@ logical function test_main() result(success)
7372
idx = REGEX(string=text,pattern='foo*',length=ln);
7473

7574
! Prints "football"
75+
success = idx>0; if (.not.success) return
7676
success = text(idx:idx+ln-1) == "foo"
7777

7878
end function test_main
7979

80+
logical function test_bracket_space() result(success)
81+
use regex_module
82+
implicit none
83+
84+
integer :: idx,ln
85+
character(*), parameter :: text = 'table football'
86+
87+
idx = REGEX(string=text,pattern='e[ ]f',length=ln);
88+
89+
! Prints "football"
90+
success = idx>0; if (.not.success) return
91+
success = text(idx:idx+ln-1) == "e f"
92+
93+
end function test_bracket_space
94+
95+
8096

8197

8298
end program tests

0 commit comments

Comments
 (0)