fs_config: generate friendly in AID class
Generate the friendly name in one location. This prepares the tool for generatting passwd and group files. Also support mapping friendly names to identifiers. Test: That output files stay the same as before. Change-Id: I12198611126613eae81ca61614ed269c2439b72b Signed-off-by: William Roberts <william.c.roberts@intel.com>
This commit is contained in:
parent
5f059a7691
commit
8f42ce71ac
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue