123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- # Copyright Hans Dembinski 2018 - 2019.
- # Distributed under the Boost Software License, Version 1.0.
- # (See accompanying file LICENSE_1_0.txt or copy at
- # https://www.boost.org/LICENSE_1_0.txt)
- from __future__ import print_function
- import sys
- import xml.etree.ElementTree as ET
- import re
- def log(*args):
- print("post-processing:", *args)
- def select(condition, *tags):
- result = []
- for tag in tags:
- for item in root.iter(tag):
- if condition(item):
- result.append(item)
- return result
- def is_detail(x):
- if x.text is not None:
- if "detail" in x.text:
- return True
- m = re.match("(?:typename)? *([A-Za-z0-9_\:]+)", x.text)
- if m is not None:
- s = m.group(1)
- if s.startswith("detail") or s.endswith("_impl"):
- x.text = s
- return True
- p = x.find("purpose")
- if p is not None:
- return p.text.lower().lstrip().startswith("implementation detail")
- return False
- def is_deprecated(x):
- p = x.find("purpose")
- if p is not None:
- return p.text.lower().lstrip().startswith("deprecated")
- return False
- tree = ET.parse(sys.argv[1])
- root = tree.getroot()
- parent_map = {c:p for p in tree.iter() for c in p}
- unspecified = ET.Element("emphasis")
- unspecified.text = "unspecified"
- # hide all unnamed template parameters, these are used for SFINAE
- for item in select(lambda x: x.get("name") == "", "template-type-parameter"):
- parent = parent_map[item]
- assert parent.tag == "template"
- parent.remove(item)
- parent = parent_map[parent]
- name = parent.get("name")
- if name is None:
- log("removing unnamed template parameter from", parent.tag)
- else:
- log("removing unnamed template parameter from", parent.tag, name)
- # replace any type with "detail" in its name with "unspecified"
- for item in select(is_detail, "type"):
- log("replacing", '"%s"' % item.text, 'with "unspecified"')
- item.clear()
- item.append(unspecified)
- # hide everything that's deprecated
- for item in select(is_deprecated, "typedef"):
- parent = parent_map[item]
- log("removing deprecated", item.tag, item.get("name"), "from", parent.tag, parent.get("name"))
- parent.remove(item)
- # hide private member functions
- for item in select(lambda x: x.get("name") == "private member functions", "method-group"):
- parent = parent_map[item]
- log("removing private member functions from", parent.tag, parent.get("name"))
- parent.remove(item)
- # hide undocumented classes, structs, functions and replace those declared
- # "implementation detail" with typedef to implementation_defined
- for item in select(lambda x:True, "class", "struct", "function"):
- purpose = item.find("purpose")
- if purpose is None:
- parent = parent_map[item]
- log("removing undocumented", item.tag, item.get("name"), "from",
- parent.tag, parent.get("name"))
- if item in parent_map[item]:
- parent_map[item].remove(item)
- elif purpose.text.strip().lower() == "implementation detail":
- log("replacing", item.tag, item.get("name"), "with unspecified typedef")
- name = item.get("name")
- item.clear()
- item.tag = "typedef"
- item.set("name", name)
- type = ET.Element("type")
- type.append(unspecified)
- item.append(type)
- parent_map = {c:p for p in tree.iter() for c in p}
- # hide methods and constructors explicitly declared as "implementation detail"
- for item in select(is_detail, "constructor", "method"):
- name = item.get("name")
- log("removing", (item.tag + " " + name) if name is not None else item.tag,
- "declared as implementation detail")
- parent_map[item].remove(item)
- tree.write(sys.argv[2])
|