blob: 9cb2d08ccda7c7d8e87c2e7c54de4a42353812fd [file] [log] [blame]
Christopher Dunndc0f7362011-06-21 21:18:49 +00001"""Amalgate json-cpp library sources into a single source and header file.
2
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):
6python amalgate.py
7"""
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):
Christopher Dunndc0f7362011-06-21 21:18:49 +000053 """Produces amalgated source.
54 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 """
Christopher Dunnbd1e8952014-11-19 23:30:47 -060059 print("Amalgating header...")
Christopher Dunn494950a2015-01-24 15:29:52 -060060 header = AmalgamationFile(source_top_dir)
61 header.add_text("/// Json-cpp amalgated 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)
64 header.add_text("#ifndef JSON_AMALGATED_H_INCLUDED")
65 header.add_text("# define JSON_AMALGATED_H_INCLUDED")
66 header.add_text("/// If defined, indicates that the source file is amalgated")
67 header.add_text("/// to prevent private header inclusion.")
68 header.add_text("#define JSON_IS_AMALGAMATION")
69 header.add_file("include/json/version.h")
Christopher Dunn980cdf02016-04-22 00:45:18 -050070 #header.add_file("include/json/allocator.h") # Not available here.
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")
78 header.add_text("#endif //ifndef JSON_AMALGATED_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)
Christopher Dunnbd1e8952014-11-19 23:30:47 -060081 print("Writing amalgated 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
Christopher Dunnbd1e8952014-11-19 23:30:47 -060086 print("Amalgating forward header...")
Christopher Dunn494950a2015-01-24 15:29:52 -060087 header = AmalgamationFile(source_top_dir)
88 header.add_text("/// Json-cpp amalgated 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)
92 header.add_text("#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
93 header.add_text("# define JSON_FORWARD_AMALGATED_H_INCLUDED")
94 header.add_text("/// If defined, indicates that the source file is amalgated")
95 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")
99 header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_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)
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600103 print("Writing amalgated 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
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600106 print("Amalgating source...")
Christopher Dunn494950a2015-01-24 15:29:52 -0600107 source = AmalgamationFile(source_top_dir)
108 source.add_text("/// Json-cpp amalgated 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
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600126 print("Writing amalgated 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]
131Generate a single amalgated source and header file from the sources.
132"""
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",
Christopher Dunndc0f7362011-06-21 21:18:49 +0000139 help="""Header include path. Used to include the header from the amalgated 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:
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600152 print("Source succesfully amalagated")
SuperManitu83b43ca2014-09-10 11:02:01 -0700153
154if __name__ == "__main__":
Christopher Dunndc0f7362011-06-21 21:18:49 +0000155 main()