| 195 | |
| 196 | |
| 197 | def _read_section(lines: list[str], start_index: int) -> ReadSectionResult: |
| 198 | context: list[str] = [] |
| 199 | del_lines: list[str] = [] |
| 200 | ins_lines: list[str] = [] |
| 201 | section_chunks: list[Chunk] = [] |
| 202 | mode: Literal["keep", "add", "delete"] = "keep" |
| 203 | index = start_index |
| 204 | orig_index = index |
| 205 | |
| 206 | while index < len(lines): |
| 207 | raw = lines[index] |
| 208 | if ( |
| 209 | raw.startswith("@@") |
| 210 | or raw.startswith(END_PATCH) |
| 211 | or raw.startswith("*** Update File:") |
| 212 | or raw.startswith("*** Delete File:") |
| 213 | or raw.startswith("*** Add File:") |
| 214 | or raw.startswith(END_FILE) |
| 215 | ): |
| 216 | break |
| 217 | if raw == "***": |
| 218 | break |
| 219 | if raw.startswith("***"): |
| 220 | raise ValueError(f"Invalid Line: {raw}") |
| 221 | |
| 222 | index += 1 |
| 223 | last_mode = mode |
| 224 | line = raw if raw else " " |
| 225 | prefix = line[0] |
| 226 | if prefix == "+": |
| 227 | mode = "add" |
| 228 | elif prefix == "-": |
| 229 | mode = "delete" |
| 230 | elif prefix == " ": |
| 231 | mode = "keep" |
| 232 | else: |
| 233 | raise ValueError(f"Invalid Line: {line}") |
| 234 | |
| 235 | line_content = line[1:] |
| 236 | switching_to_context = mode == "keep" and last_mode != mode |
| 237 | if switching_to_context and (del_lines or ins_lines): |
| 238 | section_chunks.append( |
| 239 | Chunk( |
| 240 | orig_index=len(context) - len(del_lines), |
| 241 | del_lines=list(del_lines), |
| 242 | ins_lines=list(ins_lines), |
| 243 | ) |
| 244 | ) |
| 245 | del_lines = [] |
| 246 | ins_lines = [] |
| 247 | |
| 248 | if mode == "delete": |
| 249 | del_lines.append(line_content) |
| 250 | context.append(line_content) |
| 251 | elif mode == "add": |
| 252 | ins_lines.append(line_content) |
| 253 | else: |
| 254 | context.append(line_content) |