def findKeyRanges(self, key, requireSymbol=None): """ Return the ndex of start and end lines matching the key given, if any. Used to find well-formed embedded blocks. As there may be more than one embedded, result is a list. Illformed embedded blocks will cause an early exit, warnings, status, {index1, index2, ...} = findKeyRanges... status == 0 --> ok; status != 0 --> result is error string instead of list. """ # state is 0 if outside keyblock and 1 if inside state=0 index = 0 result = [] for s in self.data: if Line.keyBegins(key,s) and (not requireSymbol or Line.symbolOf(s) == requireSymbol): if not state: result.append(index) state = 1 else: return (1, "begin encountered twice without end for key " + key + " at line " + str(index)) if Line.keyEnds(key,s) and (not requireSymbol or Line.symbolOf(s) == requireSymbol): if state: result.append(index) state = 0 else: return (1, "end encountered without begin for key " + key + " at line " + str(index)) index += 1 return( 0, result )
def computeSignature(self, symbol, language, sourcekey, withcomment=False): """return attempted guess at the number of lines at the end of the block that constitute a babel impl method signature. The block being checked is the block before the block with the symbol code body. @param language one of python, java, c, cxx, f77, f90. @param sourceKey the key, not symbol, of interest. @param withcomment try to include the comment block if any. """ result = 0 lines = self.getLines() p = len(lines)-1 if p < 1: return 0 line = lines[p] if language == "python": while p >= 0 and line[0:4] != "####" and line[0:6] != " def " and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): # break on 2 blank lines if len(line) == 0: q = p -1 if q >= 0 and len(lines[q]) == 0: break # else keep line, move on to next result += 1 p -= 1 line = lines[p] result += 1 ; # include ' def ' line. # python comment blocks are embedded, not extra. if language == "java": while p > 0 and len(line) != 0 and \ line[0:6] != "import" and \ line[0:8] != " public" and \ line[0:4] != "////" and \ line[0:3] != "/**" and \ line[0:5] != " */" and \ line[0:8] != " static" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): result += 1 p -= 1 line = lines[p] result += 1 ; # include ' public' line. if withcomment: while p > 0 and len(line) != 0 and \ line[0:5] != " /**" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): result +=1 p -= 1 line = lines[p] if language == "c" or language == "cxx": while p > 0 and \ not Line.cppDirective(line) and \ line[0:15] != "// user defined" and \ line[0:15] != "// static class" and \ line[0:3] != "/**" and \ line[0:3] != " */" and \ line[0:5] != " */" and \ line[0:22] != "// special constructor" and \ line[0:22] != "// speical constructor" and \ line[0:1] != "}" and \ line[0:8] != "////////" and \ line[0:8] != "/**//**/" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): # two blank lines, or 1 if _tail symbol if len(line) == 0: mname = Line.methodName(symbol) if mname[0] == "_": break q = p-1 if q >= 0 and len(lines[q]) == 0: break # else keep line and move on result += 1 p -= 1 line = lines[p] if withcomment: while p > 0 and len(line) != 0 and \ line[0:5] != " /**" and \ line[0:2] != "/*" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): result +=1 p -= 1 line = lines[p] result += 1 ; # include '( )/*(*)' line. if language == "f77" or language == "f77_31": while p > 0 and \ line[0:19] != " subroutine " and \ line[0:4] != "CCCC" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): # break on 2 blank lines if len(line) == 0: q = p -1 if q >= 0 and len(lines[q]) == 0: break # else keep line and move on result += 1 p -= 1 line = lines[p] result += 1 ; # include subroutine if withcomment: while p > 0 and len(line) != 0 and \ line[0:15] != "C Method:" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): result +=1 p -= 1 line = lines[p] if language == "f90": while p > 0 and \ line[0:21] != "recursive subroutine " and \ line[0:5] != "!!!!" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): # break on 2 blank lines if len(line) == 0: q = p -1 if q >= 0 and len(lines[q]) == 0: break # else keep line and move on result += 1 p -= 1 line = lines[p] result += 1 ; # include subroutine if withcomment: while p > 0 and len(line) != 0 and \ line[0:9] != "! Method:" and \ not Line.keyEnds(sourcekey, line) and \ not Line.keyBegins(sourcekey,line): result +=1 p -= 1 line = lines[p] return result
def loadList(self, input, key, lines, warn=True, preserveProtected=False): """Load a list of lines as a source. Either this or load may be called once per SourceFile object. input is an identifier string, normally a filename, that might be useful in error messages. key is the splicing generic prefix tag (not per-sidl-symbol), and lines is the data.""" chunk = [] protectedChunk = [] # protected blocks need a separate chunk subsymbols = [] # Symbols designating substitution blocks nokey = "null" protectedKey = "bocca.protected" message = "Block still unended at end of file." self.num = 0 blockStart = 1 protectedBlockStart = 0 seek_begin = True # true while not in key'd block protected_block = False # true while in bocca.protected for line in lines: self.num += 1 if seek_begin: if Line.keyEnds(key, line): seek_begin = False message = "Block end found before beginning." break # outside a key block, start block, or append old. if Line.keyBegins(key, line): seek_begin = False self.endChunk( nokey, blockStart, chunk, line, input, protected=False) # save old if any blockStart = self.num self.beginChunk( chunk) # start new if any chunk.append(line) else: chunk.append(line) elif protected_block: # inside a protected block if Line.keyBegins(protectedKey, line) or Line.keyBegins(key, line): message = "Block begin found inside bocca.protected" break if Line.keyEnds(protectedKey, line): protectedChunk.append(line) chunk.append(line) self.endChunk( protectedKey, protectedBlockStart, protectedChunk, line, input, protected=True) subsymbols.append(Line.symbolOf(line)) protected_block = False; else: # Chunk contains content of subblocks; will be replaced/stubbed if necessary when # performing substitution protectedChunk.append(line) chunk.append(line) else: # inside a key block if Line.keyBegins(key,line): # warn unended block message = "Block begin found inside another." break if Line.keyEnds(key,line): seek_begin = True chunk.append(line) self.endChunk( key, blockStart, chunk, line, input, subsymbols, protected=False) # save key block subsymbols = [] blockStart = self.num+1 # start new block self.beginChunk( chunk) elif preserveProtected and Line.keyBegins(protectedKey, line): # Begin the protected block protectedBlockStart = self.num self.beginChunk(protectedChunk) protectedChunk.append(line) chunk.append(line) protected_block = True; else: chunk.append(line) # end else # end for if not seek_begin: print "In ", input, ":", message, " at line ", self.num if len(chunk) > 0: print "Current block started at line ", blockStart, ":" print "\t", chunk[0] return (1, message) if len(chunk) > 0: self.endChunk( nokey, blockStart, chunk, line, input) if len(self.symbolIndex) < 1 and warn: print "Warning: no blocks in ", input, " for key ", key return (0, "ok")