summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xutil/test_util_precompile.py47
-rwxr-xr-xutil/util_precompile.py22
2 files changed, 69 insertions, 0 deletions
diff --git a/util/test_util_precompile.py b/util/test_util_precompile.py
index f27f6c4a2f..210130c12c 100755
--- a/util/test_util_precompile.py
+++ b/util/test_util_precompile.py
@@ -5,7 +5,9 @@
# found in the LICENSE file.
'Unit tests for util_precompile.py'
+import os
import pickle
+import tempfile
import unittest
import zlib
@@ -137,6 +139,50 @@ class TestUtilPrecompile(unittest.TestCase):
else:
self.fail('did not find "%s" in the dictionary')
+ def test_incremental_blob(self):
+ """Verify that string blob is properly extended.
+
+ When invoked with an existing blob, util_precompile.py is supposed to
+ re-use existing strings and only add new ones.
+
+ Create a test file with a set of strings, generate the blob, then
+ create another test file, with an extra string inserted in the
+ beginning and verify, generate the blob again, and verify that the
+ resulting blob has the strings at expected indices.
+ """
+ first_string_set = ('format string #1',
+ 'format string #2',
+ 'format_strint #3')
+
+ second_string_set = ('format string #4',) + first_string_set
+ with tempfile.TemporaryDirectory(prefix='test_uc') as td:
+ source_code = os.path.join(td, 'src.E')
+ lock_file = os.path.join(td, 'lock')
+ blob = os.path.join(td, 'blob')
+ util_precompile.FMT_DICT = {}
+
+ def prepare_source_code(file_name, strings):
+ 'Generate test .E file given a list of text strings'
+ with open(file_name, 'w') as sf:
+ for string in strings:
+ sf.write(' cprintf(CHAN, "%s");\n' % string)
+
+ prepare_source_code(source_code, first_string_set)
+ util_precompile.main(['_', '-o', blob, '-l',
+ lock_file, source_code])
+ prepare_source_code(source_code, second_string_set)
+ util_precompile.FMT_DICT = {}
+ util_precompile.main(['_', '-o', blob, '-l',
+ lock_file, source_code])
+
+ # Verify that strings in the blob are at the expected indices.
+ # The first set strings should have lower indices.
+ for i, string in enumerate(first_string_set):
+ self.assertEqual(util_precompile.FMT_DICT.get(string, None), i)
+ # The second set strings should have higher indices.
+ string = second_string_set[0]
+ i = len(second_string_set) - 1
+ self.assertEqual(util_precompile.FMT_DICT.get(string, None), i)
def test_drop_escapes(self):
'Verify proper conversion of escape characters'
@@ -147,5 +193,6 @@ class TestUtilPrecompile(unittest.TestCase):
for i, o in insouts:
self.assertEqual(o, util_precompile.drop_escapes(i))
+
if __name__ == '__main__':
unittest.main()
diff --git a/util/util_precompile.py b/util/util_precompile.py
index c58b811913..bc8ad0320f 100755
--- a/util/util_precompile.py
+++ b/util/util_precompile.py
@@ -521,6 +521,27 @@ def generate_blob():
print('dump size %d, compressed size %d' % (len(dump), len(zipped)))
return zipped
+def seed_blob(outfile):
+ """Read string data from a previously saved blob
+
+ This function is invoked only if the blob file exists.
+ """
+ global FMT_DICT
+ if outfile.endswith('Ep'):
+ print('invoked with', ' '.join(sys.argv))
+ assert False
+ with open(outfile, 'rb') as blob:
+ try:
+ zipped = blob.read()
+ pickled = zlib.decompress(zipped)
+ dump = pickle.loads(pickled)
+ except (zlib.error, pickle.UnpicklingError):
+ print('%s does not seem to be a proper blob, ignored' % outfile)
+ return
+ strings = dump.split('\0')
+ for i in range(len(strings)):
+ FMT_DICT[strings[i]] = i
+
def main(argv):
"""Main function.
@@ -546,6 +567,7 @@ def main(argv):
else:
# Output file is newer than all inputs.
return
+ seed_blob(flags.output)
for e_file in files[1:]:
preobj_process(e_file, flags.ext)