File: amalgamate.py

package info (click to toggle)
libjsoncpp 1.7.4-3
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 1,736 kB
  • ctags: 1,164
  • sloc: cpp: 8,047; python: 1,556; ansic: 170; makefile: 47; sh: 33
file content (155 lines) | stat: -rw-r--r-- 6,809 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""Amalgate json-cpp library sources into a single source and header file.

Works with python2.6+ and python3.4+.

Example of invocation (must be invoked from json-cpp top directory):
python amalgate.py
"""
import os
import os.path
import sys

class AmalgamationFile:
    def __init__(self, top_dir):
        self.top_dir = top_dir
        self.blocks = []

    def add_text(self, text):
        if not text.endswith("\n"):
            text += "\n"
        self.blocks.append(text)

    def add_file(self, relative_input_path, wrap_in_comment=False):
        def add_marker(prefix):
            self.add_text("")
            self.add_text("// " + "/"*70)
            self.add_text("// %s of content of file: %s" % (prefix, relative_input_path.replace("\\","/")))
            self.add_text("// " + "/"*70)
            self.add_text("")
        add_marker("Beginning")
        f = open(os.path.join(self.top_dir, relative_input_path), "rt")
        content = f.read()
        if wrap_in_comment:
            content = "/*\n" + content + "\n*/"
        self.add_text(content)
        f.close()
        add_marker("End")
        self.add_text("\n\n\n\n")

    def get_value(self):
        return "".join(self.blocks).replace("\r\n","\n")

    def write_to(self, output_path):
        output_dir = os.path.dirname(output_path)
        if output_dir and not os.path.isdir(output_dir):
            os.makedirs(output_dir)
        f = open(output_path, "wb")
        f.write(str.encode(self.get_value(), 'UTF-8'))
        f.close()

def amalgamate_source(source_top_dir=None,
                       target_source_path=None,
                       header_include_path=None):
    """Produces amalgated source.
       Parameters:
           source_top_dir: top-directory
           target_source_path: output .cpp path
           header_include_path: generated header path relative to target_source_path.
    """
    print("Amalgating header...")
    header = AmalgamationFile(source_top_dir)
    header.add_text("/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).")
    header.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
    header.add_file("LICENSE", wrap_in_comment=True)
    header.add_text("#ifndef JSON_AMALGATED_H_INCLUDED")
    header.add_text("# define JSON_AMALGATED_H_INCLUDED")
    header.add_text("/// If defined, indicates that the source file is amalgated")
    header.add_text("/// to prevent private header inclusion.")
    header.add_text("#define JSON_IS_AMALGAMATION")
    header.add_file("include/json/version.h")
    #header.add_file("include/json/allocator.h") # Not available here.
    header.add_file("include/json/config.h")
    header.add_file("include/json/forwards.h")
    header.add_file("include/json/features.h")
    header.add_file("include/json/value.h")
    header.add_file("include/json/reader.h")
    header.add_file("include/json/writer.h")
    header.add_file("include/json/assertions.h")
    header.add_text("#endif //ifndef JSON_AMALGATED_H_INCLUDED")

    target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
    print("Writing amalgated header to %r" % target_header_path)
    header.write_to(target_header_path)

    base, ext = os.path.splitext(header_include_path)
    forward_header_include_path = base + "-forwards" + ext
    print("Amalgating forward header...")
    header = AmalgamationFile(source_top_dir)
    header.add_text("/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).")
    header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path)
    header.add_text("/// This header provides forward declaration for all JsonCpp types.")
    header.add_file("LICENSE", wrap_in_comment=True)
    header.add_text("#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
    header.add_text("# define JSON_FORWARD_AMALGATED_H_INCLUDED")
    header.add_text("/// If defined, indicates that the source file is amalgated")
    header.add_text("/// to prevent private header inclusion.")
    header.add_text("#define JSON_IS_AMALGAMATION")
    header.add_file("include/json/config.h")
    header.add_file("include/json/forwards.h")
    header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")

    target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
                                               forward_header_include_path)
    print("Writing amalgated forward header to %r" % target_forward_header_path)
    header.write_to(target_forward_header_path)

    print("Amalgating source...")
    source = AmalgamationFile(source_top_dir)
    source.add_text("/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).")
    source.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
    source.add_file("LICENSE", wrap_in_comment=True)
    source.add_text("")
    source.add_text('#include "%s"' % header_include_path)
    source.add_text("""
#ifndef JSON_IS_AMALGAMATION
#error "Compile with -I PATH_TO_JSON_DIRECTORY"
#endif
""")
    source.add_text("")
    lib_json = "src/lib_json"
    source.add_file(os.path.join(lib_json, "json_tool.h"))
    source.add_file(os.path.join(lib_json, "json_reader.cpp"))
    source.add_file(os.path.join(lib_json, "json_valueiterator.inl"))
    source.add_file(os.path.join(lib_json, "json_value.cpp"))
    source.add_file(os.path.join(lib_json, "json_writer.cpp"))

    print("Writing amalgated source to %r" % target_source_path)
    source.write_to(target_source_path)

def main():
    usage = """%prog [options]
Generate a single amalgated source and header file from the sources.
"""
    from optparse import OptionParser
    parser = OptionParser(usage=usage)
    parser.allow_interspersed_args = False
    parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
        help="""Output .cpp source path. [Default: %default]""")
    parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
        help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""")
    parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(),
        help="""Source top-directory. [Default: %default]""")
    parser.enable_interspersed_args()
    options, args = parser.parse_args()

    msg = amalgamate_source(source_top_dir=options.top_dir,
                             target_source_path=options.target_source_path,
                             header_include_path=options.header_include_path)
    if msg:
        sys.stderr.write(msg + "\n")
        sys.exit(1)
    else:
        print("Source succesfully amalagated")

if __name__ == "__main__":
    main()