/ scripts / Retired / findBalance.py
findBalance.py
  1  #!/usr/bin/python3
  2  #
  3  # Copyright (c) 2016-2019 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  
 22  from reflib import *
 23  import argparse, copy, io, os, pdb, re, string, sys
 24  
 25  def prefix(depth):
 26      return '  ' * depth
 27  
 28  openPat   = re.compile('^\[open,(?P<attribs>refpage=.*)\]')
 29  ifdefPat = re.compile('^if(n|)def::(?P<condition>.*)\[(?P<text>.*)\]')
 30  endifPat = re.compile('^endif::(?P<condition>.*)\[\]')
 31  
 32  # Look for imbalanced block delimiters and conditionals
 33  #   specFile - filename to examine
 34  def 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  
143  if __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)