Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 1 | #!/usr/bin/env python |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 2 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 3 | """Amalgamate json-cpp library sources into a single source and header file. |
| 4 | |
| 5 | Works with python2.6+ and python3.4+. |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 6 | |
| 7 | Example of invocation (must be invoked from json-cpp top directory): |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 8 | python amalgamate.py |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 9 | """ |
| 10 | import os |
| 11 | import os.path |
| 12 | import sys |
| 13 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 14 | INCLUDE_PATH = "include/json" |
| 15 | SRC_PATH = "src/lib_json" |
| 16 | |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 17 | class AmalgamationFile: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 18 | def __init__(self, top_dir): |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 19 | self.top_dir = top_dir |
| 20 | self.blocks = [] |
| 21 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 22 | def add_text(self, text): |
| 23 | if not text.endswith("\n"): |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 24 | text += "\n" |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 25 | self.blocks.append(text) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 26 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 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") |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 36 | content = f.read() |
| 37 | if wrap_in_comment: |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 38 | content = "/*\n" + content + "\n*/" |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 39 | self.add_text(content) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 40 | f.close() |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 41 | add_marker("End") |
| 42 | self.add_text("\n\n\n\n") |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 43 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 44 | def get_value(self): |
| 45 | return "".join(self.blocks).replace("\r\n","\n") |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 46 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 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')) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 53 | f.close() |
| 54 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 55 | def amalgamate_source(source_top_dir=None, |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 56 | target_source_path=None, |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 57 | header_include_path=None): |
| 58 | """Produces amalgamated source. |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 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 | """ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 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") |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 84 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 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) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 88 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 89 | base, ext = os.path.splitext(header_include_path) |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 90 | forward_header_include_path = base + "-forwards" + ext |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 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, "version.h")) |
| 103 | header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) |
| 104 | header.add_file(os.path.join(INCLUDE_PATH, "config.h")) |
| 105 | header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) |
| 106 | header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 107 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 108 | target_forward_header_path = os.path.join(os.path.dirname(target_source_path), |
| 109 | forward_header_include_path) |
| 110 | print("Writing amalgamated forward header to %r" % target_forward_header_path) |
| 111 | header.write_to(target_forward_header_path) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 112 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 113 | print("Amalgamating source...") |
| 114 | source = AmalgamationFile(source_top_dir) |
| 115 | source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).") |
| 116 | source.add_text('/// It is intended to be used with #include "%s"' % header_include_path) |
| 117 | source.add_file("LICENSE", wrap_in_comment=True) |
| 118 | source.add_text("") |
| 119 | source.add_text('#include "%s"' % header_include_path) |
| 120 | source.add_text(""" |
| 121 | #ifndef JSON_IS_AMALGAMATION |
| 122 | #error "Compile with -I PATH_TO_JSON_DIRECTORY" |
| 123 | #endif |
| 124 | """) |
| 125 | source.add_text("") |
| 126 | source.add_file(os.path.join(SRC_PATH, "json_tool.h")) |
| 127 | source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) |
| 128 | source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) |
| 129 | source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) |
| 130 | source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 131 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 132 | print("Writing amalgamated source to %r" % target_source_path) |
| 133 | source.write_to(target_source_path) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 134 | |
| 135 | def main(): |
| 136 | usage = """%prog [options] |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 137 | Generate a single amalgamated source and header file from the sources. |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 138 | """ |
| 139 | from optparse import OptionParser |
| 140 | parser = OptionParser(usage=usage) |
| 141 | parser.allow_interspersed_args = False |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 142 | parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp", |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 143 | help="""Output .cpp source path. [Default: %default]""") |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 144 | parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h", |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 145 | help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""") |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 146 | parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(), |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 147 | help="""Source top-directory. [Default: %default]""") |
| 148 | parser.enable_interspersed_args() |
| 149 | options, args = parser.parse_args() |
| 150 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 151 | msg = amalgamate_source(source_top_dir=options.top_dir, |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 152 | target_source_path=options.target_source_path, |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 153 | header_include_path=options.header_include_path) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 154 | if msg: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 155 | sys.stderr.write(msg + "\n") |
| 156 | sys.exit(1) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 157 | else: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 158 | print("Source successfully amalgamated") |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 159 | |
| 160 | if __name__ == "__main__": |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 161 | main() |