1+ #!/usr/bin/env python3
2+ """
3+ Script to automatically fix minizip-ng headers by adding missing includes.
4+ This script adds the mz_strm.h include to mz_zip_rw.h to fix callback type definitions.
5+ """
6+
7+ import os
8+ import re
9+ import sys
10+
11+ def fix_mz_zip_rw_header (file_path ):
12+ """Add missing mz_strm.h include to mz_zip_rw.h"""
13+
14+ if not os .path .exists (file_path ):
15+ print (f"Error: File { file_path } not found" )
16+ return False
17+
18+ with open (file_path , 'r' , encoding = 'utf-8' ) as f :
19+ content = f .read ()
20+
21+ # Check if mz_strm.h is already included
22+ if '#include "mz_strm.h"' in content or '#include <mz_strm.h>' in content :
23+ print (f"mz_strm.h already included in { file_path } " )
24+ return True
25+
26+ # Find the right place to insert the include (after the copyright header)
27+ lines = content .split ('\n ' )
28+
29+ # Look for the first #ifndef or #include after the copyright block
30+ insert_index = None
31+ for i , line in enumerate (lines ):
32+ if line .strip ().startswith ('#ifndef' ) or line .strip ().startswith ('#include' ):
33+ insert_index = i
34+ break
35+
36+ if insert_index is None :
37+ print (f"Could not find insertion point in { file_path } " )
38+ return False
39+
40+ # Insert the include
41+ lines .insert (insert_index , '#include "mz_strm.h"' )
42+
43+ # Write back the file
44+ with open (file_path , 'w' , encoding = 'utf-8' ) as f :
45+ f .write ('\n ' .join (lines ))
46+
47+ print (f"Successfully added mz_strm.h include to { file_path } " )
48+ return True
49+
50+ def fix_mz_zip_header (file_path ):
51+ """Add missing mz_strm.h include to mz_zip.h if needed"""
52+
53+ if not os .path .exists (file_path ):
54+ print (f"Error: File { file_path } not found" )
55+ return False
56+
57+ with open (file_path , 'r' , encoding = 'utf-8' ) as f :
58+ content = f .read ()
59+
60+ # Check if mz_strm.h is already included
61+ if '#include "mz_strm.h"' in content or '#include <mz_strm.h>' in content :
62+ print (f"mz_strm.h already included in { file_path } " )
63+ return True
64+
65+ # Check if this file uses callback types
66+ if 'mz_stream_read_cb' in content or 'mz_stream_write_cb' in content :
67+ lines = content .split ('\n ' )
68+
69+ # Look for the first #ifndef or #include after the copyright block
70+ insert_index = None
71+ for i , line in enumerate (lines ):
72+ if line .strip ().startswith ('#ifndef' ) or line .strip ().startswith ('#include' ):
73+ insert_index = i
74+ break
75+
76+ if insert_index is not None :
77+ # Insert the include
78+ lines .insert (insert_index , '#include "mz_strm.h"' )
79+
80+ # Write back the file
81+ with open (file_path , 'w' , encoding = 'utf-8' ) as f :
82+ f .write ('\n ' .join (lines ))
83+
84+ print (f"Successfully added mz_strm.h include to { file_path } " )
85+ return True
86+
87+ print (f"No callback types found in { file_path } , skipping" )
88+ return True
89+
90+ def fix_mz_strm_os_posix (file_path ):
91+ """Wrap O_NOFOLLOW usage with #ifdef O_NOFOLLOW ... #endif in mz_strm_os_posix.c"""
92+ if not os .path .exists (file_path ):
93+ print (f"Error: File { file_path } not found" )
94+ return False
95+
96+ with open (file_path , 'r' , encoding = 'utf-8' ) as f :
97+ content = f .read ()
98+
99+ # Patch the line: mode_open |= O_NOFOLLOW;
100+ # Only patch if not already inside an #ifdef
101+ if 'mode_open |= O_NOFOLLOW;' in content and '#ifdef O_NOFOLLOW' not in content :
102+ new_content = re .sub (
103+ r'(\s+if \(mode & MZ_OPEN_MODE_NOFOLLOW\)\s*)mode_open \|= O_NOFOLLOW;' ,
104+ r'\1#ifdef O_NOFOLLOW\n mode_open |= O_NOFOLLOW;\n#endif' ,
105+ content
106+ )
107+ if new_content == content :
108+ # fallback: patch any occurrence
109+ new_content = content .replace (
110+ 'mode_open |= O_NOFOLLOW;' ,
111+ '#ifdef O_NOFOLLOW\n mode_open |= O_NOFOLLOW;\n #endif'
112+ )
113+ with open (file_path , 'w' , encoding = 'utf-8' ) as f :
114+ f .write (new_content )
115+ print (f"Patched O_NOFOLLOW usage in { file_path } " )
116+ return True
117+ else :
118+ print (f"No O_NOFOLLOW patch needed in { file_path } " )
119+ return True
120+
121+ def main ():
122+ """Main function to fix all minizip headers and patch O_NOFOLLOW usage"""
123+
124+ # Get the minizip-ng directory path (relative to this script)
125+ minizip_dir = "minizip-ng"
126+
127+ if not os .path .exists (minizip_dir ):
128+ print (f"Error: minizip-ng directory not found at { minizip_dir } " )
129+ print ("Please run this script from the Externals/minizip-ng directory" )
130+ return 1
131+
132+ print ("Fixing minizip-ng headers..." )
133+
134+ # Fix mz_zip_rw.h
135+ mz_zip_rw_path = os .path .join (minizip_dir , "mz_zip_rw.h" )
136+ if not fix_mz_zip_rw_header (mz_zip_rw_path ):
137+ return 1
138+
139+ # Fix mz_zip.h if needed
140+ mz_zip_path = os .path .join (minizip_dir , "mz_zip.h" )
141+ if not fix_mz_zip_header (mz_zip_path ):
142+ return 1
143+
144+ # Patch mz_strm_os_posix.c for O_NOFOLLOW
145+ mz_strm_os_posix_path = os .path .join (minizip_dir , "mz_strm_os_posix.c" )
146+ if not fix_mz_strm_os_posix (mz_strm_os_posix_path ):
147+ return 1
148+
149+ print ("Header fixes completed successfully!" )
150+ return 0
151+
152+ if __name__ == "__main__" :
153+ sys .exit (main ())
0 commit comments