blob: c12215a8b2b6513ea76915f3b4189d6b28dae4c6 [file] [log] [blame]
Josh Sorefe6a588a2017-12-03 11:54:29 -05001"""Amalgamate json-cpp library sources into a single source and header file.
Christopher Dunndc0f7362011-06-21 21:18:49 +00002
Christopher Dunn99822b22015-03-03 16:16:47 -06003Works with python2.6+ and python3.4+.
Christopher Dunndc0f7362011-06-21 21:18:49 +00004
5Example of invocation (must be invoked from json-cpp top directory):
Josh Sorefe6a588a2017-12-03 11:54:29 -05006python amalgamate.py
Christopher Dunndc0f7362011-06-21 21:18:49 +00007"""
8import os
9import os.path
10import sys
11
12class AmalgamationFile:
Christopher Dunn494950a2015-01-24 15:29:52 -060013 def __init__(self, top_dir):
Christopher Dunndc0f7362011-06-21 21:18:49 +000014 self.top_dir = top_dir
15 self.blocks = []
16
Christopher Dunn494950a2015-01-24 15:29:52 -060017 def add_text(self, text):
18 if not text.endswith("\n"):
SuperManitu83b43ca2014-09-10 11:02:01 -070019 text += "\n"
Christopher Dunn494950a2015-01-24 15:29:52 -060020 self.blocks.append(text)
Christopher Dunndc0f7362011-06-21 21:18:49 +000021
Christopher Dunn494950a2015-01-24 15:29:52 -060022 def add_file(self, relative_input_path, wrap_in_comment=False):
23 def add_marker(prefix):
24 self.add_text("")
25 self.add_text("// " + "/"*70)
26 self.add_text("// %s of content of file: %s" % (prefix, relative_input_path.replace("\\","/")))
27 self.add_text("// " + "/"*70)
28 self.add_text("")
29 add_marker("Beginning")
30 f = open(os.path.join(self.top_dir, relative_input_path), "rt")
Christopher Dunndc0f7362011-06-21 21:18:49 +000031 content = f.read()
32 if wrap_in_comment:
SuperManitu83b43ca2014-09-10 11:02:01 -070033 content = "/*\n" + content + "\n*/"
Christopher Dunn494950a2015-01-24 15:29:52 -060034 self.add_text(content)
Christopher Dunndc0f7362011-06-21 21:18:49 +000035 f.close()
Christopher Dunn494950a2015-01-24 15:29:52 -060036 add_marker("End")
37 self.add_text("\n\n\n\n")
Christopher Dunndc0f7362011-06-21 21:18:49 +000038
Christopher Dunn494950a2015-01-24 15:29:52 -060039 def get_value(self):
40 return "".join(self.blocks).replace("\r\n","\n")
Christopher Dunndc0f7362011-06-21 21:18:49 +000041
Christopher Dunn494950a2015-01-24 15:29:52 -060042 def write_to(self, output_path):
43 output_dir = os.path.dirname(output_path)
44 if output_dir and not os.path.isdir(output_dir):
45 os.makedirs(output_dir)
46 f = open(output_path, "wb")
47 f.write(str.encode(self.get_value(), 'UTF-8'))
Christopher Dunndc0f7362011-06-21 21:18:49 +000048 f.close()
49
Christopher Dunn494950a2015-01-24 15:29:52 -060050def amalgamate_source(source_top_dir=None,
Christopher Dunndc0f7362011-06-21 21:18:49 +000051 target_source_path=None,
Christopher Dunn494950a2015-01-24 15:29:52 -060052 header_include_path=None):
Josh Sorefe6a588a2017-12-03 11:54:29 -050053 """Produces amalgamated source.
Christopher Dunndc0f7362011-06-21 21:18:49 +000054 Parameters:
55 source_top_dir: top-directory
56 target_source_path: output .cpp path
57 header_include_path: generated header path relative to target_source_path.
58 """
Josh Sorefe6a588a2017-12-03 11:54:29 -050059 print("Amalgamating header...")
Christopher Dunn494950a2015-01-24 15:29:52 -060060 header = AmalgamationFile(source_top_dir)
Josh Sorefe6a588a2017-12-03 11:54:29 -050061 header.add_text("/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).")
Christopher Dunnc6582412015-02-15 11:37:37 -060062 header.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
Christopher Dunn494950a2015-01-24 15:29:52 -060063 header.add_file("LICENSE", wrap_in_comment=True)
Josh Sorefe6a588a2017-12-03 11:54:29 -050064 header.add_text("#ifndef JSON_AMALGAMATED_H_INCLUDED")
65 header.add_text("# define JSON_AMALGAMATED_H_INCLUDED")
66 header.add_text("/// If defined, indicates that the source file is amalgamated")
Christopher Dunn494950a2015-01-24 15:29:52 -060067 header.add_text("/// to prevent private header inclusion.")
68 header.add_text("#define JSON_IS_AMALGAMATION")
69 header.add_file("include/json/version.h")
Billy Donahued85d7502019-01-19 22:58:02 -050070 header.add_file("include/json/allocator.h")
Christopher Dunn494950a2015-01-24 15:29:52 -060071 header.add_file("include/json/config.h")
72 header.add_file("include/json/forwards.h")
73 header.add_file("include/json/features.h")
74 header.add_file("include/json/value.h")
75 header.add_file("include/json/reader.h")
76 header.add_file("include/json/writer.h")
77 header.add_file("include/json/assertions.h")
Josh Sorefe6a588a2017-12-03 11:54:29 -050078 header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED")
Christopher Dunndc0f7362011-06-21 21:18:49 +000079
Christopher Dunn494950a2015-01-24 15:29:52 -060080 target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
Josh Sorefe6a588a2017-12-03 11:54:29 -050081 print("Writing amalgamated header to %r" % target_header_path)
Christopher Dunn494950a2015-01-24 15:29:52 -060082 header.write_to(target_header_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +000083
Christopher Dunn494950a2015-01-24 15:29:52 -060084 base, ext = os.path.splitext(header_include_path)
SuperManitu83b43ca2014-09-10 11:02:01 -070085 forward_header_include_path = base + "-forwards" + ext
Josh Sorefe6a588a2017-12-03 11:54:29 -050086 print("Amalgamating forward header...")
Christopher Dunn494950a2015-01-24 15:29:52 -060087 header = AmalgamationFile(source_top_dir)
Josh Sorefe6a588a2017-12-03 11:54:29 -050088 header.add_text("/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).")
Christopher Dunnc6582412015-02-15 11:37:37 -060089 header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path)
Christopher Dunn494950a2015-01-24 15:29:52 -060090 header.add_text("/// This header provides forward declaration for all JsonCpp types.")
91 header.add_file("LICENSE", wrap_in_comment=True)
Josh Sorefe6a588a2017-12-03 11:54:29 -050092 header.add_text("#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED")
93 header.add_text("# define JSON_FORWARD_AMALGAMATED_H_INCLUDED")
94 header.add_text("/// If defined, indicates that the source file is amalgamated")
Christopher Dunn494950a2015-01-24 15:29:52 -060095 header.add_text("/// to prevent private header inclusion.")
96 header.add_text("#define JSON_IS_AMALGAMATION")
97 header.add_file("include/json/config.h")
98 header.add_file("include/json/forwards.h")
Josh Sorefe6a588a2017-12-03 11:54:29 -050099 header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED")
Christopher Dunndc0f7362011-06-21 21:18:49 +0000100
Christopher Dunn494950a2015-01-24 15:29:52 -0600101 target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
102 forward_header_include_path)
Josh Sorefe6a588a2017-12-03 11:54:29 -0500103 print("Writing amalgamated forward header to %r" % target_forward_header_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600104 header.write_to(target_forward_header_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000105
Josh Sorefe6a588a2017-12-03 11:54:29 -0500106 print("Amalgamating source...")
Christopher Dunn494950a2015-01-24 15:29:52 -0600107 source = AmalgamationFile(source_top_dir)
Josh Sorefe6a588a2017-12-03 11:54:29 -0500108 source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).")
Christopher Dunnc6582412015-02-15 11:37:37 -0600109 source.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600110 source.add_file("LICENSE", wrap_in_comment=True)
111 source.add_text("")
Christopher Dunn0ee7e242015-02-15 10:47:49 -0600112 source.add_text('#include "%s"' % header_include_path)
113 source.add_text("""
Christopher Dunn2f4e40b2015-02-18 09:17:06 -0600114#ifndef JSON_IS_AMALGAMATION
Christopher Dunn0ee7e242015-02-15 10:47:49 -0600115#error "Compile with -I PATH_TO_JSON_DIRECTORY"
116#endif
117""")
Christopher Dunn494950a2015-01-24 15:29:52 -0600118 source.add_text("")
SuperManitu83b43ca2014-09-10 11:02:01 -0700119 lib_json = "src/lib_json"
Christopher Dunn494950a2015-01-24 15:29:52 -0600120 source.add_file(os.path.join(lib_json, "json_tool.h"))
121 source.add_file(os.path.join(lib_json, "json_reader.cpp"))
Christopher Dunn494950a2015-01-24 15:29:52 -0600122 source.add_file(os.path.join(lib_json, "json_valueiterator.inl"))
123 source.add_file(os.path.join(lib_json, "json_value.cpp"))
124 source.add_file(os.path.join(lib_json, "json_writer.cpp"))
Christopher Dunndc0f7362011-06-21 21:18:49 +0000125
Josh Sorefe6a588a2017-12-03 11:54:29 -0500126 print("Writing amalgamated source to %r" % target_source_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600127 source.write_to(target_source_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000128
129def main():
130 usage = """%prog [options]
Josh Sorefe6a588a2017-12-03 11:54:29 -0500131Generate a single amalgamated source and header file from the sources.
Christopher Dunndc0f7362011-06-21 21:18:49 +0000132"""
133 from optparse import OptionParser
134 parser = OptionParser(usage=usage)
135 parser.allow_interspersed_args = False
SuperManitu83b43ca2014-09-10 11:02:01 -0700136 parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
Christopher Dunndc0f7362011-06-21 21:18:49 +0000137 help="""Output .cpp source path. [Default: %default]""")
SuperManitu83b43ca2014-09-10 11:02:01 -0700138 parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
Josh Sorefe6a588a2017-12-03 11:54:29 -0500139 help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""")
SuperManitu83b43ca2014-09-10 11:02:01 -0700140 parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(),
Christopher Dunndc0f7362011-06-21 21:18:49 +0000141 help="""Source top-directory. [Default: %default]""")
142 parser.enable_interspersed_args()
143 options, args = parser.parse_args()
144
Christopher Dunn494950a2015-01-24 15:29:52 -0600145 msg = amalgamate_source(source_top_dir=options.top_dir,
Christopher Dunndc0f7362011-06-21 21:18:49 +0000146 target_source_path=options.target_source_path,
Christopher Dunn494950a2015-01-24 15:29:52 -0600147 header_include_path=options.header_include_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000148 if msg:
Christopher Dunn494950a2015-01-24 15:29:52 -0600149 sys.stderr.write(msg + "\n")
150 sys.exit(1)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000151 else:
Josh Sorefe6a588a2017-12-03 11:54:29 -0500152 print("Source successfully amalgamated")
SuperManitu83b43ca2014-09-10 11:02:01 -0700153
154if __name__ == "__main__":
Christopher Dunndc0f7362011-06-21 21:18:49 +0000155 main()