fs_config: generate friendly in AID class

am: 8f42ce71ac

Change-Id: I958aa6152a2b42bb7a82fe1e909fc911a08b2f36
This commit is contained in:
William Roberts 2016-12-10 00:21:02 +00:00 committed by android-build-merger
commit 092fa031cd
1 changed files with 120 additions and 60 deletions

View File

@ -98,8 +98,20 @@ class AID(object):
value (str) The User Id (uid) of the associate define.
found (str) The file it was found in, can be None.
normalized_value (str): Same as value, but base 10.
friendly (str): The friendly name of aid.
"""
PREFIX = 'AID_'
# Some of the AIDS like AID_MEDIA_EX had names like mediaex
# list a map of things to fixup until we can correct these
# at a later date.
_FIXUPS = {
'media_drm': 'mediadrm',
'media_ex': 'mediaex',
'media_codec': 'mediacodec'
}
def __init__(self, identifier, value, found):
"""
Args:
@ -116,6 +128,39 @@ class AID(object):
self.found = found
self.normalized_value = str(int(value, 0))
# Where we calculate the friendly name
friendly = identifier[len(AID.PREFIX):].lower()
self.friendly = AID._fixup_friendly(friendly)
@staticmethod
def is_friendly(name):
"""Determines if an AID is a freindly name or C define.
For example if name is AID_SYSTEM it returns false, if name
was system, it would return true.
Returns:
True if name is a friendly name False otherwise.
"""
return not name.startswith(AID.PREFIX)
@staticmethod
def _fixup_friendly(friendly):
"""Fixup friendly names that historically don't follow the convention.
Args:
friendly (str): The friendly name.
Returns:
The fixedup friendly name as a str.
"""
if friendly in AID._FIXUPS:
return AID._FIXUPS[friendly]
return friendly
class FSConfig(object):
"""Represents a filesystem config array entry.
@ -160,22 +205,12 @@ class AIDHeaderParser(object):
"""
_SKIPWORDS = ['UNUSED']
_AID_KW = 'AID_'
_AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % _AID_KW)
_AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
_OEM_START_KW = 'START'
_OEM_END_KW = 'END'
_OEM_RANGE = re.compile('AID_OEM_RESERVED_[0-9]*_{0,1}(%s|%s)' %
(_OEM_START_KW, _OEM_END_KW))
# Some of the AIDS like AID_MEDIA_EX had names like mediaex
# list a map of things to fixup until we can correct these
# at a later date.
_FIXUPS = {
'media_drm': 'mediadrm',
'media_ex': 'mediaex',
'media_codec': 'mediacodec'
}
def __init__(self, aid_header):
"""
Args:
@ -240,19 +275,18 @@ class AIDHeaderParser(object):
ValueError: With message set to indicate the error.
"""
# friendly name
name = AIDHeaderParser._convert_friendly(identifier)
aid = AID(identifier, value, self._aid_header)
# duplicate name
if name in self._aid_name_to_value:
if aid.friendly in self._aid_name_to_value:
raise ValueError('Duplicate aid "%s"' % identifier)
if value in self._aid_value_to_name:
raise ValueError('Duplicate aid value "%u" for %s' % value,
identifier)
self._aid_name_to_value[name] = AID(identifier, value, self._aid_header)
self._aid_value_to_name[value] = name
self._aid_name_to_value[aid.friendly] = aid
self._aid_value_to_name[value] = aid.friendly
def _handle_oem_range(self, identifier, value):
"""Handle an OEM range C #define.
@ -363,7 +397,7 @@ class AIDHeaderParser(object):
Returns:
A list of AID() objects.
"""
return self._aid_name_to_value
return self._aid_name_to_value.values()
@staticmethod
def _convert_lst_to_tup(name, lst):
@ -385,25 +419,6 @@ class AIDHeaderParser(object):
return tuple(lst)
@staticmethod
def _convert_friendly(identifier):
"""
Translate AID_FOO_BAR to foo_bar (ie name)
Args:
identifier (str): The name of the #define.
Returns:
The friendly name as a str.
"""
name = identifier[len(AIDHeaderParser._AID_KW):].lower()
if name in AIDHeaderParser._FIXUPS:
return AIDHeaderParser._FIXUPS[name]
return name
@staticmethod
def _is_oem_range(aid):
"""Detects if a given aid is within the reserved OEM range.
@ -449,8 +464,7 @@ class FSConfigFileParser(object):
# Since _AID_PREFIX is within the set of _AID_MATCH the error logic only
# checks end, if you change this, you may have to update the error
# detection code.
_AID_PREFIX = 'AID_'
_AID_MATCH = re.compile('%s[A-Z0-9_]+' % _AID_PREFIX)
_AID_MATCH = re.compile('%s[A-Z0-9_]+' % AID.PREFIX)
_AID_ERR_MSG = 'Expecting upper case, a number or underscore'
# list of handler to required options, used to identify the
@ -560,7 +574,7 @@ class FSConfigFileParser(object):
self._seen_aids[0])
match = FSConfigFileParser._AID_MATCH.match(section_name)
invalid = match.end() if match else len(FSConfigFileParser._AID_PREFIX)
invalid = match.end() if match else len(AID.PREFIX)
if invalid != len(section_name):
tmp_errmsg = ('Invalid characters in AID section at "%d" for: "%s"'
% (invalid, FSConfigFileParser._AID_ERR_MSG))
@ -861,6 +875,13 @@ class FSConfigGen(BaseGenerator):
_FILE_COMMENT = '// Defined in file: \"%s\"'
def __init__(self, *args, **kwargs):
BaseGenerator.__init__(args, kwargs)
self._oem_parser = None
self._base_parser = None
self._friendly_to_aid = None
def add_opts(self, opt_group):
opt_group.add_argument(
@ -874,19 +895,46 @@ class FSConfigGen(BaseGenerator):
def __call__(self, args):
hdr = AIDHeaderParser(args['aid_header'])
oem_ranges = hdr.oem_ranges
self._base_parser = AIDHeaderParser(args['aid_header'])
self._oem_parser = FSConfigFileParser(args['fsconfig'],
self._base_parser.oem_ranges)
base_aids = self._base_parser.aids
oem_aids = self._oem_parser.aids
parser = FSConfigFileParser(args['fsconfig'], oem_ranges)
FSConfigGen._generate(parser.files, parser.dirs, parser.aids)
# Detect name collisions on AIDs. Since friendly works as the
# identifier for collision testing and we need friendly later on for
# name resolution, just calculate and use friendly.
# {aid.friendly: aid for aid in base_aids}
base_friendly = {aid.friendly: aid for aid in base_aids}
oem_friendly = {aid.friendly: aid for aid in oem_aids}
@staticmethod
def _to_fs_entry(fs_config):
"""
Given an FSConfig entry, converts it to a proper
array entry for the array entry.
base_set = set(base_friendly.keys())
oem_set = set(oem_friendly.keys())
{ mode, user, group, caps, "path" },
common = base_set & oem_set
if len(common) > 0:
emsg = 'Following AID Collisions detected for: \n'
for friendly in common:
base = base_friendly[friendly]
oem = oem_friendly[friendly]
emsg += (
'Identifier: "%s" Friendly Name: "%s" '
'found in file "%s" and "%s"' %
(base.identifier, base.friendly, base.found, oem.found))
sys.exit(emsg)
self._friendly_to_aid = oem_friendly
self._friendly_to_aid.update(base_friendly)
self._generate()
def _to_fs_entry(self, fs_config):
"""Converts an FSConfig entry to an fs entry.
Prints '{ mode, user, group, caps, "path" },'.
Calls sys.exit() on error.
Args:
fs_config (FSConfig): The entry to convert to
@ -901,6 +949,19 @@ class FSConfigGen(BaseGenerator):
caps = fs_config.caps
path = fs_config.path
emsg = 'Cannot convert friendly name "%s" to identifier!'
# remap friendly names to identifier names
if AID.is_friendly(user):
if user not in self._friendly_to_aid:
sys.exit(emsg % user)
user = self._friendly_to_aid[user].identifier
if AID.is_friendly(group):
if group not in self._friendly_to_aid:
sys.exit(emsg % group)
group = self._friendly_to_aid[group].identifier
fmt = '{ %s, %s, %s, %s, "%s" },'
expanded = fmt % (mode, user, group, caps, path)
@ -910,15 +971,11 @@ class FSConfigGen(BaseGenerator):
@staticmethod
def _gen_inc():
"""
Generate the include header lines and print to stdout.
Internal use only.
"""
"""Generate the include header lines and print to stdout."""
for include in FSConfigGen._INCLUDES:
print '#include %s' % include
@staticmethod
def _generate(files, dirs, aids):
def _generate(self):
"""Generates an OEM android_filesystem_config.h header file to stdout.
Args:
@ -933,6 +990,10 @@ class FSConfigGen(BaseGenerator):
FSConfigGen._gen_inc()
print
dirs = self._oem_parser.dirs
files = self._oem_parser.files
aids = self._oem_parser.aids
are_dirs = len(dirs) > 0
are_files = len(files) > 0
are_aids = len(aids) > 0
@ -952,13 +1013,12 @@ class FSConfigGen(BaseGenerator):
print FSConfigGen._DEFINE_NO_FILES + '\n'
if not are_files and not are_dirs and not are_aids:
print FSConfigGen._DEFAULT_WARNING
return
if are_files:
print FSConfigGen._OPEN_FILE_STRUCT
for fs_config in files:
FSConfigGen._to_fs_entry(fs_config)
self._to_fs_entry(fs_config)
if not are_dirs:
print FSConfigGen._IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
@ -971,7 +1031,7 @@ class FSConfigGen(BaseGenerator):
if are_dirs:
print FSConfigGen._OPEN_DIR_STRUCT
for dir_entry in dirs:
FSConfigGen._to_fs_entry(dir_entry)
self._to_fs_entry(dir_entry)
print FSConfigGen._CLOSE_FILE_STRUCT
@ -1019,8 +1079,8 @@ class AIDArrayGen(BaseGenerator):
print
print AIDArrayGen._OPEN_ID_ARRAY
for name, aid in hdr.aids.iteritems():
print AIDArrayGen._ID_ENTRY % (name, aid.identifier)
for aid in hdr.aids:
print AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier)
print AIDArrayGen._CLOSE_FILE_STRUCT
print