def generatelinenumbers(self): ''' the difference with the std preprocessor linemapping (see merger.py) is that here we assume that when there are no linemarkers the output line always generates from the input coordinate fetched from the last linemarker found. ''' inputlineno = 0 # actual input line number including line with markers inputmarkercnt = 0 # count the linemarkers in the input (each linemarker takes one line) cleanoutput = '' # output without linemarkers for line in self.output.splitlines(): inputlineno +=1 if line.startswith('# '): inputmarkercnt += 1 (self.lastinputlineno,self.lastinputfile,self.lastflag) = utils.linemarkerinfo(line) else: if line == '': # avoid mapping empty lines #print "EMPTY LINE" pass else: # > > > Our line map < < < self.inputtooutput[self.lastinputlineno] = inputlineno-inputmarkercnt self.outputtoinput[inputlineno-inputmarkercnt] = self.lastinputlineno self.lastoutputlineno += 1 cleanoutput += line + '\n' self.output = cleanoutput
def generatelinenumbers(self): # Generate the map of line numbers. # # Every time a linemarker in the output is found... # # This way we can extract from the line annotation the input line number to which # the output line refers to, and associate it correctly. # # In the module's output, # linemarkers will indicate precisely where the lines come from, # but this information needs to be removed from the input block, or # pycparser won't handle it. # inputline = 0 # actual input line number in the input (i.e. lines[]), including line with markers inputmarkers = 0 # count the linemarkers in the input (we know each linemarker takes one entire line) cleanoutput = '' # clean output (without linemarkers) for line in self.output.splitlines(): inputline +=1 ##print "LINE LINE LINE %s" % inputline if line.startswith('# '): inputmarkers += 1 markerinfo = utils.linemarkerinfo(line) self.lastinputlineno = markerinfo[0] self.lastinputfile = markerinfo[1] ##print "MARKER: '%s'" % line ##print " " + str(utils.linemarkerinfo(line)) ##print " last '%s'" % (utils.linemarkerinfo(line)[1]) ##print "\n\n" else: #print "input:%s -> output:%s" % (lastlineno, inputline-inputmarkers) #print "output:%s -> input:%s" % (inputline-inputmarkers, lastlineno) # > > > Our line map < < < self.inputtooutput[self.lastinputlineno] = inputline-inputmarkers self.outputtoinput[inputline-inputmarkers] = self.lastinputlineno self.lastoutputlineno += 1 cleanoutput += line + '\n' self.output = cleanoutput
def loadfromstring(self, string, env): self.cseqenv = env self.input = string string = self._sanitise(string) # Run the preprocessor with linemarker generation. # # the linemarker has the following format # (see https://gcc.gnu.org/onlinedocs/gcc-4.3.6/cpp/Preprocessor-Output.html): # # # LINE_NO FILENAME FLAG # # examples: # # 1 "<stdin>" # # 1 "include/pthread.h" 2 # localincludepath = '' if '/' in env.inputfile: localincludepath = env.inputfile[:env.inputfile.rfind('/')] # Workaround: # cpp does not strip C++-style comments ('//') from the input code, # gcc works instead. # includestring = ' -I%s' % os.path.dirname( __file__) + '/include' # include fake headers first if localincludepath != '': includestring += ' -I%s' % localincludepath if env.includepath: includestring += ' -I' + ' -I'.join(env.includepath.split(':')) # Pre-process away GNU C extensions. macros = "-D'__attribute__(x)=' -D'__extension__(x)=' -D'__volatile__=' -D'__asm__='" #cmdline = 'cpp -Iinclude -E -C ' + filename + ' > ' + filename + '.1' + '.c' #cmdline = 'gcc -Iinclude -P -E - ' # hyphen at the end forces input from stdin cmdline = 'gcc %s -nostdinc %s -E - ' % ( macros, includestring) # hyphen at the end forces input from stdin p = subprocess.Popen(shlex.split(cmdline), stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = p.communicate(input=string)[0] if self.need_gnu_fix: string = self._gnu_extension_fix(string) # After preprocessing, line markers indicate where the lines come from, but # this information needs to be removed from the input block, or # pycparser won't handle it. # input = string.splitlines() output = '' # clean input (without linemarkers) outputlineno = 0 # current output line number (clean, no linemarkers) inputlinenooffset = 0 # number of input lines since the last marker # coords fetched from the last linemarker lastinputfile = '' # input file from the last linemarker lastinputlineno = 0 # line number from the last linemarker for line in input: if line.startswith('# '): inputlinenooffset = 0 (lastinputlineno, lastinputfile, lastflag) = utils.linemarkerinfo(line) else: # > > > Our line map < < < self.outputtoinput[ outputlineno] = lastinputlineno + inputlinenooffset - 1 self.outputtofiles[ outputlineno] = lastinputfile if lastinputfile != '<stdin>' else env.inputfile #print "%s,%s <- %s" % (self.outputtoinput[outputlineno],self.outputtofiles[outputlineno],outputlineno) inputlinenooffset += 1 outputlineno += 1 output += line + '\n' self.markedoutput = string self.output = output self.lastoutputlineno = outputlineno
def loadfromstring(self, string, env): self.input = string string = self._sanitise(string) ''' parser = pycparser.c_parser.CParser() # avoid using CSeq's enhanced parser as it is more complex - all other modules should use that. self.ast = parser.parse(out) self.output = self.visit(self.ast) ''' # Run the preprocessor with linemarker generation. # # the linemarker has the following format # (see https://gcc.gnu.org/onlinedocs/gcc-4.3.6/cpp/Preprocessor-Output.html): # # # LINE_NO FILENAME FLAG # # examples: # # 1 "<stdin>" # # 1 "include/pthread.h" 2 # # # Workaround: cpp does not strip C++-style comments ('//') from the input code, # need to use gcc preprocessor # ###cmdline = 'cpp -Iinclude -E -C ' + filename + ' > ' + filename + '.1' + '.c' ##cmdline = 'gcc -Iinclude -P -E - ' # hyphen at the end forces input from stdin # cmdline = 'gcc -Iinclude -E - ' # hyphen at the end forces input from stdin p = subprocess.Popen(shlex.split(cmdline), stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = p.communicate(input=string)[0] # After preprocessing, line markers will indicate precisely where the lines come from, # but this information needs to be removed from the input block, or # pycparser won't handle it. # lines = string.splitlines() inputline = 0 # actual input line number in the input (i.e. lines[]), including linemarkers count inputmarkers = 0 # count the linemarkers in the input (we know each linemarker takes one entire line) # coords given by the last linemarker lastinputfile = '' # input file in the last linemarker self.lastlineno = 0 # line number since last linemarker boh = '' # clean input (without linemarkers) for line in lines: inputline +=1 if line.startswith('# '): inputmarkers += 1 markerinfo = utils.linemarkerinfo(line) self.lastlineno = markerinfo[0] lastinputfile = markerinfo[1] #print "MARKER: '%s'" % line #print " " + str(utils.linemarkerinfo(line)) #print " last '%s'" % (utils.linemarkerinfo(line)[1]) #print "\n\n" else: #print "line %s in the input is actually coming from %s, line %s" % (inputline, lastinputfile, lastlineno) #print "line %s in the input (not counting '# lines') is actually coming from %s, line %s" % (inputline-inputmarkers, lastinputfile, lastlineno) #print "input:%s -> output:%s" % (lastlineno, inputline-inputmarkers) #print "output:%s -> input:%s" % (inputline-inputmarkers, lastlineno) # > > > Our line map < < < self.inputtooutput[self.lastlineno] = inputline-inputmarkers self.outputtoinput[inputline-inputmarkers] = self.lastlineno #print line #print " -"*20 #print "\n" self.lastlineno += 1 boh += line + '\n' string = boh #super(Merger, self).loadfromstring(string, env) self.output = boh
def loadfromstring(self, string, env): self.cseqenv = env self.input = string string = self._sanitise(string) # Run the preprocessor with linemarker generation. # # the linemarker has the following format # (see https://gcc.gnu.org/onlinedocs/gcc-4.3.6/cpp/Preprocessor-Output.html): # # # LINE_NO FILENAME FLAG # # examples: # # 1 "<stdin>" # # 1 "include/pthread.h" 2 # localincludepath = '' if '/' in env.inputfile: localincludepath = env.inputfile[:env.inputfile.rfind('/')] # Workaround: # cpp does not strip C++-style comments ('//') from the input code, # gcc works instead. # includestring = ' -I%s' % os.path.dirname(__file__)+'/include' # include fake headers first if localincludepath!='': includestring += ' -I%s' % localincludepath if env.includepath: includestring += ' -I'+' -I'.join(env.includepath.split(':')) # Pre-process away GNU C extensions. macros = "-D'__attribute__(x)=' -D'__extension__(x)=' -D'__volatile__=' -D'__asm__='" #cmdline = 'cpp -Iinclude -E -C ' + filename + ' > ' + filename + '.1' + '.c' #cmdline = 'gcc -Iinclude -P -E - ' # hyphen at the end forces input from stdin cmdline = 'gcc %s -nostdinc %s -E - ' % (macros,includestring) # hyphen at the end forces input from stdin p = subprocess.Popen(shlex.split(cmdline), stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) string = p.communicate(input=string)[0] if self.need_gnu_fix: string = self._gnu_extension_fix(string) # After preprocessing, line markers indicate where the lines come from, but # this information needs to be removed from the input block, or # pycparser won't handle it. # input = string.splitlines() output = '' # clean input (without linemarkers) outputlineno = 0 # current output line number (clean, no linemarkers) inputlinenooffset = 0 # number of input lines since the last marker # coords fetched from the last linemarker lastinputfile = '' # input file from the last linemarker lastinputlineno = 0 # line number from the last linemarker for line in input: if line.startswith('# '): inputlinenooffset = 0 (lastinputlineno,lastinputfile,lastflag) = utils.linemarkerinfo(line) else: # > > > Our line map < < < self.outputtoinput[outputlineno] = lastinputlineno+inputlinenooffset-1 self.outputtofiles[outputlineno] = lastinputfile if lastinputfile!='<stdin>' else env.inputfile #print "%s,%s <- %s" % (self.outputtoinput[outputlineno],self.outputtofiles[outputlineno],outputlineno) inputlinenooffset += 1 outputlineno += 1 output += line + '\n' self.markedoutput = string self.output = output self.lastoutputlineno = outputlineno