Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 3 | """Amalgamate json-cpp library sources into a single source and header file. |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 4 | |
Christopher Dunn | 99822b2 | 2015-03-03 16:16:47 -0600 | [diff] [blame] | 5 | Works with python2.6+ and python3.4+. |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 6 | |
| 7 | Example of invocation (must be invoked from json-cpp top directory): |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 8 | python amalgamate.py |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 9 | """ |
| 10 | import os |
| 11 | import os.path |
| 12 | import sys |
| 13 | |
Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 14 | INCLUDE_PATH = "include/json" |
| 15 | SRC_PATH = "src/lib_json" |
| 16 | |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 17 | class AmalgamationFile: |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 18 | def __init__(self, top_dir): |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 19 | self.top_dir = top_dir |
| 20 | self.blocks = [] |
| 21 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 22 | def add_text(self, text): |
| 23 | if not text.endswith("\n"): |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 24 | text += "\n" |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 25 | self.blocks.append(text) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 26 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 27 | def add_file(self, relative_input_path, wrap_in_comment=False): |
| 28 | def add_marker(prefix): |
| 29 | self.add_text("") |
| 30 | self.add_text("// " + "/"*70) |
| 31 | self.add_text("// %s of content of file: %s" % (prefix, relative_input_path.replace("\\","/"))) |
| 32 | self.add_text("// " + "/"*70) |
| 33 | self.add_text("") |
| 34 | add_marker("Beginning") |
| 35 | f = open(os.path.join(self.top_dir, relative_input_path), "rt") |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 36 | content = f.read() |
| 37 | if wrap_in_comment: |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 38 | content = "/*\n" + content + "\n*/" |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 39 | self.add_text(content) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 40 | f.close() |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 41 | add_marker("End") |
| 42 | self.add_text("\n\n\n\n") |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 43 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 44 | def get_value(self): |
| 45 | return "".join(self.blocks).replace("\r\n","\n") |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 46 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 47 | def write_to(self, output_path): |
| 48 | output_dir = os.path.dirname(output_path) |
| 49 | if output_dir and not os.path.isdir(output_dir): |
| 50 | os.makedirs(output_dir) |
| 51 | f = open(output_path, "wb") |
| 52 | f.write(str.encode(self.get_value(), 'UTF-8')) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 53 | f.close() |
| 54 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 55 | def amalgamate_source(source_top_dir=None, |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 56 | target_source_path=None, |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 57 | header_include_path=None): |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 58 | """Produces amalgamated source. |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 59 | Parameters: |
| 60 | source_top_dir: top-directory |
| 61 | target_source_path: output .cpp path |
| 62 | header_include_path: generated header path relative to target_source_path. |
| 63 | """ |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 64 | print("Amalgamating header...") |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 65 | header = AmalgamationFile(source_top_dir) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 66 | header.add_text("/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).") |
Christopher Dunn | c658241 | 2015-02-15 11:37:37 -0600 | [diff] [blame] | 67 | header.add_text('/// It is intended to be used with #include "%s"' % header_include_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 68 | header.add_file("LICENSE", wrap_in_comment=True) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 69 | header.add_text("#ifndef JSON_AMALGAMATED_H_INCLUDED") |
| 70 | header.add_text("# define JSON_AMALGAMATED_H_INCLUDED") |
| 71 | header.add_text("/// If defined, indicates that the source file is amalgamated") |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 72 | header.add_text("/// to prevent private header inclusion.") |
| 73 | header.add_text("#define JSON_IS_AMALGAMATION") |
Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 74 | header.add_file(os.path.join(INCLUDE_PATH, "version.h")) |
| 75 | header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) |
| 76 | header.add_file(os.path.join(INCLUDE_PATH, "config.h")) |
| 77 | header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) |
Jordan Bayles | 00b979f | 2019-09-25 14:04:53 -0700 | [diff] [blame] | 78 | header.add_file(os.path.join(INCLUDE_PATH, "json_features.h")) |
Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 79 | header.add_file(os.path.join(INCLUDE_PATH, "value.h")) |
| 80 | header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) |
| 81 | header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) |
| 82 | header.add_file(os.path.join(INCLUDE_PATH, "assertions.h")) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 83 | header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 84 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 85 | target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 86 | print("Writing amalgamated header to %r" % target_header_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 87 | header.write_to(target_header_path) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 88 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 89 | base, ext = os.path.splitext(header_include_path) |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 90 | forward_header_include_path = base + "-forwards" + ext |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 91 | print("Amalgamating forward header...") |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 92 | header = AmalgamationFile(source_top_dir) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 93 | header.add_text("/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).") |
Christopher Dunn | c658241 | 2015-02-15 11:37:37 -0600 | [diff] [blame] | 94 | header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 95 | header.add_text("/// This header provides forward declaration for all JsonCpp types.") |
| 96 | header.add_file("LICENSE", wrap_in_comment=True) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 97 | header.add_text("#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") |
| 98 | header.add_text("# define JSON_FORWARD_AMALGAMATED_H_INCLUDED") |
| 99 | header.add_text("/// If defined, indicates that the source file is amalgamated") |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 100 | header.add_text("/// to prevent private header inclusion.") |
| 101 | header.add_text("#define JSON_IS_AMALGAMATION") |
Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 102 | header.add_file(os.path.join(INCLUDE_PATH, "config.h")) |
| 103 | header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 104 | header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 105 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 106 | target_forward_header_path = os.path.join(os.path.dirname(target_source_path), |
| 107 | forward_header_include_path) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 108 | print("Writing amalgamated forward header to %r" % target_forward_header_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 109 | header.write_to(target_forward_header_path) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 110 | |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 111 | print("Amalgamating source...") |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 112 | source = AmalgamationFile(source_top_dir) |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 113 | source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).") |
Christopher Dunn | c658241 | 2015-02-15 11:37:37 -0600 | [diff] [blame] | 114 | source.add_text('/// It is intended to be used with #include "%s"' % header_include_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 115 | source.add_file("LICENSE", wrap_in_comment=True) |
| 116 | source.add_text("") |
Christopher Dunn | 0ee7e24 | 2015-02-15 10:47:49 -0600 | [diff] [blame] | 117 | source.add_text('#include "%s"' % header_include_path) |
| 118 | source.add_text(""" |
Christopher Dunn | 2f4e40b | 2015-02-18 09:17:06 -0600 | [diff] [blame] | 119 | #ifndef JSON_IS_AMALGAMATION |
Christopher Dunn | 0ee7e24 | 2015-02-15 10:47:49 -0600 | [diff] [blame] | 120 | #error "Compile with -I PATH_TO_JSON_DIRECTORY" |
| 121 | #endif |
| 122 | """) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 123 | source.add_text("") |
Jordan Bayles | 7b28698 | 2019-08-13 22:41:43 -0700 | [diff] [blame] | 124 | source.add_file(os.path.join(SRC_PATH, "json_tool.h")) |
| 125 | source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) |
| 126 | source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) |
| 127 | source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) |
| 128 | source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 129 | |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 130 | print("Writing amalgamated source to %r" % target_source_path) |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 131 | source.write_to(target_source_path) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 132 | |
| 133 | def main(): |
| 134 | usage = """%prog [options] |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 135 | Generate a single amalgamated source and header file from the sources. |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 136 | """ |
| 137 | from optparse import OptionParser |
| 138 | parser = OptionParser(usage=usage) |
| 139 | parser.allow_interspersed_args = False |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 140 | parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp", |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 141 | help="""Output .cpp source path. [Default: %default]""") |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 142 | parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h", |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 143 | help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""") |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 144 | parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(), |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 145 | help="""Source top-directory. [Default: %default]""") |
| 146 | parser.enable_interspersed_args() |
| 147 | options, args = parser.parse_args() |
| 148 | |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 149 | msg = amalgamate_source(source_top_dir=options.top_dir, |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 150 | target_source_path=options.target_source_path, |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 151 | header_include_path=options.header_include_path) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 152 | if msg: |
Christopher Dunn | 494950a | 2015-01-24 15:29:52 -0600 | [diff] [blame] | 153 | sys.stderr.write(msg + "\n") |
| 154 | sys.exit(1) |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 155 | else: |
Josh Soref | e6a588a | 2017-12-03 11:54:29 -0500 | [diff] [blame] | 156 | print("Source successfully amalgamated") |
SuperManitu | 83b43ca | 2014-09-10 11:02:01 -0700 | [diff] [blame] | 157 | |
| 158 | if __name__ == "__main__": |
Christopher Dunn | dc0f736 | 2011-06-21 21:18:49 +0000 | [diff] [blame] | 159 | main() |