• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2#
3# Copyright (c) 2016-2018 The Khronos Group Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# fixupRef.py - replace old // refBegin .. // refEnd syntax with new
18# open block syntax
19#
20# Usage: fixupRef.py [-outdir path] [-overwrite] files
21
22from reflib import *
23from vkapi import *
24import argparse, copy, io, os, pdb, re, string, sys
25
26# Return 'None' for None, the string otherwise
27def noneStr(str):
28    if str == None:
29        return '(None)'
30    else:
31        return str
32
33# Escape single quotes in a string for asciidoc
34def escapeQuote(str):
35    return str.replace("'", "\'")
36
37# Start a refpage open block
38def openBlock(pi, fp):
39    if pi.refs != '':
40        print("[open,refpage='" + pi.name +
41              "',desc='" + pi.desc +
42              "',type='" + pi.type +
43              "',xrefs='" + pi.refs + "']",
44              file=fp)
45    else:
46        print("[open,refpage='" + pi.name +
47              "',desc='" + pi.desc +
48              "',type='" + pi.type + "']",
49              file=fp)
50    print('--', file=fp)
51
52# End a refpage open block
53def closeBlock(pi, fp):
54    print('--', file=fp)
55    # Just for finding block ends while debugging
56    # print("// end [open,refpage='" + pi.name + "']", file=fp)
57
58# Replace old // refBegin .. // refEnd references in an asciidoc
59# file with open blocks, per # ??? .
60#   specFile - filename to extract from
61#   outDir - output directory to write updated file to, if not overwritten
62#   overwrite - True if the file should be overwritten in place
63#   skipped - set of filenames containing commands which weren't
64#       rewritten with open blocks (e.g. enums). Updated in place.
65def replaceRef(specFile, outDir, overwrite = False, skipped = set()):
66    file = loadFile(specFile)
67    if file == None:
68        return
69
70    # Save the path to this file for later use in rewriting relative includes
71    specDir = os.path.dirname(os.path.abspath(specFile))
72
73    pageMap = findRefs(file)
74    logDiag(specFile + ': found', len(pageMap.keys()), 'potential pages')
75
76    sys.stderr.flush()
77
78    # Fix up references in pageMap
79    fixupRefs(pageMap, specFile, file)
80
81    # Map the page info dictionary into a dictionary of actions
82    # keyed by line number they're performed on/after:
83    #   'action' : 'begin' or 'end'. What to do on a refBegin or refEnd line
84    #   'replace': True if this line needs to be replaced
85    #   'name'   : Name of the ref page being defined
86    #   'desc'   : One-line description of the ref page being defined
87    #   'type'   : Type of the ref page being defined, 'structs', 'protos', etc.
88    #   'refs'   : Space-separated string of crossreferenced pages
89
90    actions = { }
91
92    for name in pageMap.keys():
93        pi = pageMap[name]
94
95        # Cleanup parameters for output
96        pi.name = noneStr(pi.name)
97        pi.desc = escapeQuote(noneStr(pi.desc))
98
99        if pi.extractPage:
100            if (file[pi.begin][0:11] == '// refBegin'):
101                # Replace line
102                actions[pi.begin] = {
103                    'action'   : 'begin',
104                    'replace'  : True,
105                    'pageinfo' : pi
106                }
107            else:
108                # Insert line
109                actions[pi.begin] = {
110                    'action'   : 'begin',
111                    'replace'  : False,
112                    'pageinfo' : pi
113                }
114
115            if (file[pi.end][0:9] == '// refEnd'):
116                # Replace line
117                actions[pi.end] = {
118                    'action'   : 'end',
119                    'replace'  : True,
120                    'pageinfo' : pi
121                }
122            else:
123                # Insert line
124                actions[pi.end] = {
125                    'action'   : 'end',
126                    'replace'  : False,
127                    'pageinfo' : pi
128                }
129        else:
130            logWarn('Skipping replacement for', pi.name, 'at', specFile,
131                    'line', pi.begin)
132            print('Skipping replacement for', pi.name, 'at', specFile,
133                  'line', pi.begin)
134            printPageInfo(pi, file)
135            skipped.add(specFile)
136
137    if overwrite:
138        pageName = specFile
139    else:
140        pageName = outDir + '/' + os.path.basename(specFile)
141
142    fp = open(pageName, 'w', encoding='utf-8')
143
144    line = 0
145    for text in file:
146        if line in actions.keys():
147            action = actions[line]['action']
148            replace = actions[line]['replace']
149            pi = actions[line]['pageinfo']
150
151            logDiag('ACTION:', action, 'REPLACE:', replace, 'at line', line)
152            logDiag('PageInfo of action:')
153            printPageInfo(pi, file)
154
155            if action == 'begin':
156                openBlock(pi, fp)
157                if not replace:
158                    print(text, file=fp, end='')
159            elif action == 'end':
160                if not replace:
161                    print(text, file=fp, end='')
162                closeBlock(pi, fp)
163            else:
164                print('ERROR: unrecognized action:', action, 'in',
165                      specFile, 'at line', line)
166                print(text, file=fp, end='')
167        else:
168            print(text, file=fp, end='')
169        line = line + 1
170
171    fp.close()
172
173    #for line in sorted(actions.keys()):
174    #    action = actions[line]
175    #    print('action at line', line, '\t',
176    #          action[0], action[1], action[2])
177
178if __name__ == '__main__':
179    global genDict
180    genDict = {}
181
182    parser = argparse.ArgumentParser()
183
184    parser.add_argument('-diag', action='store', dest='diagFile',
185                        help='Set the diagnostic file')
186    parser.add_argument('-warn', action='store', dest='warnFile',
187                        help='Set the warning file')
188    parser.add_argument('-log', action='store', dest='logFile',
189                        help='Set the log file for both diagnostics and warnings')
190    parser.add_argument('-outdir', action='store', dest='outDir',
191                        default='out',
192                        help='Set the base directory in which pages are generated')
193    parser.add_argument('-overwrite', action='store_true',
194                        help='Overwrite input filenames instead of writing different output filenames')
195    parser.add_argument('files', metavar='filename', nargs='*',
196                        help='a filename to extract ref pages from')
197    parser.add_argument('--version', action='version', version='%(prog)s 1.0')
198
199    results = parser.parse_args()
200
201    setLogFile(True,  True, results.logFile)
202    setLogFile(True, False, results.diagFile)
203    setLogFile(False, True, results.warnFile)
204
205    skipped = set()
206    for file in results.files:
207        replaceRef(file, results.outDir, results.overwrite, skipped)
208
209    if len(skipped) > 0:
210        print('Files containing skipped feature blocks:')
211        for file in sorted(skipped):
212            print('\t' + file)
213