1212# #
1313# ############################################################################ #
1414
15+ #!/usr/bin/env python3
1516import argparse
1617import sys
17-
18+ import os
1819from c_formatter_42 .run import run_all
1920
21+ def process_file (filepath , confirm = False ):
22+ """Process a single file with formatting."""
23+ try :
24+ with open (filepath , "r" ) as file :
25+ content = file .read ()
26+
27+ if confirm :
28+ result = input (f"Are you sure you want to overwrite { filepath } ?[y/N] " )
29+ if result != "y" :
30+ return True
31+
32+ print (f"Formatting: { filepath } " )
33+ with open (filepath , "w" ) as file :
34+ file .write (run_all (content ))
35+ return True
36+ except OSError as e :
37+ print (f"Error: { e .filename } : { e .strerror } " , file = sys .stderr )
38+ return False
2039
21- def main ():
40+ def process_path (path , confirm = False , ignore_dirs = None ):
41+ """
42+ Process a path (file or directory) recursively.
43+ Formats .c and .h files in the directory.
44+ """
45+ ignore_dirs = ignore_dirs or []
46+
47+ if os .path .isfile (path ):
48+ if path .endswith (('.c' , '.h' )):
49+ return process_file (path , confirm )
50+ return True
51+
52+ if os .path .isdir (path ):
53+ success = True
54+ for root , dirs , files in os .walk (path ):
55+ dirs [:] = [d for d in dirs if not any (ignore_dir in os .path .join (root , d ) for ignore_dir in ignore_dirs )]
56+
57+ for file in files :
58+ if file .endswith (('.c' , '.h' )):
59+ filepath = os .path .join (root , file )
60+ success &= process_file (filepath , confirm )
61+ return success
62+
63+ print (f"Error: { path } is not a file or directory" , file = sys .stderr )
64+ return False
65+
66+ def main () -> int :
2267 arg_parser = argparse .ArgumentParser (
2368 prog = "c_formatter_42" ,
24- description = "Format C source according to the norm" ,
69+ description = "Format C source files according to the norm" ,
2570 formatter_class = argparse .RawTextHelpFormatter ,
2671 )
2772 arg_parser .add_argument (
@@ -31,33 +76,30 @@ def main():
3176 help = "Ask confirmation before overwriting any file" ,
3277 )
3378 arg_parser .add_argument (
34- "filepaths" ,
35- metavar = "FILE" ,
79+ "-i" ,
80+ "--ignore" ,
81+ nargs = '+' ,
82+ default = [],
83+ help = "Ignore specified folders (e.g. .git/ .vscode/)" ,
84+ )
85+ arg_parser .add_argument (
86+ "paths" ,
87+ metavar = "PATH" ,
3688 nargs = "*" ,
37- help = "File to format inplace, if no file is provided read STDIN" ,
89+ help = "Files or directories to format. If no path is provided, read STDIN" ,
3890 )
3991 args = arg_parser .parse_args ()
40-
41- if len (args .filepaths ) == 0 :
92+
93+ if len (args .paths ) == 0 :
4294 content = sys .stdin .read ()
4395 print (run_all (content ), end = "" )
44- else :
45- for filepath in args .filepaths :
46- try :
47- with open (filepath , "r" ) as file :
48- content = file .read ()
49- if args .confirm :
50- result = input (
51- f"Are you sure you want to overwrite { filepath } ?[y/N]"
52- )
53- if result != "y" :
54- continue
55- print (f"Writing to { filepath } " )
56- with open (filepath , "w" ) as file :
57- file .write (run_all (content ))
58- except OSError as e :
59- print (f"Error: { e .filename } : { e .strerror } " )
60-
96+ return 0
97+
98+ success = True
99+ for path in args .paths :
100+ success &= process_path (path , args .confirm , args .ignore )
101+
102+ return 0 if success else 1
61103
62104if __name__ == "__main__" :
63- main ()
105+ sys . exit ( main () )
0 commit comments