Tools: Add python modules

Add generic python modules to TF-M to support build and image packaging
tools.

* arg_utils provides helpers to deal with argparse arguments
* c_include gets the list of include paths for a file from the
  `compile_commands.json` build database
* c_macro includes a python implementation of (most of) the C
  preprocessor.
* c_struct is a libclang-based evaluator of C datastructures (Including
  enums) which can be used to generate python representations of nested
  C datastructures which rely on complex macro configuration.
* crypto_conversion_utils provides helpers to convert various types of
  crypto keys to different and convert string representations of
  algorithms and hash functions to their python objects
* encrypt_data provides functions to encrypt bytes() objects
* file_loader provides automatic handler functions for various filetypes
  based on their extensions, primarily useful for loading crypto keys
* key_derivation provides a python implementation of HKDF and a
  SP200-108 CMAC KDF, both matching the TF-M/MbedTLS/CC3XX implementation
* sign_data provides functions to perform symmetric and asymmetric
  signatures of bytes() objects
* sign_then_encrypt_data provides combined signing and encryption,
  either via symmetric AEAD modes or a combination of the sign_data and
  encrypt_data modules
* struct_pack provides helper functions for packing bytes objects
  together.

Change-Id: I858dd8ef69c9069ec0a44e4ad3f9a1d70cc5d4da
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/tools/modules/c_include.py b/tools/modules/c_include.py
new file mode 100644
index 0000000..636f31d
--- /dev/null
+++ b/tools/modules/c_include.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+#-------------------------------------------------------------------------------
+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+import os
+import json
+
+def get_compile_command(compile_commands_file, c_file):
+    with open(compile_commands_file, "rt") as f:
+        compile_commands = json.load(f)
+
+    return [x['command'] for x in compile_commands if c_file in x['file']][0]
+
+def get_includes(compile_commands_file, c_file):
+    compile_command = get_compile_command(compile_commands_file, c_file).split()
+    return [x[2:].strip() for x in compile_command if x.rstrip()[:2] == "-I"]
+
+def get_defines(compile_commands_file, c_file):
+    compile_command = get_compile_command(compile_commands_file, c_file).split()
+    return [x[2:].strip() for x in compile_command if x.rstrip()[:2] == "-D"]
+
+
+if __name__ == '__main__':
+    import argparse
+
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument("--compile_commands_file", help="path to compile_command.json", required=True)
+    parser.add_argument("--c_file", help="name of the c file to take", required=True)
+    parser.add_argument("--log_level", help="log level", required=False, default="ERROR", choices=logging._levelToName.values())
+    args = parser.parse_args()
+    logger.setLevel(args.log_level)
+
+    print(get_compile_command(args.compile_commands_file, args.c_file))
+    print(get_includes(args.compile_commands_file, args.c_file))
+    print(get_defines(args.compile_commands_file, args.c_file))