fortrangoingonforty/ferp / d312f5c

Browse files

Fix error exit codes and directory handling

- Add has_error flag to track errors during file processing
- Return exit code 2 when errors occur (matching grep behavior)
- Print error message for directories when -d read is used
- Add has_error to OpenMP reduction clause for thread safety
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
d312f5c3176ffd10d5eb22af6d35e19560c7b80e
Parents
71ca2f8
Tree
c2aeaa4

1 changed file

StatusFile+-
M src/main.f90 18 3
src/main.f90modified
@@ -35,6 +35,7 @@ program ferp
35
   integer :: num_exclude_patterns, num_include_patterns
35
   integer :: num_exclude_patterns, num_include_patterns
36
   logical :: any_match, file_match
36
   logical :: any_match, file_match
37
   logical :: found_early  ! For quiet mode early termination in parallel
37
   logical :: found_early  ! For quiet mode early termination in parallel
38
+  logical :: has_error  ! Track if any errors occurred (for exit code 2)
38
 
39
 
39
   ! Parse command-line arguments
40
   ! Parse command-line arguments
40
   call parse_arguments(opts, patterns, files, ierr)
41
   call parse_arguments(opts, patterns, files, ierr)
@@ -114,6 +115,7 @@ program ferp
114
 
115
 
115
   any_match = .false.
116
   any_match = .false.
116
   found_early = .false.
117
   found_early = .false.
118
+  has_error = .false.
117
 
119
 
118
   ! Process input sources
120
   ! Process input sources
119
   if (size(files) == 0) then
121
   if (size(files) == 0) then
@@ -128,7 +130,7 @@ program ferp
128
     ! Process each file with OpenMP parallelization (release builds)
130
     ! Process each file with OpenMP parallelization (release builds)
129
     ! Thread-safe: all buffers are now dynamically allocated per-thread
131
     ! Thread-safe: all buffers are now dynamically allocated per-thread
130
     !$omp parallel do default(shared) private(src, file_match) &
132
     !$omp parallel do default(shared) private(src, file_match) &
131
-    !$omp& reduction(.or.:any_match) schedule(dynamic)
133
+    !$omp& reduction(.or.:any_match,has_error) schedule(dynamic)
132
     do i = 1, size(files)
134
     do i = 1, size(files)
133
       ! Early termination check for quiet mode
135
       ! Early termination check for quiet mode
134
       if (opts%quiet .and. found_early) cycle
136
       if (opts%quiet .and. found_early) cycle
@@ -143,7 +145,14 @@ program ferp
143
             ! This path is rare - usually -r is specified explicitly
145
             ! This path is rare - usually -r is specified explicitly
144
             cycle
146
             cycle
145
           case default  ! DIR_READ
147
           case default  ! DIR_READ
146
-            ! Will try to read directory as file (usually fails)
148
+            ! Print error message and skip (like grep)
149
+            if (.not. opts%no_messages) then
150
+              !$omp critical(error_output)
151
+              write(error_unit, '(A)') 'ferp: ' // trim(files(i)) // ': Is a directory'
152
+              !$omp end critical(error_output)
153
+            end if
154
+            has_error = .true.
155
+            cycle
147
         end select
156
         end select
148
       end if
157
       end if
149
 
158
 
@@ -178,6 +187,9 @@ program ferp
178
           if (opts%quiet) found_early = .true.
187
           if (opts%quiet) found_early = .true.
179
         end if
188
         end if
180
         call src%close()
189
         call src%close()
190
+      else
191
+        ! File open failed - set error flag
192
+        has_error = .true.
181
       end if
193
       end if
182
     end do
194
     end do
183
     !$omp end parallel do
195
     !$omp end parallel do
@@ -188,7 +200,10 @@ program ferp
188
 
200
 
189
   ! Exit with appropriate code
201
   ! Exit with appropriate code
190
   ! 0 = match found, 1 = no match, 2 = error
202
   ! 0 = match found, 1 = no match, 2 = error
191
-  if (any_match) then
203
+  ! Note: grep returns 2 if there's any error, even with matches
204
+  if (has_error) then
205
+    call c_exit(2_c_int)
206
+  else if (any_match) then
192
     call c_exit(0_c_int)
207
     call c_exit(0_c_int)
193
   else
208
   else
194
     call c_exit(1_c_int)
209
     call c_exit(1_c_int)