17ec681f3Smrg# encoding=utf-8
27ec681f3Smrg# Copyright © 2018 Intel Corporation
37ec681f3Smrg#
47ec681f3Smrg# Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg# copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg# to deal in the Software without restriction, including without limitation
77ec681f3Smrg# the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg# and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg# Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg#
117ec681f3Smrg# The above copyright notice and this permission notice (including the next
127ec681f3Smrg# paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg# Software.
147ec681f3Smrg#
157ec681f3Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg# IN THE SOFTWARE.
227ec681f3Smrg
237ec681f3Smrg# Converts a file to a C/C++ #include containing a string
247ec681f3Smrg
257ec681f3Smrgimport argparse
267ec681f3Smrgimport io
277ec681f3Smrgimport os
287ec681f3Smrg
297ec681f3Smrg
307ec681f3Smrgdef get_args():
317ec681f3Smrg    parser = argparse.ArgumentParser()
327ec681f3Smrg    parser.add_argument('input', help="Name of input file")
337ec681f3Smrg    parser.add_argument('output', help="Name of output file")
347ec681f3Smrg    parser.add_argument("-n", "--name",
357ec681f3Smrg                        help="Name of C variable")
367ec681f3Smrg    parser.add_argument("-b", "--binary", dest='binary', action='store_const',
377ec681f3Smrg                        const=True, default=False)
387ec681f3Smrg    args = parser.parse_args()
397ec681f3Smrg    return args
407ec681f3Smrg
417ec681f3Smrg
427ec681f3Smrgdef filename_to_C_identifier(n):
437ec681f3Smrg    if n[0] != '_' and not n[0].isalpha():
447ec681f3Smrg        n = "_" + n[1:]
457ec681f3Smrg
467ec681f3Smrg    return "".join([c if c.isalnum() or c == "_" else "_" for c in n])
477ec681f3Smrg
487ec681f3Smrg
497ec681f3Smrgdef emit_byte(f, b):
507ec681f3Smrg    f.write("0x{:02x}, ".format(ord(b)).encode('utf-8'))
517ec681f3Smrg
527ec681f3Smrg
537ec681f3Smrgdef process_file(args):
547ec681f3Smrg    with io.open(args.input, "rb") as infile:
557ec681f3Smrg        try:
567ec681f3Smrg            with io.open(args.output, "wb") as outfile:
577ec681f3Smrg                # If a name was not specified on the command line, pick one based on the
587ec681f3Smrg                # name of the input file.  If no input filename was specified, use
597ec681f3Smrg                # from_stdin.
607ec681f3Smrg                if args.name is not None:
617ec681f3Smrg                    name = args.name
627ec681f3Smrg                else:
637ec681f3Smrg                    name = filename_to_C_identifier(args.input)
647ec681f3Smrg
657ec681f3Smrg                outfile.write("static const char {}[] = {{\n".format(name).encode('utf-8'))
667ec681f3Smrg
677ec681f3Smrg                linecount = 0
687ec681f3Smrg                while True:
697ec681f3Smrg                    byte = infile.read(1)
707ec681f3Smrg                    if byte == b"":
717ec681f3Smrg                        break
727ec681f3Smrg
737ec681f3Smrg                    if not args.binary:
747ec681f3Smrg                        assert(ord(byte) != 0)
757ec681f3Smrg
767ec681f3Smrg                    emit_byte(outfile, byte)
777ec681f3Smrg                    linecount = linecount + 1
787ec681f3Smrg                    if linecount > 20:
797ec681f3Smrg                        outfile.write(b"\n ")
807ec681f3Smrg                        linecount = 0
817ec681f3Smrg                if not args.binary:
827ec681f3Smrg                    outfile.write(b"\n0")
837ec681f3Smrg                outfile.write(b"\n};\n\n")
847ec681f3Smrg        except Exception:
857ec681f3Smrg            # In the event that anything goes wrong, delete the output file,
867ec681f3Smrg            # then re-raise the exception. Deleteing the output file should
877ec681f3Smrg            # ensure that the build system doesn't try to use the stale,
887ec681f3Smrg            # half-generated file.
897ec681f3Smrg            os.unlink(args.output)
907ec681f3Smrg            raise
917ec681f3Smrg
927ec681f3Smrg
937ec681f3Smrgdef main():
947ec681f3Smrg    args = get_args()
957ec681f3Smrg    process_file(args)
967ec681f3Smrg
977ec681f3Smrg
987ec681f3Smrgif __name__ == "__main__":
997ec681f3Smrg    main()
100