Loading core/tasks/product-graph.mk +96 −20 Original line number Diff line number Diff line Loading @@ -14,8 +14,31 @@ # limitations under the License. # # the foreach and the if remove the single space entries that creep in because of the evals define gather-all-products $(sort $(foreach p, \ $(eval _all_products_visited := ) $(call all-products-inner, $(ALL_PRODUCTS)) \ , $(if $(strip $(p)),$(strip $(p)),)) \ ) endef define all-products-inner $(foreach p,$(1),\ $(if $(filter $(p),$(_all_products_visited)),, \ $(p) \ $(eval _all_products_visited += $(p)) \ $(call all-products-inner, $(PRODUCTS.$(strip $(p)).INHERITS_FROM)) ) \ ) endef this_makefile := build/core/tasks/product-graph.mk products_svg := $(OUT_DIR)/products.svg products_pdf := $(OUT_DIR)/products.pdf products_graph := $(products_pdf:%.pdf=%.dot) products_graph := $(OUT_DIR)/products.dot ifeq ($(strip $(ANDROID_PRODUCT_GRAPH)),) products_list := $(INTERNAL_PRODUCT) else Loading @@ -26,39 +49,92 @@ products_list := $(foreach prod,$(ANDROID_PRODUCT_GRAPH),$(call resolve-short-pr endif endif $(products_graph): PRIVATE_PRODUCTS := $(products_list) really_all_products := $(call gather-all-products) $(products_graph): @echo Product graph DOT: $@ for $(PRIVATE_PRODUCTS) $(products_graph): PRIVATE_PRODUCTS := $(really_all_products) $(products_graph): PRIVATE_PRODUCTS_FILTER := $(products_list) $(products_graph): $(this_makefile) @echo Product graph DOT: $@ for $(PRIVATE_PRODUCTS_FILTER) $(hide) ( \ echo 'digraph {'; \ echo 'graph [ ratio=.5 ];'; \ $(foreach p,$(ALL_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), \ echo \"$(d)\" -\> \"$(p)\";)) \ $(foreach prod, \ $(sort $(foreach p,$(ALL_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), $(d))) \ $(foreach p,$(ALL_PRODUCTS),$(p))), \ $(foreach p,$(PRIVATE_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), echo \"$(d)\" -\> \"$(p)\";)) \ $(foreach prod, $(PRIVATE_PRODUCTS), \ echo \"$(prod)\" [ \ label=\"$(dir $(prod))\\n$(notdir $(prod))\\n\\n$(PRODUCTS.$(strip $(prod)).PRODUCT_MODEL)\\n$(PRODUCTS.$(strip $(prod)).PRODUCT_DEVICE)\" \ $(if $(filter $(prod),$(PRIVATE_PRODUCTS)), \ style=\"filled\" fillcolor=\"#FFFDB0\",) \ $(if $(filter $(prod),$(PRIVATE_PRODUCTS_FILTER)), style=\"filled\" fillcolor=\"#FFFDB0\",) \ fontcolor=\"darkblue\" href=\"products/$(prod).html\" \ ];) \ echo '}' \ ) \ | ./build/tools/filter-product-graph.py $(PRIVATE_PRODUCTS) \ | ./build/tools/filter-product-graph.py $(PRIVATE_PRODUCTS_FILTER) \ > $@ # This rule doesn't include any nodes that don't inherit from # anything or don't have anything inherit from them, to make the # graph more readable. To add that, add this line to the rule # below: # $(foreach p,$(ALL_PRODUCTS), echo \"$(p)\";) \ # Evaluates to the name of the product file # $(1) product file define product-debug-filename $(OUT_DIR)/products/$(strip $(1)).html endef # Makes a rule for the product debug info # $(1) product file define transform-product-debug $(OUT_DIR)/products/$(strip $(1)).txt: $(this_makefile) @echo Product debug info file: $$@ $(hide) rm -f $$@ $(hide) mkdir -p $$(dir $$@) $(hide) echo 'FILE=$(strip $(1))' >> $$@ $(hide) echo 'PRODUCT_NAME=$$(PRODUCTS.$(strip $(1)).PRODUCT_NAME)' >> $$@ $(hide) echo 'PRODUCT_MODEL=$$(PRODUCTS.$(strip $(1)).PRODUCT_MODEL)' >> $$@ $(hide) echo 'PRODUCT_LOCALES=$$(PRODUCTS.$(strip $(1)).PRODUCT_LOCALES)' >> $$@ $(hide) echo 'PRODUCT_AAPT_CONFIG=$$(PRODUCTS.$(strip $(1)).PRODUCT_AAPT_CONFIG)' >> $$@ $(hide) echo 'PRODUCT_AAPT_PREF_CONFIG=$$(PRODUCTS.$(strip $(1)).PRODUCT_AAPT_PREF_CONFIG)' >> $$@ $(hide) echo 'PRODUCT_PACKAGES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGES)' >> $$@ $(hide) echo 'PRODUCT_DEVICE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEVICE)' >> $$@ $(hide) echo 'PRODUCT_MANUFACTURER=$$(PRODUCTS.$(strip $(1)).PRODUCT_MANUFACTURER)' >> $$@ $(hide) echo 'PRODUCT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PROPERTY_OVERRIDES)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_PROPERTY_OVERRIDES)' >> $$@ $(hide) echo 'PRODUCT_CHARACTERISTICS=$$(PRODUCTS.$(strip $(1)).PRODUCT_CHARACTERISTICS)' >> $$@ $(hide) echo 'PRODUCT_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_COPY_FILES)' >> $$@ $(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_OTA_PUBLIC_KEYS)' >> $$@ $(hide) echo 'PRODUCT_EXTRA_RECOVERY_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_EXTRA_RECOVERY_KEYS)' >> $$@ $(hide) echo 'PRODUCT_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGE_OVERLAYS)' >> $$@ $(hide) echo 'DEVICE_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).DEVICE_PACKAGE_OVERLAYS)' >> $$@ $(hide) echo 'PRODUCT_TAGS=$$(PRODUCTS.$(strip $(1)).PRODUCT_TAGS)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_NAME=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_NAME)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_FILES)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_COPY_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_MODULES)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_DOC_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_DOC_MODULES)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_WIFI_CHANNELS=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_WIFI_CHANNELS)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_DEV_CERTIFICATE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_DEV_CERTIFICATE)' >> $$@ $(hide) echo 'PRODUCT_RESTRICT_VENDOR_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_RESTRICT_VENDOR_FILES)' >> $$@ $(hide) echo 'PRODUCT_FACTORY_RAMDISK_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_FACTORY_RAMDISK_MODULES)' >> $$@ $(hide) echo 'PRODUCT_VENDOR_KERNEL_HEADERS=$$(PRODUCTS.$(strip $(1)).PRODUCT_VENDOR_KERNEL_HEADERS)' >> $$@ $(call product-debug-filename, $(p)): \ $(OUT_DIR)/products/$(strip $(1)).txt \ build/tools/product_debug.py \ $(this_makefile) @echo Product debug html file: $$@ $(hide) mkdir -p $$(dir $$@) $(hide) cat $$< | build/tools/product_debug.py > $$@ endef product_debug_files:= $(foreach p,$(really_all_products), \ $(eval $(call transform-product-debug, $(p))) \ $(eval product_debug_files += $(call product-debug-filename, $(p))) \ ) $(products_pdf): $(products_graph) @echo Product graph PDF: $@ dot -Tpdf -Nshape=box -o $@ $< product-graph: $(products_pdf) $(products_svg): $(products_graph) $(product_debug_files) @echo Product graph SVG: $@ dot -Tsvg -Nshape=box -o $@ $< product-graph: $(products_pdf) $(products_svg) tools/product_debug.py 0 → 100755 +160 −0 Original line number Diff line number Diff line #!/usr/bin/env python # # Copyright (C) 2012 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import re import sys def break_lines(key, val): # these don't get split if key in ("PRODUCT_MODEL"): return (key,val) return (key, "\n".join(val.split())) def split_line(line): words = line.split("=", 1) if len(words) == 1: return (words[0], "") else: return (words[0], words[1]) def sort_lines(text): lines = text.split() lines.sort() return "\n".join(lines) def parse_variables(lines): return [split_line(line) for line in lines if line.strip()] def render_variables(variables): variables = dict(variables) del variables["FILE"] variables = list(variables.iteritems()) variables.sort(lambda a, b: cmp(a[0], b[0])) return ("<table id='variables'>" + "\n".join([ "<tr><th>%(key)s</th><td>%(val)s</td></tr>" % { "key": key, "val": val } for key,val in variables]) +"</table>") def linkify_inherit(variables, text, func_name): groups = re.split("(\\$\\(call " + func_name + ",.*\\))", text) result = "" for i in range(0,len(groups)/2): i = i * 2 result = result + groups[i] s = groups[i+1] href = s.split(",", 1)[1].strip()[:-1] href = href.replace("$(SRC_TARGET_DIR)", "build/target") href = ("../" * variables["FILE"].count("/")) + href + ".html" result = result + "<a href=\"%s\">%s</a>" % (href,s) result = result + groups[-1] return result def render_original(variables, text): text = linkify_inherit(variables, text, "inherit-product") text = linkify_inherit(variables, text, "inherit-product-if-exists") return text def read_file(fn): f = file(fn) text = f.read() f.close() return text def main(argv): # read the variables lines = sys.stdin.readlines() variables = parse_variables(lines) # format the variables variables = [break_lines(key,val) for key,val in variables] # now it's a dict variables = dict(variables) sorted_vars = ( "PRODUCT_COPY_FILES", "PRODUCT_PACKAGES", "PRODUCT_LOCALES", "PRODUCT_FACTORY_RAMDISK_MODULES", "PRODUCT_PROPERTY_OVERRIDES", ) for key in sorted_vars: variables[key] = sort_lines(variables[key]) # the original file original = read_file(variables["FILE"]) # formatting values = dict(variables) values.update({ "variables": render_variables(variables), "original": render_original(variables, original), }) print """<html> <head> <title>%(FILE)s</title> <style type="text/css"> body { font-family: Helvetica, Arial, sans-serif; padding-bottom: 20px; } #variables { border-collapse: collapse; } #variables th, #variables td { vertical-align: top; text-align: left; border-top: 1px solid #c5cdde; border-bottom: 1px solid #c5cdde; padding: 2px 10px 2px 10px; } #variables th { font-size: 10pt; background-color: #e2ecff } #variables td { background-color: #ebf2ff; white-space: pre; font-size: 10pt; } #original { background-color: #ebf2ff; border-top: 1px solid #c5cdde; border-bottom: 1px solid #c5cdde; padding: 2px 10px 2px 10px; white-space: pre; font-size: 10pt; } </style> </head> <body> <h1>%(FILE)s</h1> <a href="#Original">Original</a> <a href="#Variables">Variables</a> <h2><a name="Original"></a>Original</h2> <div id="original">%(original)s</div> <h2><a name="Variables"></a>Variables</h2> %(variables)s </body> </html> """ % values if __name__ == "__main__": main(sys.argv) Loading
core/tasks/product-graph.mk +96 −20 Original line number Diff line number Diff line Loading @@ -14,8 +14,31 @@ # limitations under the License. # # the foreach and the if remove the single space entries that creep in because of the evals define gather-all-products $(sort $(foreach p, \ $(eval _all_products_visited := ) $(call all-products-inner, $(ALL_PRODUCTS)) \ , $(if $(strip $(p)),$(strip $(p)),)) \ ) endef define all-products-inner $(foreach p,$(1),\ $(if $(filter $(p),$(_all_products_visited)),, \ $(p) \ $(eval _all_products_visited += $(p)) \ $(call all-products-inner, $(PRODUCTS.$(strip $(p)).INHERITS_FROM)) ) \ ) endef this_makefile := build/core/tasks/product-graph.mk products_svg := $(OUT_DIR)/products.svg products_pdf := $(OUT_DIR)/products.pdf products_graph := $(products_pdf:%.pdf=%.dot) products_graph := $(OUT_DIR)/products.dot ifeq ($(strip $(ANDROID_PRODUCT_GRAPH)),) products_list := $(INTERNAL_PRODUCT) else Loading @@ -26,39 +49,92 @@ products_list := $(foreach prod,$(ANDROID_PRODUCT_GRAPH),$(call resolve-short-pr endif endif $(products_graph): PRIVATE_PRODUCTS := $(products_list) really_all_products := $(call gather-all-products) $(products_graph): @echo Product graph DOT: $@ for $(PRIVATE_PRODUCTS) $(products_graph): PRIVATE_PRODUCTS := $(really_all_products) $(products_graph): PRIVATE_PRODUCTS_FILTER := $(products_list) $(products_graph): $(this_makefile) @echo Product graph DOT: $@ for $(PRIVATE_PRODUCTS_FILTER) $(hide) ( \ echo 'digraph {'; \ echo 'graph [ ratio=.5 ];'; \ $(foreach p,$(ALL_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), \ echo \"$(d)\" -\> \"$(p)\";)) \ $(foreach prod, \ $(sort $(foreach p,$(ALL_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), $(d))) \ $(foreach p,$(ALL_PRODUCTS),$(p))), \ $(foreach p,$(PRIVATE_PRODUCTS), \ $(foreach d,$(PRODUCTS.$(strip $(p)).INHERITS_FROM), echo \"$(d)\" -\> \"$(p)\";)) \ $(foreach prod, $(PRIVATE_PRODUCTS), \ echo \"$(prod)\" [ \ label=\"$(dir $(prod))\\n$(notdir $(prod))\\n\\n$(PRODUCTS.$(strip $(prod)).PRODUCT_MODEL)\\n$(PRODUCTS.$(strip $(prod)).PRODUCT_DEVICE)\" \ $(if $(filter $(prod),$(PRIVATE_PRODUCTS)), \ style=\"filled\" fillcolor=\"#FFFDB0\",) \ $(if $(filter $(prod),$(PRIVATE_PRODUCTS_FILTER)), style=\"filled\" fillcolor=\"#FFFDB0\",) \ fontcolor=\"darkblue\" href=\"products/$(prod).html\" \ ];) \ echo '}' \ ) \ | ./build/tools/filter-product-graph.py $(PRIVATE_PRODUCTS) \ | ./build/tools/filter-product-graph.py $(PRIVATE_PRODUCTS_FILTER) \ > $@ # This rule doesn't include any nodes that don't inherit from # anything or don't have anything inherit from them, to make the # graph more readable. To add that, add this line to the rule # below: # $(foreach p,$(ALL_PRODUCTS), echo \"$(p)\";) \ # Evaluates to the name of the product file # $(1) product file define product-debug-filename $(OUT_DIR)/products/$(strip $(1)).html endef # Makes a rule for the product debug info # $(1) product file define transform-product-debug $(OUT_DIR)/products/$(strip $(1)).txt: $(this_makefile) @echo Product debug info file: $$@ $(hide) rm -f $$@ $(hide) mkdir -p $$(dir $$@) $(hide) echo 'FILE=$(strip $(1))' >> $$@ $(hide) echo 'PRODUCT_NAME=$$(PRODUCTS.$(strip $(1)).PRODUCT_NAME)' >> $$@ $(hide) echo 'PRODUCT_MODEL=$$(PRODUCTS.$(strip $(1)).PRODUCT_MODEL)' >> $$@ $(hide) echo 'PRODUCT_LOCALES=$$(PRODUCTS.$(strip $(1)).PRODUCT_LOCALES)' >> $$@ $(hide) echo 'PRODUCT_AAPT_CONFIG=$$(PRODUCTS.$(strip $(1)).PRODUCT_AAPT_CONFIG)' >> $$@ $(hide) echo 'PRODUCT_AAPT_PREF_CONFIG=$$(PRODUCTS.$(strip $(1)).PRODUCT_AAPT_PREF_CONFIG)' >> $$@ $(hide) echo 'PRODUCT_PACKAGES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGES)' >> $$@ $(hide) echo 'PRODUCT_DEVICE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEVICE)' >> $$@ $(hide) echo 'PRODUCT_MANUFACTURER=$$(PRODUCTS.$(strip $(1)).PRODUCT_MANUFACTURER)' >> $$@ $(hide) echo 'PRODUCT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PROPERTY_OVERRIDES)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_PROPERTY_OVERRIDES)' >> $$@ $(hide) echo 'PRODUCT_CHARACTERISTICS=$$(PRODUCTS.$(strip $(1)).PRODUCT_CHARACTERISTICS)' >> $$@ $(hide) echo 'PRODUCT_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_COPY_FILES)' >> $$@ $(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_OTA_PUBLIC_KEYS)' >> $$@ $(hide) echo 'PRODUCT_EXTRA_RECOVERY_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_EXTRA_RECOVERY_KEYS)' >> $$@ $(hide) echo 'PRODUCT_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGE_OVERLAYS)' >> $$@ $(hide) echo 'DEVICE_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).DEVICE_PACKAGE_OVERLAYS)' >> $$@ $(hide) echo 'PRODUCT_TAGS=$$(PRODUCTS.$(strip $(1)).PRODUCT_TAGS)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_NAME=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_NAME)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_FILES)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_COPY_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_MODULES)' >> $$@ $(hide) echo 'PRODUCT_SDK_ADDON_DOC_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_DOC_MODULES)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_WIFI_CHANNELS=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_WIFI_CHANNELS)' >> $$@ $(hide) echo 'PRODUCT_DEFAULT_DEV_CERTIFICATE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_DEV_CERTIFICATE)' >> $$@ $(hide) echo 'PRODUCT_RESTRICT_VENDOR_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_RESTRICT_VENDOR_FILES)' >> $$@ $(hide) echo 'PRODUCT_FACTORY_RAMDISK_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_FACTORY_RAMDISK_MODULES)' >> $$@ $(hide) echo 'PRODUCT_VENDOR_KERNEL_HEADERS=$$(PRODUCTS.$(strip $(1)).PRODUCT_VENDOR_KERNEL_HEADERS)' >> $$@ $(call product-debug-filename, $(p)): \ $(OUT_DIR)/products/$(strip $(1)).txt \ build/tools/product_debug.py \ $(this_makefile) @echo Product debug html file: $$@ $(hide) mkdir -p $$(dir $$@) $(hide) cat $$< | build/tools/product_debug.py > $$@ endef product_debug_files:= $(foreach p,$(really_all_products), \ $(eval $(call transform-product-debug, $(p))) \ $(eval product_debug_files += $(call product-debug-filename, $(p))) \ ) $(products_pdf): $(products_graph) @echo Product graph PDF: $@ dot -Tpdf -Nshape=box -o $@ $< product-graph: $(products_pdf) $(products_svg): $(products_graph) $(product_debug_files) @echo Product graph SVG: $@ dot -Tsvg -Nshape=box -o $@ $< product-graph: $(products_pdf) $(products_svg)
tools/product_debug.py 0 → 100755 +160 −0 Original line number Diff line number Diff line #!/usr/bin/env python # # Copyright (C) 2012 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import re import sys def break_lines(key, val): # these don't get split if key in ("PRODUCT_MODEL"): return (key,val) return (key, "\n".join(val.split())) def split_line(line): words = line.split("=", 1) if len(words) == 1: return (words[0], "") else: return (words[0], words[1]) def sort_lines(text): lines = text.split() lines.sort() return "\n".join(lines) def parse_variables(lines): return [split_line(line) for line in lines if line.strip()] def render_variables(variables): variables = dict(variables) del variables["FILE"] variables = list(variables.iteritems()) variables.sort(lambda a, b: cmp(a[0], b[0])) return ("<table id='variables'>" + "\n".join([ "<tr><th>%(key)s</th><td>%(val)s</td></tr>" % { "key": key, "val": val } for key,val in variables]) +"</table>") def linkify_inherit(variables, text, func_name): groups = re.split("(\\$\\(call " + func_name + ",.*\\))", text) result = "" for i in range(0,len(groups)/2): i = i * 2 result = result + groups[i] s = groups[i+1] href = s.split(",", 1)[1].strip()[:-1] href = href.replace("$(SRC_TARGET_DIR)", "build/target") href = ("../" * variables["FILE"].count("/")) + href + ".html" result = result + "<a href=\"%s\">%s</a>" % (href,s) result = result + groups[-1] return result def render_original(variables, text): text = linkify_inherit(variables, text, "inherit-product") text = linkify_inherit(variables, text, "inherit-product-if-exists") return text def read_file(fn): f = file(fn) text = f.read() f.close() return text def main(argv): # read the variables lines = sys.stdin.readlines() variables = parse_variables(lines) # format the variables variables = [break_lines(key,val) for key,val in variables] # now it's a dict variables = dict(variables) sorted_vars = ( "PRODUCT_COPY_FILES", "PRODUCT_PACKAGES", "PRODUCT_LOCALES", "PRODUCT_FACTORY_RAMDISK_MODULES", "PRODUCT_PROPERTY_OVERRIDES", ) for key in sorted_vars: variables[key] = sort_lines(variables[key]) # the original file original = read_file(variables["FILE"]) # formatting values = dict(variables) values.update({ "variables": render_variables(variables), "original": render_original(variables, original), }) print """<html> <head> <title>%(FILE)s</title> <style type="text/css"> body { font-family: Helvetica, Arial, sans-serif; padding-bottom: 20px; } #variables { border-collapse: collapse; } #variables th, #variables td { vertical-align: top; text-align: left; border-top: 1px solid #c5cdde; border-bottom: 1px solid #c5cdde; padding: 2px 10px 2px 10px; } #variables th { font-size: 10pt; background-color: #e2ecff } #variables td { background-color: #ebf2ff; white-space: pre; font-size: 10pt; } #original { background-color: #ebf2ff; border-top: 1px solid #c5cdde; border-bottom: 1px solid #c5cdde; padding: 2px 10px 2px 10px; white-space: pre; font-size: 10pt; } </style> </head> <body> <h1>%(FILE)s</h1> <a href="#Original">Original</a> <a href="#Variables">Variables</a> <h2><a name="Original"></a>Original</h2> <div id="original">%(original)s</div> <h2><a name="Variables"></a>Variables</h2> %(variables)s </body> </html> """ % values if __name__ == "__main__": main(sys.argv)