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