• 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 *
23import argparse, copy, io, os, pdb, re, string, sys
24
25def prefix(depth):
26    return '  ' * depth
27
28openPat   = re.compile('^\[open,(?P<attribs>refpage=.*)\]')
29ifdefPat = re.compile('^if(n|)def::(?P<condition>.*)\[(?P<text>.*)\]')
30endifPat = re.compile('^endif::(?P<condition>.*)\[\]')
31
32# Look for imbalanced block delimiters and conditionals
33#   specFile - filename to examine
34def findBalance(specFile):
35    file = loadFile(specFile)
36    if file == None:
37        return
38
39    # blocks[] is a stack of nesting constructs, each of which is
40    # [ '--', line, None ] for a -- delimiter on line
41    # [ 'ifdef', line, condition] for an ifdef or ifndef on line
42    blocks = []
43
44    line = 1
45
46    for str in file:
47        blockDepth = len(blocks)
48        if blockDepth > 0:
49            thisBlock = blocks[blockDepth-1]
50            blockType = thisBlock[0]
51            blockLine = thisBlock[1]
52            blockCondition = thisBlock[2]
53        else:
54            thisBlock = None
55            blockType = None
56            blockLine = None
57            blockCondition = None
58
59        if str.rstrip() == '--':
60            if (blockDepth > 0 and blockType == '--'):
61                print(prefix(blockDepth - 1) +
62                      'Closing -- block opened @', blockLine,
63                      '-> new block depth =', blockDepth - 1)
64                blocks.pop()
65            else:
66                print(prefix(blockDepth) +
67                      'Opening -- block @', line,
68                      '-> new block depth:', blockDepth + 1)
69                blocks.append([ '--', line, None ])
70            line = line + 1
71            continue
72
73        matches = beginPat.search(str)
74        if matches != None:
75            # print('Matched [open pattern @', line, ':', str.rstrip())
76            line = line + 1
77            continue
78
79        matches = ifdefPat.search(str)
80        if matches != None:
81            condition = matches.group('condition')
82            text = matches.group('text')
83
84            if text != '':
85                print('Matched self-closing if(n)def pattern @', line,
86                      'condition:', condition, 'text:', text)
87            else:
88                print(prefix(blockDepth) +
89                      'Opening if(n)def block @', line,
90                      '-> new block depth =', blockDepth + 1,
91                      'condition:', condition)
92                blocks.append([ 'ifdef', line, condition ])
93
94            line = line + 1
95            continue
96
97        matches = endifPat.search(str)
98        if matches != None:
99            condition = matches.group('condition')
100
101            if (blockDepth > 0):
102                if blockType == 'ifdef':
103                    # Try closing an ifdef/ifndef block
104                    if blockCondition != condition:
105                        print('** WARNING:', specFile,
106                              'endif @', blockLine,
107                              'block depth:', blockDepth,
108                              'condition', condition,
109                              'does not match ifdef/ifndef @',
110                              blockLine, 'condition', blockCondition)
111
112                    print(prefix(blockDepth - 1) +
113                          'Closing endif block @', line,
114                          '-> new block depth =', blockDepth - 1)
115                    blocks.pop()
116                elif blockType == '--':
117                    # An overlap!
118                    print('** ERROR:', specFile, 'endif @', line,
119                          'block depth:', blockDepth,
120                          'overlaps -- block start @', blockLine)
121                else:
122                    # Should never get here
123                    print('** ERROR:', specFile,
124                          'block depth:', blockDepth,
125                          'unknown open block type:', blockType)
126            else:
127                # Unlikely error condition from bad markup
128                print('** ERROR:', specFile,
129                      'block depth:', blockDepth,
130                      'endif @', line, 'with no matching open block')
131
132            line = line + 1
133            continue
134
135        line = line + 1
136
137    blockDepth = len(blocks)
138    if blockDepth > 0:
139        print('** ERROR:', specFile, 'still in open block at EOF:',
140              'block depth =', blockDepth,
141              'block type:', blocks[blockDepth-1][0])
142
143if __name__ == '__main__':
144    global genDict
145    genDict = {}
146
147    parser = argparse.ArgumentParser()
148
149    parser.add_argument('-diag', action='store', dest='diagFile',
150                        help='Set the diagnostic file')
151    parser.add_argument('-warn', action='store', dest='warnFile',
152                        help='Set the warning file')
153    parser.add_argument('-log', action='store', dest='logFile',
154                        help='Set the log file for both diagnostics and warnings')
155    parser.add_argument('files', metavar='filename', nargs='*',
156                        help='a filename to extract ref pages from')
157    parser.add_argument('--version', action='version', version='%(prog)s 1.0')
158
159    results = parser.parse_args()
160
161    setLogFile(True,  True, results.logFile)
162    setLogFile(True, False, results.diagFile)
163    setLogFile(False, True, results.warnFile)
164
165    skipped = set()
166    for file in results.files:
167        findBalance(file)
168
169    if len(skipped) > 0:
170        print('Files containing skipped feature blocks:')
171        for file in sorted(skipped):
172            print('\t' + file)
173