174 lines
5.5 KiB
Python
Executable file
174 lines
5.5 KiB
Python
Executable file
#!/usr/bin/python
|
|
|
|
# Copyright 2015 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""A Main file for command and structure generators.
|
|
|
|
Takes in structures.txt and commands.txt as outputted by extract_*.sh, then
|
|
passes files as input to structure_generator and command_generator objects.
|
|
"""
|
|
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
import command_generator
|
|
import extract_structures
|
|
import structure_generator
|
|
|
|
TMP_DIR = '/tmp'
|
|
TYPES_FILE = 'tpm_types.h'
|
|
|
|
|
|
class GeneratorException(Exception):
|
|
"""Generator error, a convenience class."""
|
|
pass
|
|
|
|
usage = ('''
|
|
usage: %s [-h|[tar_archive|part2.html part3.html]]
|
|
|
|
-h show this message and exit
|
|
|
|
tar_archive - a tarred archive consisting of at least two HTML files,
|
|
parts 2 and 3 of the TCG TPM2 library specification. File
|
|
names must include 'part2' and 'part3'. The extracted files
|
|
could be found in %s after this script finished processing.
|
|
|
|
part{23}.html - parts 2 and 3 of the TCG TPM2 library specification in
|
|
html format.
|
|
''' % (os.path.basename(__file__), TMP_DIR))
|
|
|
|
|
|
def _TryUntarring(tar_file_name):
|
|
"""Try retrieving parts 2 and 3 from the passed in archive.
|
|
|
|
Args:
|
|
tar_file_name: a string, file name of the tar file which is supposed to
|
|
contain parts 2 and 3 of the specification.
|
|
|
|
Returns:
|
|
A tuple of strings, two file names in case they were found in the archive
|
|
and successfully extracted.
|
|
"""
|
|
part2 = None
|
|
part3 = None
|
|
tar_extract_base = ['tar', '-C', TMP_DIR, '-f']
|
|
|
|
components = subprocess.check_output(['tar', 'tf', tar_file_name],
|
|
stderr=subprocess.STDOUT)
|
|
for name in components.splitlines():
|
|
if re.search('part2', name, re.IGNORECASE):
|
|
subprocess.check_output(tar_extract_base + [tar_file_name, '-x', name],
|
|
stderr=subprocess.STDOUT)
|
|
part2 = os.path.join(TMP_DIR, name)
|
|
if re.search('part3', name, re.IGNORECASE):
|
|
subprocess.check_output(tar_extract_base + [tar_file_name, '-x', name],
|
|
stderr=subprocess.STDOUT)
|
|
part3 = os.path.join(TMP_DIR, name)
|
|
return part2, part3
|
|
|
|
|
|
def _ParseCommandLine(args):
|
|
|
|
"""Process command line and determine input file names.
|
|
|
|
Input files could be supplied by two different ways - as part of a tar
|
|
archive (in which case only one command line parameter is expected), or as
|
|
two separate file names, one for part 2 and one for part 3.
|
|
|
|
If a single command line parameter is supplied, and it is not '-h', tar
|
|
extraction is attempted and if successful, two separate files are created in
|
|
TMP_DIR.
|
|
|
|
Args:
|
|
args: a list of string, command line parameters retrieved from sys.argv
|
|
|
|
Returns:
|
|
A tuple of two strings, two html files to process, part 2 and part 3 of
|
|
the spec.
|
|
|
|
Raises:
|
|
GeneratorException: on input errors.
|
|
"""
|
|
if len(args) == 1:
|
|
if args[0] == '-h':
|
|
print(usage)
|
|
sys.exit(0)
|
|
try:
|
|
structures_file, commands_file = _TryUntarring(args[0])
|
|
except subprocess.CalledProcessError as e:
|
|
raise GeneratorException("command '%s' failed:\n%s\n%s" %
|
|
(' '.join(e.cmd), e.output, usage))
|
|
|
|
elif len(args) == 2:
|
|
structures_file = args[0]
|
|
commands_file = args[1]
|
|
else:
|
|
raise GeneratorException(usage)
|
|
return structures_file, commands_file
|
|
|
|
|
|
def main(argv):
|
|
"""A Main function.
|
|
|
|
TPM structures and commands files are parsed and C header and C implementation
|
|
files are generated.
|
|
|
|
Args:
|
|
argv: a list of strings, command line parameters.
|
|
"""
|
|
|
|
structures_file, commands_file = _ParseCommandLine(argv[1:])
|
|
print('parse part2...')
|
|
html_parser = extract_structures.SpecParser()
|
|
tpm_table = html_parser.GetTable()
|
|
# The tables included in the below tuple are defined twice in the
|
|
# specification, once in part 2 and once in part 4. Let's ignore the part 2
|
|
# definitions to avoid collisions.
|
|
tpm_table.SetSkipTables((2, 6, 9, 10, 13))
|
|
html_parser.feed(open(structures_file).read())
|
|
html_parser.close()
|
|
tpm_defines = tpm_table.GetHFile()
|
|
|
|
print('parse part3...')
|
|
tpm_table.SetSkipTables(())
|
|
html_parser.feed(open(commands_file).read())
|
|
html_parser.close()
|
|
|
|
# Move to the root directory, which is one level above the script.
|
|
os.chdir(os.path.join(os.path.dirname(argv[0]), '..'))
|
|
|
|
# Save types include file.
|
|
print('generate output...')
|
|
types_file = open(TYPES_FILE, 'w')
|
|
guard_name = TYPES_FILE.upper()
|
|
guard_name = guard_name.replace('.', '_')
|
|
guard_name = 'TPM2_' + guard_name + '_'
|
|
types_file.write((structure_generator.COPYRIGHT_HEADER +
|
|
structure_generator.HEADER_FILE_GUARD_HEADER) %
|
|
{'name': guard_name})
|
|
types_file.write(tpm_defines)
|
|
types_file.write((structure_generator.HEADER_FILE_GUARD_FOOTER) %
|
|
{'name': guard_name})
|
|
types_file.close()
|
|
typemap = tpm_table.GetTypeMap()
|
|
structure_generator.GenerateHeader(typemap)
|
|
structure_generator.GenerateImplementation(typemap)
|
|
commands = tpm_table.GetCommandList()
|
|
command_generator.GenerateHeader(commands)
|
|
command_generator.GenerateImplementation(commands, typemap)
|
|
print('Processed %d TPM types.' % len(typemap))
|
|
print('Processed %d commands.' % len(commands))
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
main(sys.argv)
|
|
except GeneratorException as e:
|
|
if e.message:
|
|
print(e, file=sys.stderr)
|
|
sys.exit(1)
|