summaryrefslogtreecommitdiff
path: root/registry/vulkan/scripts/Retired/fixupRef.py
blob: 4a9b792a309637448c1ea1b6c8baed4f753e95f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#!/usr/bin/python3
#
# Copyright 2016-2021 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0

# fixupRef.py - replace old // refBegin .. // refEnd syntax with new
# open block syntax
#
# Usage: fixupRef.py [-outdir path] [-overwrite] files

from reflib import *
from vkapi import *
import argparse, copy, io, os, pdb, re, string, sys

# Return 'None' for None, the string otherwise
def noneStr(str):
    if str == None:
        return '(None)'
    else:
        return str

# Escape single quotes in a string for asciidoc
def escapeQuote(str):
    return str.replace("'", "\'")

# Start a refpage open block
def openBlock(pi, fp):
    if pi.refs != '':
        print("[open,refpage='" + pi.name +
              "',desc='" + pi.desc +
              "',type='" + pi.type +
              "',xrefs='" + pi.refs + "']",
              file=fp)
    else:
        print("[open,refpage='" + pi.name +
              "',desc='" + pi.desc +
              "',type='" + pi.type + "']",
              file=fp)
    print('--', file=fp)

# End a refpage open block
def closeBlock(pi, fp):
    print('--', file=fp)
    # Just for finding block ends while debugging
    # print("// end [open,refpage='" + pi.name + "']", file=fp)

# Replace old // refBegin .. // refEnd references in an asciidoc
# file with open blocks, per # ??? .
#   specFile - filename to extract from
#   outDir - output directory to write updated file to, if not overwritten
#   overwrite - True if the file should be overwritten in place
#   skipped - set of filenames containing commands which weren't
#       rewritten with open blocks (e.g. enums). Updated in place.
def replaceRef(specFile, outDir, overwrite = False, skipped = set()):
    file = loadFile(specFile)
    if file == None:
        return

    # Save the path to this file for later use in rewriting relative includes
    specDir = os.path.dirname(os.path.abspath(specFile))

    pageMap = findRefs(file)
    logDiag(specFile + ': found', len(pageMap.keys()), 'potential pages')

    sys.stderr.flush()

    # Fix up references in pageMap
    fixupRefs(pageMap, specFile, file)

    # Map the page info dictionary into a dictionary of actions
    # keyed by line number they're performed on/after:
    #   'action' : 'begin' or 'end'. What to do on a refBegin or refEnd line
    #   'replace': True if this line needs to be replaced
    #   'name'   : Name of the ref page being defined
    #   'desc'   : One-line description of the ref page being defined
    #   'type'   : Type of the ref page being defined, 'structs', 'protos', etc.
    #   'refs'   : Space-separated string of crossreferenced pages

    actions = { }

    for name in pageMap.keys():
        pi = pageMap[name]

        # Cleanup parameters for output
        pi.name = noneStr(pi.name)
        pi.desc = escapeQuote(noneStr(pi.desc))

        if pi.extractPage:
            if (file[pi.begin][0:11] == '// refBegin'):
                # Replace line
                actions[pi.begin] = {
                    'action'   : 'begin',
                    'replace'  : True,
                    'pageinfo' : pi
                }
            else:
                # Insert line
                actions[pi.begin] = {
                    'action'   : 'begin',
                    'replace'  : False,
                    'pageinfo' : pi
                }

            if (file[pi.end][0:9] == '// refEnd'):
                # Replace line
                actions[pi.end] = {
                    'action'   : 'end',
                    'replace'  : True,
                    'pageinfo' : pi
                }
            else:
                # Insert line
                actions[pi.end] = {
                    'action'   : 'end',
                    'replace'  : False,
                    'pageinfo' : pi
                }
        else:
            logWarn('Skipping replacement for', pi.name, 'at', specFile,
                    'line', pi.begin)
            print('Skipping replacement for', pi.name, 'at', specFile,
                  'line', pi.begin)
            printPageInfo(pi, file)
            skipped.add(specFile)

    if overwrite:
        pageName = specFile
    else:
        pageName = outDir + '/' + os.path.basename(specFile)

    fp = open(pageName, 'w', encoding='utf-8')

    line = 0
    for text in file:
        if line in actions.keys():
            action = actions[line]['action']
            replace = actions[line]['replace']
            pi = actions[line]['pageinfo']

            logDiag('ACTION:', action, 'REPLACE:', replace, 'at line', line)
            logDiag('PageInfo of action:')
            printPageInfo(pi, file)

            if action == 'begin':
                openBlock(pi, fp)
                if not replace:
                    print(text, file=fp, end='')
            elif action == 'end':
                if not replace:
                    print(text, file=fp, end='')
                closeBlock(pi, fp)
            else:
                print('ERROR: unrecognized action:', action, 'in',
                      specFile, 'at line', line)
                print(text, file=fp, end='')
        else:
            print(text, file=fp, end='')
        line = line + 1

    fp.close()

    #for line in sorted(actions.keys()):
    #    action = actions[line]
    #    print('action at line', line, '\t',
    #          action[0], action[1], action[2])

if __name__ == '__main__':
    global genDict
    genDict = {}

    parser = argparse.ArgumentParser()

    parser.add_argument('-diag', action='store', dest='diagFile',
                        help='Set the diagnostic file')
    parser.add_argument('-warn', action='store', dest='warnFile',
                        help='Set the warning file')
    parser.add_argument('-log', action='store', dest='logFile',
                        help='Set the log file for both diagnostics and warnings')
    parser.add_argument('-outdir', action='store', dest='outDir',
                        default='out',
                        help='Set the base directory in which pages are generated')
    parser.add_argument('-overwrite', action='store_true',
                        help='Overwrite input filenames instead of writing different output filenames')
    parser.add_argument('files', metavar='filename', nargs='*',
                        help='a filename to extract ref pages from')
    parser.add_argument('--version', action='version', version='%(prog)s 1.0')

    results = parser.parse_args()

    setLogFile(True,  True, results.logFile)
    setLogFile(True, False, results.diagFile)
    setLogFile(False, True, results.warnFile)

    skipped = set()
    for file in results.files:
        replaceRef(file, results.outDir, results.overwrite, skipped)

    if len(skipped) > 0:
        print('Files containing skipped feature blocks:')
        for file in sorted(skipped):
            print('\t' + file)