101 lines
4 KiB
Python
101 lines
4 KiB
Python
|
#!/usr/bin/python
|
||
|
'''Creates a folder containing text files of Cocoa keywords.'''
|
||
|
import os, commands, re
|
||
|
from sys import argv
|
||
|
|
||
|
def find(searchpath, ext):
|
||
|
'''Mimics the "find searchpath -name *.ext" unix command.'''
|
||
|
results = []
|
||
|
for path, dirs, files in os.walk(searchpath):
|
||
|
for filename in files:
|
||
|
if filename.endswith(ext):
|
||
|
results.append(os.path.join(path, filename))
|
||
|
return results
|
||
|
|
||
|
def find_headers(root_folder, frameworks):
|
||
|
'''Returns list of the header files for the given frameworks.'''
|
||
|
headers = []
|
||
|
folder = root_folder + '/System/Library/Frameworks/'
|
||
|
for framework in frameworks:
|
||
|
headers.extend(find(folder + framework + '.framework', '.h'))
|
||
|
return headers
|
||
|
|
||
|
def default_headers():
|
||
|
'''Headers for common Cocoa frameworks.'''
|
||
|
cocoa_frameworks = ('Foundation', 'CoreFoundation', 'AppKit',
|
||
|
'AddressBook', 'CoreData', 'PreferencePanes', 'QTKit',
|
||
|
'ScreenSaver', 'SyncServices', 'WebKit')
|
||
|
iphone_frameworks = ('UIKit', 'GameKit')
|
||
|
iphone_sdk_path = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk'
|
||
|
return find_headers('', cocoa_frameworks) + \
|
||
|
find_headers(iphone_sdk_path, iphone_frameworks)
|
||
|
|
||
|
def match_output(command, regex, group_num):
|
||
|
'''
|
||
|
Returns an ordered list of all matches of the supplied regex for the
|
||
|
output of the given command.
|
||
|
'''
|
||
|
results = []
|
||
|
for line in commands.getoutput(command).split("\n"):
|
||
|
match = re.search(regex, line)
|
||
|
if match and not match.group(group_num) in results:
|
||
|
results.append(match.group(group_num))
|
||
|
results.sort()
|
||
|
return results
|
||
|
|
||
|
def get_functions(header_files):
|
||
|
'''Returns list of Cocoa Functions.'''
|
||
|
lines = match_output(r"grep -h '^[A-Z][A-Z_]* [^;]* \**\(NS\|UI\)\w\+ *(' "
|
||
|
+ header_files, r'((NS|UI)\w+)\s*\(.*?\)', 1)
|
||
|
lines = [format_function_line(line) for line in lines]
|
||
|
lines += match_output(r"grep -h '^#define \(NS\|UI\)\w\+ *(' "
|
||
|
+ header_files, r'((NS|UI)\w+)\s*\(.*?\)', 1)
|
||
|
return lines
|
||
|
|
||
|
def format_function_line(line):
|
||
|
# line = line.replace('NSInteger', 'int')
|
||
|
# line = line.replace('NSUInteger', 'unsigned int')
|
||
|
# line = line.replace('CGFloat', 'float')
|
||
|
return re.sub(r'void(\s*[^*])', r'\1', line)
|
||
|
|
||
|
def get_types(header_files):
|
||
|
'''Returns a list of Cocoa Types.'''
|
||
|
return match_output(r"grep -h 'typedef .* _*\(NS\|UI\)[A-Za-z]*' "
|
||
|
+ header_files, r'((NS|UI)[A-Za-z]+)\)?\s*(;|{)', 1)
|
||
|
|
||
|
def get_constants(header_files):
|
||
|
'''Returns a list of Cocoa Constants.'''
|
||
|
return match_output(r"awk '/^(typedef )?(enum|NS_(ENUM|OPTIONS)\(.*\)) .*\{/ {pr = 1;} /\}/ {pr = 0;}"
|
||
|
r"{ if(pr) print $0; }' " + header_files,
|
||
|
r'^\s*((NS|UI)[A-Z][A-Za-z0-9_]*)', 1)
|
||
|
|
||
|
def get_notifications(header_files):
|
||
|
'''Returns a list of Cocoa Notifications.'''
|
||
|
return match_output(r"egrep -h '\*(\s*const\s+)?\s*(NS|UI).*Notification' "
|
||
|
+ header_files, r'(NS|UI)\w*Notification', 0)
|
||
|
|
||
|
def write_file(filename, lines):
|
||
|
'''Attempts to write list to file or exits with error if it can't.'''
|
||
|
try:
|
||
|
f = open(filename, 'w')
|
||
|
except IOError, error:
|
||
|
raise SystemExit(argv[0] + ': %s' % error)
|
||
|
f.write("\n".join(lines))
|
||
|
f.close()
|
||
|
|
||
|
def extract_files_to(dirname=None):
|
||
|
'''Extracts .txt files to given directory or ./cocoa_indexes by default.'''
|
||
|
if dirname is None:
|
||
|
dirname = './cocoa_indexes'
|
||
|
if not os.path.isdir(dirname):
|
||
|
os.mkdir(dirname)
|
||
|
headers = ' '.join(default_headers())
|
||
|
|
||
|
write_file(dirname + '/functions.txt', get_functions (headers))
|
||
|
write_file(dirname + '/types.txt', get_types (headers))
|
||
|
write_file(dirname + '/constants.txt', get_constants (headers))
|
||
|
write_file(dirname + '/notifications.txt', get_notifications(headers))
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
extract_files_to(argv[1] if len(argv) > 1 else None)
|