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