Fix jsoncpp.pc file
[platform/upstream/jsoncpp.git] / amalgamate.py
1 #!/usr/bin/env python
2
3 """Amalgamate json-cpp library sources into a single source and header file.
4
5 Works with python2.6+ and python3.4+.
6
7 Example of invocation (must be invoked from json-cpp top directory):
8 python amalgamate.py
9 """
10 import os
11 import os.path
12 import sys
13
14 INCLUDE_PATH = "include/json"
15 SRC_PATH = "src/lib_json"
16
17 class AmalgamationFile:
18     def __init__(self, top_dir):
19         self.top_dir = top_dir
20         self.blocks = []
21
22     def add_text(self, text):
23         if not text.endswith("\n"):
24             text += "\n"
25         self.blocks.append(text)
26
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")
36         content = f.read()
37         if wrap_in_comment:
38             content = "/*\n" + content + "\n*/"
39         self.add_text(content)
40         f.close()
41         add_marker("End")
42         self.add_text("\n\n\n\n")
43
44     def get_value(self):
45         return "".join(self.blocks).replace("\r\n","\n")
46
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'))
53         f.close()
54
55 def amalgamate_source(source_top_dir=None,
56                        target_source_path=None,
57                        header_include_path=None):
58     """Produces amalgamated source.
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     """
64     print("Amalgamating header...")
65     header = AmalgamationFile(source_top_dir)
66     header.add_text("/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).")
67     header.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
68     header.add_file("LICENSE", wrap_in_comment=True)
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")
72     header.add_text("/// to prevent private header inclusion.")
73     header.add_text("#define JSON_IS_AMALGAMATION")
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"))
78     header.add_file(os.path.join(INCLUDE_PATH, "json_features.h"))
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"))
83     header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED")
84
85     target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
86     print("Writing amalgamated header to %r" % target_header_path)
87     header.write_to(target_header_path)
88
89     base, ext = os.path.splitext(header_include_path)
90     forward_header_include_path = base + "-forwards" + ext
91     print("Amalgamating forward header...")
92     header = AmalgamationFile(source_top_dir)
93     header.add_text("/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).")
94     header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path)
95     header.add_text("/// This header provides forward declaration for all JsonCpp types.")
96     header.add_file("LICENSE", wrap_in_comment=True)
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")
100     header.add_text("/// to prevent private header inclusion.")
101     header.add_text("#define JSON_IS_AMALGAMATION")
102     header.add_file(os.path.join(INCLUDE_PATH, "config.h"))
103     header.add_file(os.path.join(INCLUDE_PATH, "forwards.h"))
104     header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED")
105
106     target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
107                                                forward_header_include_path)
108     print("Writing amalgamated forward header to %r" % target_forward_header_path)
109     header.write_to(target_forward_header_path)
110
111     print("Amalgamating source...")
112     source = AmalgamationFile(source_top_dir)
113     source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).")
114     source.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
115     source.add_file("LICENSE", wrap_in_comment=True)
116     source.add_text("")
117     source.add_text('#include "%s"' % header_include_path)
118     source.add_text("""
119 #ifndef JSON_IS_AMALGAMATION
120 #error "Compile with -I PATH_TO_JSON_DIRECTORY"
121 #endif
122 """)
123     source.add_text("")
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"))
129
130     print("Writing amalgamated source to %r" % target_source_path)
131     source.write_to(target_source_path)
132
133 def main():
134     usage = """%prog [options]
135 Generate a single amalgamated source and header file from the sources.
136 """
137     from optparse import OptionParser
138     parser = OptionParser(usage=usage)
139     parser.allow_interspersed_args = False
140     parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
141         help="""Output .cpp source path. [Default: %default]""")
142     parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
143         help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""")
144     parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(),
145         help="""Source top-directory. [Default: %default]""")
146     parser.enable_interspersed_args()
147     options, args = parser.parse_args()
148
149     msg = amalgamate_source(source_top_dir=options.top_dir,
150                              target_source_path=options.target_source_path,
151                              header_include_path=options.header_include_path)
152     if msg:
153         sys.stderr.write(msg + "\n")
154         sys.exit(1)
155     else:
156         print("Source successfully amalgamated")
157
158 if __name__ == "__main__":
159     main()