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 endChunk(self, key, blockStart, lineList, line, inputfilename, subsymbols=[], protected=False): """ finish recording a chunk and save data. string key, int blockStart, reference linelist """ symbol = "null" if key != "null": symbol = Line.symbolOf(line) if not protected and symbol in self.symbols: print "Warning: duplicate block for symbol ", symbol, " ignored at line ", str(blockStart) return elif protected and symbol in self.protectedSymbols: print "Warning: duplicate block for protected symbol ",symbol,"ignored at line ", str(blockStart) return if not protected: self.symbolIndex[symbol] = len(self.sections) self.symbols.append(symbol) else: self.protectedSymbolIndex[symbol] = len(self.sections) self.protectedSymbols.append(symbol) block = Block.Block() block.init(key, lineList, inputfilename, blockStart, subsymbols) self.sections.append(block)
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")
def writeBlock(self, before, fs, after, opts, append): """process a block with -B -A or --signature options. # return 0 if ok, nonzero otherwise # @param before the block ahead of this one or none if this is first. # @param fs the current block to print. # @param after the block after this one or none if this is last. # @param opts handling flags for lines. # @param append[0] an in-out integer array with one element. it tracks # how many blocks have been written in the single file case. """ lines = fs.getLines() pos = 0 symbol = Line.symbolOf(lines[pos]) if symbol == "null": return 1 if not Line.matchedSymbol(symbol, opts.matchSyms): return 0 # compute before lines pre = opts.linesBefore post = opts.linesAfter if (opts.signatures or opts.method) and before != None: post = self.updateAfterCount(opts, symbol) pre = before.computeSignature( symbol, opts.language, opts.sourceKey, opts.methodcomment) outlines = [] if pre > 0 and before != None: blines = before.getLines() blen = len(blines) while blen > 0 and pre > 0: outlines.append(blines[blen-1]) blen -= 1 pre -= 1 outlines.reverse() # copy main segment if opts.genLines: endtag="" if opts.method: endtag="/* This line not in actual source */" Line.addLineNumber(fs.start(), outlines, fs.source(), opts.language, endtag ) while pos < len(lines): outlines.append(lines[pos]) pos += 1 pos = 0 # compute after if post > 0 and after != None: alines = after.getLines() n = 0 while n < len(alines) and post > 0: outlines.append(alines[n]) n += 1 post -= 1 # write if len(outlines) < 1: return 1 flags = "w" if opts.singleFile: if append[0]: flags= "a" if len(opts.outputFile): fname = os.path.join(opts.outputDir, opts.outputFile) else: fname = os.path.join(opts.outputDir, opts.inputFile) fname += ".splice" else: fname = os.path.join(opts.outputDir, opts.blockFilePrefix) # print "Writing block for ", symbol, fname fname = fname + symbol + opts.blockFileSuffix # print "Writing block for ", symbol, fname try: outfile = open(fname,flags) if opts.singleFile and append[0] and len(opts.spliceHeader) > 0 and (not opts.method): w = 0 delta = len(opts.spliceHeader) while w < 72: outfile.write("%s" % opts.spliceHeader) w += delta outfile.write("\n") j = 0 while j < len(outlines): if opts.keepLines or opts.genLines or outlines[j][0:5] != "#line": print >> outfile, outlines[j].strip("\n") j+= 1 append[0] += 1 return 0 except: print "Error writing block for ", symbol return 1