2016-06-14 13:04:48 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sys
|
2017-01-25 11:53:23 +00:00
|
|
|
import binascii
|
2020-10-19 11:37:31 +00:00
|
|
|
import time
|
2016-06-14 13:04:48 +00:00
|
|
|
|
|
|
|
assert len(sys.argv) > 2
|
|
|
|
|
2020-10-19 11:37:31 +00:00
|
|
|
start = time.time()
|
|
|
|
print("MEMFS: starting")
|
|
|
|
|
2020-10-12 13:52:42 +00:00
|
|
|
# Exclude experimental features e.g. GRIB3 and TAF
|
2019-05-01 16:51:57 +00:00
|
|
|
# The BUFR codetables is not used in the engine
|
2020-10-19 08:16:24 +00:00
|
|
|
EXCLUDED = ["grib3", "codetables", "taf", "stations"]
|
2020-10-20 19:03:48 +00:00
|
|
|
EXPECTED_FCOUNT = 6
|
2018-03-16 16:47:07 +00:00
|
|
|
|
2020-04-16 11:44:40 +00:00
|
|
|
pos = 1
|
2020-10-19 08:16:24 +00:00
|
|
|
if sys.argv[1] == "-exclude":
|
2020-03-12 17:19:34 +00:00
|
|
|
product = sys.argv[2]
|
2020-10-19 08:16:24 +00:00
|
|
|
if product == "bufr":
|
2020-03-12 17:19:34 +00:00
|
|
|
EXCLUDED.append(product)
|
2020-10-20 19:03:48 +00:00
|
|
|
EXPECTED_FCOUNT = 4
|
2020-10-19 08:16:24 +00:00
|
|
|
elif product == "grib":
|
|
|
|
EXCLUDED.extend(["grib1", "grib2"])
|
2020-10-20 19:03:48 +00:00
|
|
|
EXPECTED_FCOUNT = 2
|
2020-03-12 17:19:34 +00:00
|
|
|
else:
|
2020-10-19 08:16:24 +00:00
|
|
|
assert False, "Invalid product %s" % product
|
2020-03-12 15:14:38 +00:00
|
|
|
pos = 3
|
|
|
|
|
|
|
|
dirs = [os.path.realpath(x) for x in sys.argv[pos:-1]]
|
2020-10-19 08:16:24 +00:00
|
|
|
print("Directories: ", dirs)
|
|
|
|
print("Excluding: ", EXCLUDED)
|
2016-06-14 13:04:48 +00:00
|
|
|
|
|
|
|
FILES = {}
|
2020-04-02 15:46:49 +00:00
|
|
|
SIZES = {}
|
2016-06-14 13:04:48 +00:00
|
|
|
NAMES = []
|
2020-10-19 08:16:24 +00:00
|
|
|
CHUNK = 16 * 1024 * 1024 # chunk size in bytes
|
2016-06-14 13:04:48 +00:00
|
|
|
|
2017-07-25 10:12:43 +00:00
|
|
|
# Binary to ASCII function. Different in Python 2 and 3
|
2017-07-23 07:08:54 +00:00
|
|
|
try:
|
2020-10-19 08:16:24 +00:00
|
|
|
str(b"\x23\x20", "ascii")
|
|
|
|
ascii = lambda x: str(x, "ascii") # Python 3
|
2020-10-21 12:04:19 +00:00
|
|
|
encode = lambda x: x.encode()
|
2017-07-23 07:08:54 +00:00
|
|
|
except:
|
2020-10-19 08:16:24 +00:00
|
|
|
ascii = lambda x: str(x) # Python 2
|
2020-10-21 12:04:19 +00:00
|
|
|
encode = lambda x: x
|
2017-07-23 07:08:54 +00:00
|
|
|
|
|
|
|
|
2020-04-16 12:00:49 +00:00
|
|
|
def get_outfile_name(base, count):
|
|
|
|
return base + "_" + str(count).zfill(3) + ".c"
|
|
|
|
|
|
|
|
|
2020-04-15 21:19:44 +00:00
|
|
|
# The last argument is the base name of the generated C file(s)
|
2020-04-16 12:00:49 +00:00
|
|
|
output_file_base = sys.argv[-1]
|
2020-10-19 08:16:24 +00:00
|
|
|
|
2020-10-19 11:37:31 +00:00
|
|
|
buffer = None
|
2020-10-19 08:16:24 +00:00
|
|
|
fcount = -1
|
|
|
|
|
2016-06-14 13:04:48 +00:00
|
|
|
for directory in dirs:
|
|
|
|
|
2020-04-16 11:44:40 +00:00
|
|
|
# print("MEMFS: directory=", directory)
|
2016-06-14 13:04:48 +00:00
|
|
|
dname = os.path.basename(directory)
|
|
|
|
NAMES.append(dname)
|
|
|
|
|
2018-08-22 16:37:56 +00:00
|
|
|
for dirpath, dirnames, files in os.walk(directory, followlinks=True):
|
2020-10-19 11:37:31 +00:00
|
|
|
|
2018-03-16 16:47:07 +00:00
|
|
|
# Prune the walk by modifying the dirnames in-place
|
2018-12-27 17:13:51 +00:00
|
|
|
dirnames[:] = [dirname for dirname in dirnames if dirname not in EXCLUDED]
|
2016-06-14 13:04:48 +00:00
|
|
|
for name in files:
|
2020-10-19 11:37:31 +00:00
|
|
|
|
|
|
|
if buffer is None:
|
|
|
|
fcount += 1
|
|
|
|
opath = get_outfile_name(output_file_base, fcount)
|
|
|
|
print("MEMFS: Generating output:", opath)
|
2020-10-20 15:23:44 +00:00
|
|
|
buffer = open(opath, "w")
|
2020-10-19 11:37:31 +00:00
|
|
|
|
2020-10-19 08:16:24 +00:00
|
|
|
full = "%s/%s" % (dirpath, name)
|
2016-06-14 13:04:48 +00:00
|
|
|
_, ext = os.path.splitext(full)
|
2020-10-19 08:16:24 +00:00
|
|
|
if ext not in [".def", ".table", ".tmpl", ".list", ".txt"]:
|
2020-10-12 13:52:42 +00:00
|
|
|
continue
|
2020-10-19 08:16:24 +00:00
|
|
|
if name == "CMakeLists.txt":
|
2016-06-14 13:04:48 +00:00
|
|
|
continue
|
|
|
|
|
2020-04-16 11:44:40 +00:00
|
|
|
full = full.replace("\\", "/")
|
2020-10-19 08:16:24 +00:00
|
|
|
fname = full[full.find("/%s/" % (dname,)) :]
|
|
|
|
# print("MEMFS: Add ", fname)
|
|
|
|
name = re.sub(r"\W", "_", fname)
|
2016-06-14 13:04:48 +00:00
|
|
|
|
|
|
|
assert name not in FILES
|
2020-04-02 15:46:49 +00:00
|
|
|
assert name not in SIZES
|
2016-06-14 13:04:48 +00:00
|
|
|
FILES[name] = fname
|
2020-10-19 08:16:24 +00:00
|
|
|
SIZES[name] = os.path.getsize(full)
|
2016-06-14 13:04:48 +00:00
|
|
|
|
2020-10-21 12:04:19 +00:00
|
|
|
buffer.write(encode("const unsigned char %s[] = {" % (name,)))
|
2016-06-14 13:04:48 +00:00
|
|
|
|
2020-10-19 08:16:24 +00:00
|
|
|
with open(full, "rb") as f:
|
2016-06-14 13:04:48 +00:00
|
|
|
i = 0
|
2020-04-16 11:44:40 +00:00
|
|
|
# Python 2
|
2020-10-19 08:16:24 +00:00
|
|
|
# contents_hex = f.read().encode("hex")
|
2017-02-06 18:03:36 +00:00
|
|
|
|
2020-04-16 11:44:40 +00:00
|
|
|
# Python 2 and 3
|
2020-04-02 15:46:49 +00:00
|
|
|
contents_hex = binascii.hexlify(f.read())
|
2017-02-06 18:03:36 +00:00
|
|
|
|
|
|
|
# Read two characters at a time and convert to C hex
|
|
|
|
# e.g. 23 -> 0x23
|
2020-04-02 15:46:49 +00:00
|
|
|
for n in range(0, len(contents_hex), 2):
|
2020-10-19 08:16:24 +00:00
|
|
|
twoChars = ascii(contents_hex[n : n + 2])
|
2020-11-02 11:41:36 +00:00
|
|
|
|
2020-10-21 12:04:19 +00:00
|
|
|
buffer.write(encode("0x%s," % (twoChars,)))
|
2020-10-21 12:08:36 +00:00
|
|
|
|
2016-06-14 13:04:48 +00:00
|
|
|
i += 1
|
|
|
|
if (i % 20) == 0:
|
2020-10-21 12:04:19 +00:00
|
|
|
buffer.write(encode("\n"))
|
2020-10-19 08:16:24 +00:00
|
|
|
|
2020-10-21 12:04:19 +00:00
|
|
|
buffer.write(encode("};\n"))
|
2020-10-19 08:16:24 +00:00
|
|
|
if buffer.tell() >= CHUNK:
|
2020-10-19 11:37:31 +00:00
|
|
|
buffer.close()
|
|
|
|
buffer = None
|
2020-10-19 08:16:24 +00:00
|
|
|
|
2020-04-15 21:19:44 +00:00
|
|
|
|
2020-10-19 11:37:31 +00:00
|
|
|
if buffer is not None:
|
|
|
|
buffer.close()
|
|
|
|
|
2020-10-17 12:05:24 +00:00
|
|
|
# The number of generated C files is hard coded.
|
|
|
|
# See memfs/CMakeLists.txt
|
2020-10-20 19:03:48 +00:00
|
|
|
assert fcount == EXPECTED_FCOUNT, fcount
|
2020-04-16 12:00:49 +00:00
|
|
|
opath = output_file_base + "_final.c"
|
2020-10-20 20:30:54 +00:00
|
|
|
print("MEMFS: Generating output:", opath)
|
2020-04-16 11:06:19 +00:00
|
|
|
g = open(opath, "w")
|
2016-06-14 13:04:48 +00:00
|
|
|
|
2020-11-02 11:41:36 +00:00
|
|
|
f = open(os.path.join(os.path.dirname(__file__), "src", "memfs.c"))
|
|
|
|
for line in f.readlines():
|
|
|
|
line = line.rstrip()
|
|
|
|
if "<MARKER>" in line:
|
|
|
|
# Write extern variables with sizes
|
|
|
|
for k, v in SIZES.items():
|
|
|
|
print("extern const unsigned char %s[%d];" % (k, v), file=g)
|
|
|
|
|
|
|
|
print(
|
|
|
|
"static struct entry entries[] = {",
|
|
|
|
file=g,
|
|
|
|
)
|
|
|
|
items = [(v, k) for k, v in FILES.items()]
|
|
|
|
for k, v in sorted(items):
|
|
|
|
print(
|
|
|
|
'{"/MEMFS%s", &%s[0], sizeof(%s) / sizeof(%s[0]) },' % (k, v, v, v),
|
|
|
|
file=g,
|
|
|
|
)
|
|
|
|
print(
|
|
|
|
"};",
|
|
|
|
file=g,
|
|
|
|
)
|
|
|
|
|
|
|
|
else:
|
|
|
|
print(line, file=g)
|
|
|
|
|
2020-04-16 11:06:19 +00:00
|
|
|
|
2020-10-19 08:16:24 +00:00
|
|
|
print("Finished")
|
2020-10-19 11:37:31 +00:00
|
|
|
|
|
|
|
print("MEMFS: done", time.time() - start)
|