fortitude

Finished
11def grep(pattern: str, flags: str, files: list[str]) -> str:
2 pass
2 """
3 Search for lines matching a pattern in files and return matching lines.
4
5 Args:
6 pattern: The string to search for
7 flags: String containing command flags (-n, -l, -i, -v, -x)
8 files: List of file paths to search in
9
10 Returns:
11 String containing all matching lines, formatted according to flags
12 """
13 # Parse flags
14 line_numbers = '-n' in flags
15 files_only = '-l' in flags
16 case_insensitive = '-i' in flags
17 invert_match = '-v' in flags
18 exact_match = '-x' in flags
19
20 results = []
21 matched_files = set()
22
23 # Edge Case: Empty files list - return empty string
24 if not files:
25 return ""
26
27 # Edge Case: Empty pattern - match empty lines
28 search_pattern = pattern.lower() if case_insensitive else pattern
29
30 multiple_files = len(files) > 1
31
32 for file_path in files:
33 try:
34 # Edge Case: File not found - skip file
35 with open(file_path, 'r', encoding='utf-8') as file:
36 lines = file.readlines()
37 except FileNotFoundError:
38 # Skip files that don't exist
39 continue
40
41 file_has_match = False
42
43 # Edge Case: Empty file - no lines to process
44 if not lines:
45 continue
46
47 for line_num, line in enumerate(lines, 1):
48 # Remove trailing newline for processing
49 line_content = line.rstrip('\n')
50
51 # Edge Case: Case insensitive matching
52 compare_line = line_content.lower() if case_insensitive else line_content
53
54 # Edge Case: Exact match flag
55 if exact_match:
56 is_match = (compare_line == search_pattern)
57 else:
58 is_match = (search_pattern in compare_line)
59
60 # Edge Case: Invert match flag
61 if invert_match:
62 is_match = not is_match
63
64 if is_match:
65 file_has_match = True
66
67 # Edge Case: Files only flag - just record the file
68 if files_only:
69 matched_files.add(file_path)
70 break # No need to check more lines in this file
71
72 output_line = line_content
73
74 # Edge Case: Multiple files - prepend filename
75 if multiple_files:
76 output_line = f"{file_path}:{output_line}"
77
78 # Edge Case: Line numbers flag - prepend line number
79 if line_numbers:
80 # Handle case where we already have filename prepended
81 if multiple_files:
82 parts = output_line.split(':', 1)
83 output_line = f"{parts[0]}:{line_num}:{parts[1]}"
84 else:
85 output_line = f"{line_num}:{output_line}"
86
87 results.append(output_line)
88
89 # Edge Case: Files only flag and this file had matches
90 if files_only and file_has_match:
91 matched_files.add(file_path)
92
93 # Edge Case: Files only flag - return just the filenames
94 if files_only:
95 return '\n'.join(sorted(matched_files)) + ('\n' if matched_files else '')
96
97 # Edge Case: No matches found - return empty string
98 return '\n'.join(results) + ('\n' if results else '')
99
100# Handled Edge Cases: Empty files list, File not found, Empty file, Empty pattern, Case insensitive matching, Exact match flag, Invert match flag, Files only flag, Multiple files, Line numbers flag, No matches found
Test NameStatus
test_multiple_files_no_matches_various_flags
Pass
test_multiple_files_one_match_match_entire_lines_flag
Pass
test_multiple_files_one_match_multiple_flags
Pass
test_multiple_files_one_match_no_flags
Pass
test_multiple_files_one_match_print_file_names_flag
Pass
test_multiple_files_several_matches_case_insensitive_flag
Pass
test_multiple_files_several_matches_file_flag_takes_precedence_over_line_number_flag
Pass
test_multiple_files_several_matches_inverted_and_match_entire_lines_flags
Pass
test_multiple_files_several_matches_inverted_flag
Pass
test_multiple_files_several_matches_no_flags
Pass
test_multiple_files_several_matches_print_line_numbers_flag
Pass
test_one_file_no_matches_various_flags
Pass
test_one_file_one_match_case_insensitive_flag
Pass
test_one_file_one_match_file_flag_takes_precedence_over_line_flag
Pass
test_one_file_one_match_match_entire_lines_flag
Pass
test_one_file_one_match_multiple_flags
Pass
test_one_file_one_match_no_flags
Pass
test_one_file_one_match_print_file_names_flag
Pass
test_one_file_one_match_print_line_numbers_flag
Pass
test_one_file_several_matches_case_insensitive_flag
Pass
test_one_file_several_matches_inverted_and_match_entire_lines_flags
Pass
test_one_file_several_matches_inverted_flag
Pass
test_one_file_several_matches_match_entire_lines_flag
Pass
test_one_file_several_matches_no_flags
Pass
test_one_file_several_matches_print_line_numbers_flag
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.