blob: 37ed32ebf55d0abbfd4b1e86e329f648fd23be22 [file] [log] [blame]
#!/usr/bin/python3 -i
#
# Copyright 2013-2023 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
import re
from generator import OutputGenerator, write
from parse_dependency import dependencyLanguageSpecMacros
def interfaceDocSortKey(item):
if item == None:
return '\0'
else:
return item.casefold()
class InterfaceDocGenerator(OutputGenerator):
"""InterfaceDocGenerator - subclass of OutputGenerator.
Generates AsciiDoc includes of the interfaces added by a an API version
or extension."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.features = []
def beginFile(self, genOpts):
OutputGenerator.beginFile(self, genOpts)
# Create subdirectory, if needed
self.makeDir(self.genOpts.directory)
def beginFeature(self, interface, emit):
# Start processing in superclass
OutputGenerator.beginFeature(self, interface, emit)
self.features.append( self.featureName )
def endFeature(self):
# Finish processing in superclass
OutputGenerator.endFeature(self)
def writeNewInterfaces(self, feature, key, title, markup, fp):
dict = self.featureDictionary[feature][key]
parentmarkup = markup
if key == 'enumconstant':
parentmarkup = 'elink:'
if dict:
write('=== ' + title, file=fp)
write('',file=fp)
# Loop through required blocks, sorted so they start with "core" features
for required in sorted(dict, key = interfaceDocSortKey):
# 'required' may be a boolean expression of extension
# names.
# Currently this syntax is the same as asciidoc conditional
# syntax, but will eventually become more complex.
if required is not None:
# Rewrite with spec macros and xrefs applied to names
requiredlink = dependencyLanguageSpecMacros(required)
# @@ A better approach would be to actually evaluate the
# logical expression at generation time.
# If the extensions required are not in the spec build,
# then do not include these requirements.
# This would support arbitrarily complex expressions,
# unlike asciidoc ifdef syntax.
write('ifdef::' + required + '[]', file=fp)
write(f'If {requiredlink} is supported:', file=fp)
write('',file=fp)
# Commands are relatively straightforward
if key == 'command':
for api in sorted(dict[required]):
write(' * ' + markup + api, file=fp)
# Types and constants are potentially parented, so need to handle that
else:
# Loop through parents, sorted so they start with unparented items
for parent in sorted(dict[required], key = interfaceDocSortKey):
parentstring = ''
if parent:
parentstring = parentmarkup + (', ' + markup).join(parent.split(','))
write(' * Extending ' + parentstring + ':', file=fp)
for api in sorted(dict[required][parent]):
write(' ** ' + markup + api, file=fp)
else:
for api in sorted(dict[required][parent]):
write(' * ' + markup + api, file=fp)
if required is not None:
write('endif::' + required + '[]', file=fp)
write('',file=fp)
def makeInterfaceFile(self, feature):
"""Generate a file containing feature interface documentation in
asciidoctor markup form.
- feature - name of the feature being generated"""
filename = feature + self.genOpts.conventions.file_suffix
fp = open(self.genOpts.directory + '/' + filename, 'w', encoding='utf-8')
# Write out the lists of new interfaces added by the feature
self.writeNewInterfaces(feature, 'define', 'New Macros', 'dlink:', fp)
self.writeNewInterfaces(feature, 'basetype', 'New Base Types', 'basetype:',fp)
self.writeNewInterfaces(feature, 'handle', 'New Object Types', 'slink:', fp)
self.writeNewInterfaces(feature, 'command', 'New Commands', 'flink:', fp)
self.writeNewInterfaces(feature, 'struct', 'New Structures', 'slink:', fp)
self.writeNewInterfaces(feature, 'union', 'New Unions', 'slink:', fp)
self.writeNewInterfaces(feature, 'funcpointer', 'New Function Pointers','tlink:', fp)
self.writeNewInterfaces(feature, 'enum', 'New Enums', 'elink:', fp)
self.writeNewInterfaces(feature, 'bitmask', 'New Bitmasks', 'tlink:', fp)
self.writeNewInterfaces(feature, 'include', 'New Headers', 'code:', fp)
self.writeNewInterfaces(feature, 'enumconstant','New Enum Constants', 'ename:', fp)
fp.close()
def endFile(self):
# Generate metadoc feature files, in refpage and non-refpage form
for feature in self.features:
self.makeInterfaceFile(feature)
OutputGenerator.endFile(self)