blob: f84936fbf963d10489a23fabae3097cfb0f3d443 [file] [log] [blame]
Christopher Dunndc0f7362011-06-21 21:18:49 +00001"""Amalgate json-cpp library sources into a single source and header file.
2
3Requires Python 2.6
4
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")
70 header.add_file("include/json/config.h")
71 header.add_file("include/json/forwards.h")
72 header.add_file("include/json/features.h")
73 header.add_file("include/json/value.h")
74 header.add_file("include/json/reader.h")
75 header.add_file("include/json/writer.h")
76 header.add_file("include/json/assertions.h")
77 header.add_text("#endif //ifndef JSON_AMALGATED_H_INCLUDED")
Christopher Dunndc0f7362011-06-21 21:18:49 +000078
Christopher Dunn494950a2015-01-24 15:29:52 -060079 target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
Christopher Dunnbd1e8952014-11-19 23:30:47 -060080 print("Writing amalgated header to %r" % target_header_path)
Christopher Dunn494950a2015-01-24 15:29:52 -060081 header.write_to(target_header_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +000082
Christopher Dunn494950a2015-01-24 15:29:52 -060083 base, ext = os.path.splitext(header_include_path)
SuperManitu83b43ca2014-09-10 11:02:01 -070084 forward_header_include_path = base + "-forwards" + ext
Christopher Dunnbd1e8952014-11-19 23:30:47 -060085 print("Amalgating forward header...")
Christopher Dunn494950a2015-01-24 15:29:52 -060086 header = AmalgamationFile(source_top_dir)
87 header.add_text("/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).")
Christopher Dunnc6582412015-02-15 11:37:37 -060088 header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path)
Christopher Dunn494950a2015-01-24 15:29:52 -060089 header.add_text("/// This header provides forward declaration for all JsonCpp types.")
90 header.add_file("LICENSE", wrap_in_comment=True)
91 header.add_text("#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
92 header.add_text("# define JSON_FORWARD_AMALGATED_H_INCLUDED")
93 header.add_text("/// If defined, indicates that the source file is amalgated")
94 header.add_text("/// to prevent private header inclusion.")
95 header.add_text("#define JSON_IS_AMALGAMATION")
96 header.add_file("include/json/config.h")
97 header.add_file("include/json/forwards.h")
98 header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
Christopher Dunndc0f7362011-06-21 21:18:49 +000099
Christopher Dunn494950a2015-01-24 15:29:52 -0600100 target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
101 forward_header_include_path)
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600102 print("Writing amalgated forward header to %r" % target_forward_header_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600103 header.write_to(target_forward_header_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000104
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600105 print("Amalgating source...")
Christopher Dunn494950a2015-01-24 15:29:52 -0600106 source = AmalgamationFile(source_top_dir)
107 source.add_text("/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).")
Christopher Dunnc6582412015-02-15 11:37:37 -0600108 source.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600109 source.add_file("LICENSE", wrap_in_comment=True)
110 source.add_text("")
Christopher Dunn0ee7e242015-02-15 10:47:49 -0600111 source.add_text('#include "%s"' % header_include_path)
112 source.add_text("""
Christopher Dunn2f4e40b2015-02-18 09:17:06 -0600113#ifndef JSON_IS_AMALGAMATION
Christopher Dunn0ee7e242015-02-15 10:47:49 -0600114#error "Compile with -I PATH_TO_JSON_DIRECTORY"
115#endif
116""")
Christopher Dunn494950a2015-01-24 15:29:52 -0600117 source.add_text("")
SuperManitu83b43ca2014-09-10 11:02:01 -0700118 lib_json = "src/lib_json"
Christopher Dunn494950a2015-01-24 15:29:52 -0600119 source.add_file(os.path.join(lib_json, "json_tool.h"))
120 source.add_file(os.path.join(lib_json, "json_reader.cpp"))
Christopher Dunn494950a2015-01-24 15:29:52 -0600121 source.add_file(os.path.join(lib_json, "json_valueiterator.inl"))
122 source.add_file(os.path.join(lib_json, "json_value.cpp"))
123 source.add_file(os.path.join(lib_json, "json_writer.cpp"))
Christopher Dunndc0f7362011-06-21 21:18:49 +0000124
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600125 print("Writing amalgated source to %r" % target_source_path)
Christopher Dunn494950a2015-01-24 15:29:52 -0600126 source.write_to(target_source_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000127
128def main():
129 usage = """%prog [options]
130Generate a single amalgated source and header file from the sources.
131"""
132 from optparse import OptionParser
133 parser = OptionParser(usage=usage)
134 parser.allow_interspersed_args = False
SuperManitu83b43ca2014-09-10 11:02:01 -0700135 parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
Christopher Dunndc0f7362011-06-21 21:18:49 +0000136 help="""Output .cpp source path. [Default: %default]""")
SuperManitu83b43ca2014-09-10 11:02:01 -0700137 parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
Christopher Dunndc0f7362011-06-21 21:18:49 +0000138 help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""")
SuperManitu83b43ca2014-09-10 11:02:01 -0700139 parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(),
Christopher Dunndc0f7362011-06-21 21:18:49 +0000140 help="""Source top-directory. [Default: %default]""")
141 parser.enable_interspersed_args()
142 options, args = parser.parse_args()
143
Christopher Dunn494950a2015-01-24 15:29:52 -0600144 msg = amalgamate_source(source_top_dir=options.top_dir,
Christopher Dunndc0f7362011-06-21 21:18:49 +0000145 target_source_path=options.target_source_path,
Christopher Dunn494950a2015-01-24 15:29:52 -0600146 header_include_path=options.header_include_path)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000147 if msg:
Christopher Dunn494950a2015-01-24 15:29:52 -0600148 sys.stderr.write(msg + "\n")
149 sys.exit(1)
Christopher Dunndc0f7362011-06-21 21:18:49 +0000150 else:
Christopher Dunnbd1e8952014-11-19 23:30:47 -0600151 print("Source succesfully amalagated")
SuperManitu83b43ca2014-09-10 11:02:01 -0700152
153if __name__ == "__main__":
Christopher Dunndc0f7362011-06-21 21:18:49 +0000154 main()