manifest: minor bugfixes and improvements

- More robust string handling by using Unicode
- Unix line ending in generated files
- Don't call keyword_substitute if
  - no keychains in line
  - printing to output is disabled due to unmet condition
- Fix handling of list of leaf datatypes in db

Change-Id: Ic9c9bdba12b2f536ffa707342728b1277363e99f
Signed-off-by: Miklos Balint <miklos.balint@arm.com>
diff --git a/secure_fw/services/tfm_partition_defs.inc b/secure_fw/services/tfm_partition_defs.inc
index 4cdacd2..ff6b689 100644
--- a/secure_fw/services/tfm_partition_defs.inc
+++ b/secure_fw/services/tfm_partition_defs.inc
@@ -1,31 +1,31 @@
-/*

- * Copyright (c) 2018, Arm Limited. All rights reserved.

- *

- * SPDX-License-Identifier: BSD-3-Clause

- *

- */

-

-/*********** WARNING: This is an auto-generated file. Do not edit! ***********/

-

-#ifndef __TFM_PARTITION_DEFS_INC__

-#define __TFM_PARTITION_DEFS_INC__

-

-#define TFM_SP_STORAGE_ID (TFM_SP_BASE + 0)

-

-#define TFM_SP_AUDIT_LOG_ID (TFM_SP_BASE + 1)

-

-#ifdef TFM_PARTITION_TEST_CORE

-#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 2)

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_CORE

-#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 3)

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_SST

-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 4)

-#endif /* TFM_PARTITION_TEST_SST */

-

-#define TFM_MAX_USER_PARTITIONS (5)

-

-#endif /* __TFM_PARTITION_DEFS_INC__ */

+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __TFM_PARTITION_DEFS_INC__
+#define __TFM_PARTITION_DEFS_INC__
+
+#define TFM_SP_STORAGE_ID (TFM_SP_BASE + 0)
+
+#define TFM_SP_AUDIT_LOG_ID (TFM_SP_BASE + 1)
+
+#ifdef TFM_PARTITION_TEST_CORE
+#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 2)
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_CORE
+#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 3)
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_SST
+#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 4)
+#endif /* TFM_PARTITION_TEST_SST */
+
+#define TFM_MAX_USER_PARTITIONS (5)
+
+#endif /* __TFM_PARTITION_DEFS_INC__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 9231401..5c94cd0 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -1,47 +1,47 @@
-/*

- * Copyright (c) 2018, Arm Limited. All rights reserved.

- *

- * SPDX-License-Identifier: BSD-3-Clause

- *

- */

-

-/*********** WARNING: This is an auto-generated file. Do not edit! ***********/

-

-#ifndef __TFM_PARTITION_LIST_INC__

-#define __TFM_PARTITION_LIST_INC__

-

-/******** TFM_SP_STORAGE ********/

-PARTITION_DECLARE(TFM_SP_STORAGE, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);

-PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, sst_am_prepare);

-

-/******** TFM_SP_AUDIT_LOG ********/

-PARTITION_DECLARE(TFM_SP_AUDIT_LOG, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);

-PARTITION_ADD_INIT_FUNC(TFM_SP_AUDIT_LOG, log_core_init);

-#ifdef LOG_UART_REDIRECTION

-PARTITION_ADD_PERIPHERAL(TFM_SP_AUDIT_LOG, UART1_BASE_S,

-    UART1_BASE_S + 0xFFF,

-    PPC_SP_APB_PPC_EXP1, CMSDK_UART1_APB_PPC_POS);

-#endif /* LOG_UART_REDIRECTION */

-

-#ifdef TFM_PARTITION_TEST_CORE

-/******** TFM_SP_CORE_TEST ********/

-PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);

-PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init);

-PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST, MPS2_IO_FPGAIO_BASE_S,

-    MPS2_IO_FPGAIO_BASE_S + 0xFFF,

-    PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS);

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_CORE

-/******** TFM_SP_CORE_TEST_2 ********/

-PARTITION_DECLARE(TFM_SP_CORE_TEST_2, SPM_PART_FLAG_SECURE);

-PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST_2, core_test_2_init);

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_SST

-/******** TFM_SP_SST_TEST_PARTITION ********/

-PARTITION_DECLARE(TFM_SP_SST_TEST_PARTITION, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);

-PARTITION_ADD_INIT_FUNC(TFM_SP_SST_TEST_PARTITION, sst_test_service_init);

-#endif /* TFM_PARTITION_TEST_SST */

-

-#endif /* __TFM_PARTITION_LIST_INC__ */

+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __TFM_PARTITION_LIST_INC__
+#define __TFM_PARTITION_LIST_INC__
+
+/******** TFM_SP_STORAGE ********/
+PARTITION_DECLARE(TFM_SP_STORAGE, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, sst_am_prepare);
+
+/******** TFM_SP_AUDIT_LOG ********/
+PARTITION_DECLARE(TFM_SP_AUDIT_LOG, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_AUDIT_LOG, log_core_init);
+#ifdef LOG_UART_REDIRECTION
+PARTITION_ADD_PERIPHERAL(TFM_SP_AUDIT_LOG, UART1_BASE_S,
+    UART1_BASE_S + 0xFFF,
+    PPC_SP_APB_PPC_EXP1, CMSDK_UART1_APB_PPC_POS);
+#endif /* LOG_UART_REDIRECTION */
+
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_SP_CORE_TEST ********/
+PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);
+PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init);
+PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST, MPS2_IO_FPGAIO_BASE_S,
+    MPS2_IO_FPGAIO_BASE_S + 0xFFF,
+    PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS);
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_SP_CORE_TEST_2 ********/
+PARTITION_DECLARE(TFM_SP_CORE_TEST_2, SPM_PART_FLAG_SECURE);
+PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST_2, core_test_2_init);
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_SST
+/******** TFM_SP_SST_TEST_PARTITION ********/
+PARTITION_DECLARE(TFM_SP_SST_TEST_PARTITION, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_SST_TEST_PARTITION, sst_test_service_init);
+#endif /* TFM_PARTITION_TEST_SST */
+
+#endif /* __TFM_PARTITION_LIST_INC__ */
diff --git a/secure_fw/services/tfm_sfid_list.inc b/secure_fw/services/tfm_sfid_list.inc
index d2029db..b6b3112 100644
--- a/secure_fw/services/tfm_sfid_list.inc
+++ b/secure_fw/services/tfm_sfid_list.inc
@@ -1,48 +1,48 @@
-/*

- * Copyright (c) 2018, Arm Limited. All rights reserved.

- *

- * SPDX-License-Identifier: BSD-3-Clause

- *

- */

-

-/*********** WARNING: This is an auto-generated file. Do not edit! ***********/

-

-#ifndef __TFM_SFID_LIST_INC__

-#define __TFM_SFID_LIST_INC__

-

-    /******** TFM_SP_STORAGE ********/

-    {sst_am_get_handle, SST_AM_GET_HANDLE_SFID},

-    {sst_am_create, SST_AM_CREATE_SFID},

-    {sst_am_get_attributes, SST_AM_GET_ATTRIBUTES_SFID},

-    {sst_am_read, SST_AM_READ_SFID},

-    {sst_am_write, SST_AM_WRITE_SFID},

-    {sst_am_delete, SST_AM_DELETE_SFID},

-

-    /******** TFM_SP_AUDIT_LOG ********/

-    {log_core_retrieve, TFM_LOG_RETRIEVE_SFID},

-    {log_core_add_line, TFM_LOG_ADD_LINE_SFID},

-    {log_core_get_info, TFM_LOG_GET_INFO_SFID},

-    {log_core_delete_items, TFM_LOG_DELETE_ITEMS_SFID},

-

-#ifdef TFM_PARTITION_TEST_CORE

-    /******** TFM_SP_CORE_TEST ********/

-    {spm_core_test_sfn, TFM_CORE_TEST_SFN_SFID},

-    {spm_core_test_sfn_init_success, TFM_CORE_TEST_SFN_INIT_SUCCESS_SFID},

-    {spm_core_test_sfn_direct_recursion, TFM_CORE_TEST_SFN_DIRECT_RECURSION_SFID},

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_CORE

-    /******** TFM_SP_CORE_TEST_2 ********/

-    {spm_core_test_2_slave_service, TFM_CORE_TEST_2_SFN_SLAVE_SERVICE_SFID},

-    {spm_core_test_2_sfn_invert, TFM_CORE_TEST_2_SFN_INVERT_SFID},

-#endif /* TFM_PARTITION_TEST_CORE */

-

-#ifdef TFM_PARTITION_TEST_SST

-    /******** TFM_SP_SST_TEST_PARTITION ********/

-    {sst_test_service_sfn_setup, TFM_SST_TEST_SFN_SETUP_SFID},

-    {sst_test_service_sfn_dummy_encrypt, TFM_SST_TEST_SFN_DUMMY_ENCRYPT_SFID},

-    {sst_test_service_sfn_dummy_decrypt, TFM_SST_TEST_SFN_DUMMY_DECRYPT_SFID},

-    {sst_test_service_sfn_clean, TFM_SST_TEST_SFN_CLEAN_SFID},

-#endif /* TFM_PARTITION_TEST_SST */

-

-#endif /* __TFM_SFID_LIST_INC__ */

+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __TFM_SFID_LIST_INC__
+#define __TFM_SFID_LIST_INC__
+
+    /******** TFM_SP_STORAGE ********/
+    {sst_am_get_handle, SST_AM_GET_HANDLE_SFID},
+    {sst_am_create, SST_AM_CREATE_SFID},
+    {sst_am_get_attributes, SST_AM_GET_ATTRIBUTES_SFID},
+    {sst_am_read, SST_AM_READ_SFID},
+    {sst_am_write, SST_AM_WRITE_SFID},
+    {sst_am_delete, SST_AM_DELETE_SFID},
+
+    /******** TFM_SP_AUDIT_LOG ********/
+    {log_core_retrieve, TFM_LOG_RETRIEVE_SFID},
+    {log_core_add_line, TFM_LOG_ADD_LINE_SFID},
+    {log_core_get_info, TFM_LOG_GET_INFO_SFID},
+    {log_core_delete_items, TFM_LOG_DELETE_ITEMS_SFID},
+
+#ifdef TFM_PARTITION_TEST_CORE
+    /******** TFM_SP_CORE_TEST ********/
+    {spm_core_test_sfn, TFM_CORE_TEST_SFN_SFID},
+    {spm_core_test_sfn_init_success, TFM_CORE_TEST_SFN_INIT_SUCCESS_SFID},
+    {spm_core_test_sfn_direct_recursion, TFM_CORE_TEST_SFN_DIRECT_RECURSION_SFID},
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_CORE
+    /******** TFM_SP_CORE_TEST_2 ********/
+    {spm_core_test_2_slave_service, TFM_CORE_TEST_2_SFN_SLAVE_SERVICE_SFID},
+    {spm_core_test_2_sfn_invert, TFM_CORE_TEST_2_SFN_INVERT_SFID},
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_SST
+    /******** TFM_SP_SST_TEST_PARTITION ********/
+    {sst_test_service_sfn_setup, TFM_SST_TEST_SFN_SETUP_SFID},
+    {sst_test_service_sfn_dummy_encrypt, TFM_SST_TEST_SFN_DUMMY_ENCRYPT_SFID},
+    {sst_test_service_sfn_dummy_decrypt, TFM_SST_TEST_SFN_DUMMY_DECRYPT_SFID},
+    {sst_test_service_sfn_clean, TFM_SST_TEST_SFN_CLEAN_SFID},
+#endif /* TFM_PARTITION_TEST_SST */
+
+#endif /* __TFM_SFID_LIST_INC__ */
diff --git a/tools/generate_from_template.py b/tools/generate_from_template.py
index 5f2153a..a1ab137 100644
--- a/tools/generate_from_template.py
+++ b/tools/generate_from_template.py
@@ -5,8 +5,9 @@
 #
 #-------------------------------------------------------------------------------
 
-import os
-from keyword_substitution import keyword_substitute, Verbosity, log_print
+from __future__ import unicode_literals
+import os, re, io
+from keyword_substitution import keyword_substitute, Verbosity, log_print, REkeychain
 
 VERBOSITY = Verbosity.warning
 log_print(Verbosity.debug, "Setting verbosity to", VERBOSITY, verbosity=VERBOSITY)
@@ -27,10 +28,17 @@
 # All operations assume tf-m repo root as active working directory
 
 # Functions
+def substitute(manifest, line, MISSING_KEYS_ACTION):
+    outlist = keyword_substitute(manifest, line, MISSING_KEYS_ACTION)
+    outstring = ""
+    for outline in outlist:
+        outstring += ''.join(outline)
+    log_print(Verbosity.info, outstring)
+    return outstring
+
 def generate(db, outfile_name):
-    outfile = \
-        open(outfile_name, "w")
-    with open(outfile_name + '.template', "r") as template_file:
+    outfile = io.open(outfile_name, "w", newline='\n')
+    with io.open(outfile_name + '.template', "r") as template_file:
         template = template_file.readlines()
 
     output = []
@@ -49,24 +57,24 @@
             iteration_counter = 0
             log_print(Verbosity.info, "Blocklines:", str(blocklines))
             for manifest in db:
-                print_blocked = False
+                ignore_line = False
                 for line in blocklines:
-                    outlist = keyword_substitute(manifest, line, MISSING_KEYS_ACTION)
-                    outstring = ""
-                    for outline in outlist:
-                        outstring += ''.join(outline)
-                    log_print(Verbosity.info, outstring)
-                    if controlconditionstart in outstring:
+                    if controlconditionstart in line:
+                        outstring = substitute(manifest, line, MISSING_KEYS_ACTION)
                         if 'False' in outstring:
                             log_print(Verbosity.info, "PRINT BLOCKED")
-                            print_blocked = True
-                    elif controlconditionend in outstring:
+                            ignore_line = True
+                    elif controlconditionend in line:
                         log_print(Verbosity.info, "PRINT ENABLED")
-                        print_blocked = False
-                    elif controlconditionelse in outstring:
-                        log_print(Verbosity.info, "PRINT " + str(print_blocked))
-                        print_blocked = not print_blocked
-                    else:
+                        ignore_line = False
+                    elif controlconditionelse in line:
+                        log_print(Verbosity.info, "PRINT " + str(ignore_line))
+                        ignore_line = not ignore_line
+                    elif not ignore_line:
+                        if re.search(REkeychain, line):
+                            outstring = substitute(manifest, line, MISSING_KEYS_ACTION)
+                        else:
+                            outstring = line
                         if control_print_iteration_counter in outstring:
                             outstring = outstring.replace(
                                             control_print_iteration_counter,
@@ -75,8 +83,7 @@
                             print "Invalid control symbol:", outstring
                             print "exiting"
                             exit(1)
-                        if not print_blocked:
-                            outfile.write(outstring)
+                        outfile.write(outstring)
                 iteration_counter += 1
                 # end for manifest in db
             blocks.append(blocklines)
@@ -104,4 +111,5 @@
 def generate_from_template_file(db, file_list):
     for file in file_list:
         outfile = file["output"]
+        print "Generating", outfile
         generate(db, outfile)
diff --git a/tools/keyword_substitution.py b/tools/keyword_substitution.py
index 9a98aae..1687338 100644
--- a/tools/keyword_substitution.py
+++ b/tools/keyword_substitution.py
@@ -24,6 +24,7 @@
 
 REkeychain = "@@\w+[\.\w+]*@@"
 REfirstkeyword = "@@\w+\.?"
+emptychain = "@@@@"
 
 MISSING_KEYS_ACTION = 'halt'
 
@@ -43,7 +44,7 @@
     depth += 1
     log_print(Verbosity.info, "substitute(",templist, chains, db, depth,")")
     if isinstance(db, type([])):
-        # db node is list
+        # db is list
         outlist = []
         for instance in db:
             log_print(Verbosity.info, "Going deeper at", depth, "for db list instance", instance)
@@ -51,8 +52,21 @@
         log_print(Verbosity.info, "substitute", depth, "returning from list with", outlist)
         return outlist
 
-    # db node is dict/leaf
     transientlist = list(templist)
+    if leaftype(db):
+        # db is leaf
+        for chain in chains:
+            if templist[chain] == emptychain:
+                transientlist[chain] = str(db)
+            else:
+                print "keychain not empty but db is"
+                transientlist[chain] = str(db) + templist[chain]
+                continue
+        chains = []
+        log_print(Verbosity.info, "substitute", depth, "returning from leaf with", transientlist)
+        return transientlist
+
+    # db is dict
     # find chain groups with same key
     chaingroups = {"chains": [], "keys": []}
     for chain in chains:
@@ -78,7 +92,7 @@
         log_print(Verbosity.info, "key lookup in", db, "for", key)
         if key in db.keys():
             if leaftype(db[key]):
-                # db node is leaf
+                # db entry value is leaf
                 for chain in chaingroups["chains"][groupidx]:
                     transientlist[chain] = str(db[key])
                 chaingroups["chains"][groupidx] = []
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index 76fb310..3129bde 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -49,6 +49,7 @@
         file_list_yaml = yaml.load(file_list_yaml_file)
         file_list = file_list_yaml["file_list"]
     generate_from_template_file(db, file_list)
+    print "Generation of files done"
 
 if __name__ == "__main__":
     main()