• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2#
3# Copyright 2016-2021 The Khronos Group Inc.
4#
5# SPDX-License-Identifier: Apache-2.0
6
7# Retroactively insert markup in show both 1.1 core features and KHR
8# extensions they were promoted from.
9
10# Usage: promote.py [-overwrite] [-out dir] [-suffix str] files
11#   -overwrite updates in place (can be risky, make sure there are backups)
12#   -out specifies directory to create output file in, default 'out'
13#   -suffix specifies suffix to add to output files, default ''
14#   files are asciidoc source files from the Vulkan spec to reflow.
15
16# For error and file-loading interfaces only
17import argparse, copy, os, pdb, re, string, sys
18from reflib import *
19from promoted import *
20
21global anchor
22anchor = 0
23
24def anchorname(anchor):
25    return 'promoted-' + str(anchor)
26
27def printanchor(fp):
28    # Anchor index for navigation
29    global anchor
30
31    print('[[' + anchorname(anchor) + ']]', file=fp)
32    print('This anchor:', anchorname(anchor), file=fp)
33    print('<<' + anchorname(anchor+1) + ', OINK>>', file=fp)
34    anchor = anchor + 1
35
36# promote a core interface and include the extension it was promoted from
37#   line - matching line with 1.1 interface
38#   type - 'protos', 'structs', 'flags', 'enums'
39#   name - interface name
40#   extension - name of extension interface was promoted from
41#   fp - output filename
42def promote(line, type, name, extension, fp):
43    if type == 'protos':
44        # printanchor(fp)
45        print('ifdef::VK_VERSION_1_1[]', file=fp)
46        print(line, file=fp, end='')
47        print('endif::VK_VERSION_1_1[]', file=fp)
48        print('', file=fp)
49        print('ifdef::VK_VERSION_1_1+' + extension +
50              '[or the equivalent command]', file=fp)
51        print('', file=fp)
52        print('ifdef::' + extension + '[]', file=fp)
53        print('include::../api/' + type + '/' + name + 'KHR.txt[]', file=fp)
54        print('endif::' + extension + '[]', file=fp)
55        del promoted[name]
56    elif type == 'structs' or type == 'enums' or type == 'flags' or type == 'handles':
57        # printanchor(fp)
58        print(line, file=fp, end='')
59        print('', file=fp)
60        print('ifdef::' + extension + '[]', file=fp)
61        print('or the equivalent', file=fp)
62        print('', file=fp)
63        print('include::../api/' + type + '/' + name + 'KHR.txt[]', file=fp)
64        print('endif::' + extension + '[]', file=fp)
65        del promoted[name]
66    else:
67        logWarn('Unrecognized promoted type', type, 'for interface', name)
68        print(line, file=fp, end='')
69
70
71def promoteFile(filename, args):
72    logDiag('promote: filename', filename)
73
74    lines = loadFile(filename)
75    if (lines == None):
76        return
77
78    # Output file handle and promote object for this file. There are no race
79    # conditions on overwriting the input, but it is not recommended unless
80    # you have backing store such as git.
81
82    if args.overwrite:
83        outFilename = filename
84    else:
85        outFilename = args.outDir + '/' + os.path.basename(filename) + args.suffix
86
87    try:
88        fp = open(outFilename, 'w', encoding='utf8')
89        True
90    except:
91        logWarn('Cannot open output file', filename, ':', sys.exc_info()[0])
92        return None
93
94    lineno = 0
95    for line in lines:
96        lineno = lineno + 1
97
98        matches = includePat.search(line)
99        if matches != None:
100            type = matches.group('type')
101            name = matches.group('name')
102            if name in promoted:
103                extension = promoted[name]['extension']
104                if extension:
105                    # Promote core interface
106                    promote(line, type, name, promoted[name]['extension'], fp)
107                    continue
108        # Fallthrough
109        print(line, file=fp, end='')
110
111    fp.close()
112
113def promoteAllAdocFiles(folder_to_promote, args):
114    for root, subdirs, files in os.walk(folder_to_promote):
115        for file in files:
116            if file.endswith(".txt"):
117                file_path = os.path.join(root, file)
118                promoteFile(file_path, args)
119        for subdir in subdirs:
120            sub_folder = os.path.join(root, subdir)
121            print('Sub-folder = %s' % sub_folder)
122            if not (subdir.lower() == "scripts") and not (subdir.lower() == "style"):
123                print('   Parsing = %s' % sub_folder)
124                promoteAllAdocFiles(sub_folder, args)
125            else:
126                print('   Skipping = %s' % sub_folder)
127
128# Patterns used to recognize interesting lines in an asciidoc source file.
129# These patterns are only compiled once.
130
131if __name__ == '__main__':
132    parser = argparse.ArgumentParser()
133
134    parser.add_argument('-diag', action='store', dest='diagFile',
135                        help='Set the diagnostic file')
136    parser.add_argument('-warn', action='store', dest='warnFile',
137                        help='Set the warning file')
138    parser.add_argument('-log', action='store', dest='logFile',
139                        help='Set the log file for both diagnostics and warnings')
140    parser.add_argument('-overwrite', action='store_true',
141                        help='Overwrite input filenames instead of writing different output filenames')
142    parser.add_argument('-out', action='store', dest='outDir',
143                        default='out',
144                        help='Set the output directory in which updated files are generated (default: out)')
145    parser.add_argument('-suffix', action='store', dest='suffix',
146                        default='',
147                        help='Set the suffix added to updated file names (default: none)')
148    parser.add_argument('files', metavar='filename', nargs='*',
149                        help='a filename to promote text in')
150    parser.add_argument('--version', action='version', version='%(prog)s 1.0')
151
152    args = parser.parse_args()
153
154    setLogFile(True,  True, args.logFile)
155    setLogFile(True, False, args.diagFile)
156    setLogFile(False, True, args.warnFile)
157
158    if args.overwrite:
159        logWarn('promote.py: will overwrite all input files')
160
161    # If no files are specified, promote the entire specification chapters folder
162    if len(args.files) == 0:
163        folder_to_promote = os.getcwd()
164        folder_to_promote += '/chapters'
165        promoteAllAdocFiles(folder_to_promote, args)
166    else:
167        for file in args.files:
168            promoteFile(file, args)
169
170    print('At end, promoted interfaces remaining:')
171    for key in promoted:
172        if promoted[key]['extension'] != None:
173            print('\t' + key)
174