Слияние кода завершено, страница обновится автоматически
#!/usr/bin/env python
"""
Update autogenerated source files from yaml database.
Copyright (c) 2019, vit9696
"""
from __future__ import print_function
import update_products
import fnmatch
import json
import operator
import os
import unicodedata
import sys
import yaml
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
def load_db(dbpath):
"""
Load yaml database and return in a list.
"""
if not os.path.exists(dbpath):
print("Cannot find %s directory, rerun from AppleModels directory!" % dbpath)
sys.exit(1)
db = []
for root, dirs, files in os.walk(dbpath):
for file in fnmatch.filter(files, '*.yaml'):
path = os.path.join(root, file)
with open(path, 'r') as fh:
try:
r = yaml.safe_load(fh)
if r.get('SystemProductName', None) is None:
print("WARN: Missing SystemProductName in %s, skipping!" % path)
continue
db.append(r)
except yaml.YAMLError as e:
print("Failed to parse file %s - %s" % (path, e))
sys.exit(1)
if len(db) == 0:
print("Empty database!")
sys.exit(1)
# Sorting is required for fast lookup.
return sorted(db, key=operator.itemgetter('SystemProductName'))
def gather_products(db, ptype='AppleModelCode', empty_valid=False, shared_valid=False, fatal=True):
"""
Obtain all product codes from the database
"""
products = []
for info in db:
pp = info.get(ptype, None)
if pp is None:
continue
for p in pp:
if p == '':
if not empty_valid:
print("ERROR: {} in contains empty {}, skipping!".format(info['SystemProductName'], ptype))
if fatal: sys.exit(1)
continue
if p == '000' or p == '0000':
print("WARN: {} in contains zero {}, skipping!".format(info['SystemProductName'], ptype))
continue
if p in products:
if not shared_valid:
print("ERROR: {} shares {} {} with other model!".format(info['SystemProductName'], ptype, p))
if fatal: sys.exit(1)
continue
products.append(p)
return products
def validate_products(db, dbpd):
usedproducts = gather_products(db)
# FIXME: Empty is not valid, but we let it be for now.
gather_products(db, 'AppleBoardCode', True, True, False)
knownproducts = dbpd
for product in usedproducts:
if knownproducts.get(product, None) is None:
print("ERROR: Model %s is used in DataBase but not present in Products!" % product)
sys.exit(1)
if knownproducts[product][update_products.KEY_STATUS] != update_products.STATUS_OK:
print("ERROR: Model %s is used in DataBase but not valid in Products!" % product)
sys.exit(1)
to_add = {}
for product in knownproducts:
if knownproducts[product][update_products.KEY_STATUS] != update_products.STATUS_OK:
continue
name = knownproducts[product][update_products.KEY_NAME]
if name.find('Mac') < 0 and name.find('Xserve') < 0:
continue
if name.find('M1') >= 0:
continue
if len(product) > 3 and product not in usedproducts:
print("WARN: Model %s (%s) is known but is not used in DataBase!" % (product, name))
if to_add.get(name, None) is None:
to_add[name] = []
to_add[name].append(product)
continue
if len(to_add) > 0:
for sysname in to_add:
for info in db:
if sysname in info['Specifications']['SystemReportName']:
print("New AppleModelCode for {}:".format(info['SystemProductName']))
for model in to_add[sysname]:
print(" - \"{}\"".format(model))
def export_db_macinfolib(db, path, year=0):
"""
Export yaml database to MacInfoLib format.
TODO: use jinja2?
"""
with open(path, 'w') as fh:
print('// DO NOT EDIT! This is an autogenerated file.', file=fh)
print('#include "MacInfoInternal.h"', file=fh)
print('CONST MAC_INFO_INTERNAL_ENTRY gMacInfoModels[] = {', file=fh)
for info in db:
if max(info['AppleModelYear']) < year:
continue
sb_model = info.get('AppleModelId')
if sb_model:
sb_model = '"{}"'.format(sb_model.lower())
else:
sb_model = 'NULL'
print(' {\n'
' .SystemProductName = "%s",\n'
' .BoardProduct = "%s",\n'
' .BoardRevision = %s,\n'
' .SmcRevision = {%s},\n'
' .SmcBranch = {%s},\n'
' .SmcPlatform = {%s},\n'
' .BIOSVersion = "%s",\n'
' .BIOSReleaseDate = "%s",\n'
' .SystemVersion = "%s",\n'
' .SystemSKUNumber = "%s",\n'
' .SystemFamily = "%s",\n'
' .BoardVersion = "%s",\n'
' .BoardAssetTag = "%s",\n'
' .BoardLocationInChassis = "%s",\n'
' .SmcGeneration = 0x%X,\n'
' .BoardType = 0x%X,\n'
' .ChassisType = 0x%X,\n'
' .MemoryFormFactor = 0x%X,\n'
' .PlatformFeature = %s,\n'
' .ChassisAssetTag = "%s",\n'
' .FirmwareFeatures = 0x%XULL,\n'
' .FirmwareFeaturesMask = 0x%XULL,\n'
' .SecureBootModel = %s,\n'
' },' % (
info['SystemProductName'],
info['BoardProduct'][0] if isinstance(info['BoardProduct'], list) else info['BoardProduct'],
'0x{:X}'.format(info['BoardRevision']) if 'BoardRevision' in info else 'MAC_INFO_BOARD_REVISION_MISSING',
', '.join(map(str, info.get('SmcRevision', [0x00]))),
', '.join(map(str, info.get('SmcBranch', [0x00]))),
', '.join(map(str, info.get('SmcPlatform', [0x00]))),
info['BIOSVersion'],
info['BIOSReleaseDate'],
info['SystemVersion'],
info['SystemSKUNumber'],
info['SystemFamily'],
info['BoardVersion'],
info['BoardAssetTag'],
info['BoardLocationInChassis'],
info['SmcGeneration'],
info['BoardType'],
info['ChassisType'],
info['MemoryFormFactor'],
'0x{:X}'.format(info['PlatformFeature']) if 'PlatformFeature' in info else 'MAC_INFO_PLATFORM_FEATURE_MISSING',
info['ChassisAssetTag'],
info.get('ExtendedFirmwareFeatures', info.get('FirmwareFeatures', 0)),
info.get('ExtendedFirmwareFeaturesMask', info.get('FirmwareFeaturesMask', 0)),
sb_model
), file=fh)
print('};', file=fh)
print('CONST UINTN gMacInfoModelCount = ARRAY_SIZE (gMacInfoModels);', file=fh)
print('CONST UINTN gMacInfoDefaultModel = 0;', file=fh)
def export_db_macserial(db, dbpd, path, year=0):
"""
Export yaml database to macserial format.
TODO: use jinja2?
"""
with open(path, 'w') as fh:
print('#ifndef GENSERIAL_MODELINFO_AUTOGEN_H', file=fh)
print('#define GENSERIAL_MODELINFO_AUTOGEN_H\n', file=fh)
print('// DO NOT EDIT! This is an autogenerated file.\n', file=fh)
print('#include "macserial.h"\n', file=fh)
print('typedef enum {', file=fh)
for info in db:
print(' {}, // {}'.format(
info['SystemProductName'].replace(',', '_'),
info['Specifications']['CPU'][0]
), file=fh)
print('} AppleModel;\n', file=fh)
print('#define APPLE_MODEL_MAX {}\n'.format(len(db)), file=fh)
print('static PLATFORMDATA ApplePlatformData[] = {', file=fh)
for info in db:
print(' {{ "{}", "{}" }},'.format(
info['SystemProductName'],
info['SystemSerialNumber']
), file=fh)
print('};\n', file=fh)
print('#define APPLE_MODEL_CODE_MAX {}'.format(max(len(info['AppleModelCode']) for info in db)), file=fh)
print('static const char *AppleModelCode[][APPLE_MODEL_CODE_MAX] = {', file=fh)
for info in db:
print(' /* {:14} */ {{"{}"}},'.format(
info['SystemProductName'],
'", "'.join(info['AppleModelCode'])
), file=fh)
print('};\n', file=fh)
print('#define APPLE_BOARD_CODE_MAX {}'.format(max(len(info['AppleBoardCode']) for info in db)), file=fh)
print('static const char *AppleBoardCode[][APPLE_BOARD_CODE_MAX] = {', file=fh)
for info in db:
print(' /* {:14} */ {{"{}"}},'.format(
info['SystemProductName'],
'", "'.join(info['AppleBoardCode'])
), file=fh)
print('};\n', file=fh)
print('#define APPLE_MODEL_YEAR_MAX {}'.format(max(len(info['AppleModelYear']) for info in db)), file=fh)
print('static uint32_t AppleModelYear[][APPLE_MODEL_YEAR_MAX] = {', file=fh)
for info in db:
print(' /* {:14} */ {{{}}},'.format(
info['SystemProductName'],
', '.join(str(year) for year in info['AppleModelYear'])
), file=fh)
print('};\n', file=fh)
print('static uint32_t ApplePreferredModelYear[] = {', file=fh)
for info in db:
print(' /* {:14} */ {},'.format(
info['SystemProductName'],
info.get('MacserialModelYear', 0)
), file=fh)
print('};\n', file=fh)
print('static APPLE_MODEL_DESC AppleModelDesc[] = {', file=fh)
models = sorted(dbpd.keys())
models.sort(key=len)
for model in models:
if dbpd[model][update_products.KEY_STATUS] == update_products.STATUS_OK:
print(' {{"{}", "{}"}},'.format(
model,
remove_accents(dbpd[model][update_products.KEY_NAME])
), file=fh)
print('};\n', file=fh)
print('#endif // GENSERIAL_MODELINFO_AUTOGEN_H', file=fh)
def export_mlb_boards(db, boards):
l = {}
for info in db:
if len(info['SystemSerialNumber']) == 12:
models = [info['BoardProduct']] if not isinstance(info['BoardProduct'], list) else info['BoardProduct']
for model in models:
if info['MaximumOSVersion'] is None:
l[model] = 'latest'
else:
l[model] = info['MaximumOSVersion']
with open(boards, 'w') as fh:
json.dump(l, fh, indent=1)
if __name__ == '__main__':
db = load_db('DataBase')
dbpd = update_products.load_products()
# Run test phase to validate the library
validate_products(db, dbpd)
export_db_macinfolib(db, os.devnull)
export_db_macserial(db, dbpd, os.devnull)
# Export new models
export_db_macinfolib(db, '../Library/OcMacInfoLib/AutoGenerated.c')
export_db_macserial(db, dbpd, '../Utilities/macserial/modelinfo_autogen.h')
# Export MLB models
export_mlb_boards(db, '../Utilities/macrecovery/boards.json')
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )