Fortran · 4437 bytes Raw Blame History
1 module resolution_engine
2 use conflict_parser
3 implicit none
4 private
5
6 public :: write_resolved_file, all_conflicts_resolved
7
8 contains
9
10 ! Check if all conflicts have been resolved
11 function all_conflicts_resolved(conflicts, n) result(resolved)
12 type(conflict_t), intent(in) :: conflicts(:)
13 integer, intent(in) :: n
14 logical :: resolved
15 integer :: i
16
17 resolved = .true.
18 do i = 1, n
19 if (conflicts(i)%choice == 0) then
20 resolved = .false.
21 return
22 end if
23 end do
24 end function all_conflicts_resolved
25
26 ! Write the resolved file back to disk
27 subroutine write_resolved_file(filename, conflicts, n_conflicts, success)
28 character(len=*), intent(in) :: filename
29 type(conflict_t), intent(in) :: conflicts(:)
30 integer, intent(in) :: n_conflicts
31 logical, intent(out) :: success
32
33 integer :: in_unit, out_unit, ios, line_num, i, j
34 character(len=1024) :: line
35 integer :: current_conflict
36 logical :: in_conflict_region
37 character(len=256) :: temp_filename
38
39 success = .false.
40 current_conflict = 0
41 in_conflict_region = .false.
42
43 ! Create temporary file
44 temp_filename = trim(filename) // '.fit_tmp'
45
46 ! Open input and output files
47 open(newunit=in_unit, file=filename, status='old', action='read', iostat=ios)
48 if (ios /= 0) return
49
50 open(newunit=out_unit, file=temp_filename, status='replace', action='write', iostat=ios)
51 if (ios /= 0) then
52 close(in_unit)
53 return
54 end if
55
56 ! Process file line by line
57 line_num = 0
58 do
59 read(in_unit, '(A)', iostat=ios) line
60 if (ios /= 0) exit
61
62 line_num = line_num + 1
63
64 ! Check if we're at the start of a conflict
65 if (index(trim(line), '<<<<<<<') == 1) then
66 in_conflict_region = .true.
67 current_conflict = current_conflict + 1
68
69 ! Write the resolved content based on choice
70 if (current_conflict <= n_conflicts) then
71 call write_resolution(out_unit, conflicts(current_conflict))
72 end if
73 cycle
74 end if
75
76 ! Skip lines inside conflict region
77 if (in_conflict_region) then
78 if (index(trim(line), '>>>>>>>') == 1) then
79 in_conflict_region = .false.
80 end if
81 cycle
82 end if
83
84 ! Write non-conflict lines
85 write(out_unit, '(A)') trim(line)
86 end do
87
88 close(in_unit)
89 close(out_unit)
90
91 ! Replace original file with resolved version
92 call execute_command_line('mv "' // trim(temp_filename) // '" "' // trim(filename) // '"', exitstat=ios)
93 success = (ios == 0)
94
95 end subroutine write_resolved_file
96
97 ! Write the resolution for a single conflict
98 subroutine write_resolution(unit, conflict)
99 integer, intent(in) :: unit
100 type(conflict_t), intent(in) :: conflict
101 integer :: i
102
103 select case (conflict%choice)
104 case (1) ! Incoming
105 if (allocated(conflict%incoming_lines)) then
106 do i = 1, size(conflict%incoming_lines)
107 write(unit, '(A)') trim(conflict%incoming_lines(i))
108 end do
109 end if
110
111 case (2) ! Local
112 if (allocated(conflict%local_lines)) then
113 do i = 1, size(conflict%local_lines)
114 write(unit, '(A)') trim(conflict%local_lines(i))
115 end do
116 end if
117
118 case (3) ! Both
119 if (allocated(conflict%incoming_lines)) then
120 do i = 1, size(conflict%incoming_lines)
121 write(unit, '(A)') trim(conflict%incoming_lines(i))
122 end do
123 end if
124 if (allocated(conflict%local_lines)) then
125 do i = 1, size(conflict%local_lines)
126 write(unit, '(A)') trim(conflict%local_lines(i))
127 end do
128 end if
129
130 case default
131 ! Should not happen if all_conflicts_resolved was called first
132 write(unit, '(A)') '!!! UNRESOLVED CONFLICT !!!'
133 end select
134
135 end subroutine write_resolution
136
137 end module resolution_engine
138