This mechanism has several purposes. First, it is used to prevent 'make' systems recompiling unchanged code files. Second, it is used so that the output of a previous run can be read back in while the current run is generating a new copy. Finally, the comparisons on all these files can be used to determine if the literate programming process has converged to a stable point or may require another pass.
Please note that some care is required to ensure convergence is possible. Note also that when line numbers are generated, a single change to the source file will cause comparisons to fail for all files with sections defined after that point, often causing an apparently redundant rebuild. This is not alsways the case, for example, in C, the assert macro reports line numbers at run time, and the rebuild is necessary. It may be useful to turn off line number generation for files once they have compiled successfully (until the production build).
Finally, note that if you put the time into an output file, it is likely to be different each run!
1: #line 233 "sink_drivers.ipk" 2: import string 3: from interscript.drivers.sinks.base import sink_base 4: from interscript.drivers.sinks import sink_open_error 5: 6: class named_file_sink(sink_base): 7: def __init__(self,pass_frame,input_filename, prefix='', eol='\n'): 8: self.pass_frame = pass_frame 9: self.process = pass_frame.process 10: self.site = self.process.site 11: self.platform = self.site.platform 12: if 'sinks' in self.process.trace: 13: self.process.acquire_object(self,'NAMED FILE SINK '+input_filename) 14: self.eol = eol 15: 16: # compute absolute pathname, and create directories if necessary 17: # we don't use posixpath because we're enforcing an _interscript_ 18: # pathname convention here 19: pathlist = string.split(input_filename,'/') 20: self.basename = pathlist[-1] 21: pathname = self.platform.mk_dir(prefix, pathlist) 22: 23: if self.platform.file_exists(pathname): 24: self.tmp_filename = self.platform.tempfile.mktemp() 25: if 'sinks' in self.process.trace: 26: print 'Generating temporary',self.tmp_filename,'for',input_filename 27: try: 28: file =self.platform.open(self.tmp_filename,'w') 29: self.pass_frame.fdict[input_filename]='temporary' 30: except: 31: raise sink_open_error, self.tmp_filename 32: sink_base.__init__(self, filename = pathname, name = input_filename, file = file ) 33: if pass_frame: self.pass_frame.flist.append(input_filename) 34: else: 35: if 'sinks' in self.process.trace: 36: print 'Generating original',input_filename 37: try: 38: file = self.platform.open(pathname,'w') 39: if pass_frame: self.pass_frame.fdict[input_filename]='original' 40: except: 41: raise sink_open_error,pathname 42: sink_base.__init__(self, filename = pathname, name = input_filename, file = file) 43: if pass_frame: self.pass_frame.flist.append(input_filename) 44: 45: def __del__(self): 46: pass_frame = self.__dict__.get('pass_frame',None) 47: if 'sinks' in self.process.trace: 48: print 'closing', self.name 49: self.file.close() 50: if hasattr(self,'tmp_filename'): 51: if self.process.update_files: 52: original_file = self.platform.open(self.filename,'r') 53: original_lines = original_file.readlines() 54: original_file.close() 55: 56: new_file = self.platform.open(self.tmp_filename,'r') 57: new_lines = new_file.readlines() 58: new_file.close() 59: 60: if not original_lines == new_lines: 61: if 'changes' in self.process.trace: 62: print 'File',self.filename,'is CHANGED' 63: if pass_frame: 64: self.pass_frame.fdict[self.name]='changed' 65: file = self.platform.open(self.filename,'w') 66: file.writelines(new_lines) 67: file.close() 68: else: 69: if 'changes' in self.process.trace: 70: print 'File',self.filename,'is unchanged' 71: if pass_frame: self.pass_frame.fdict[self.name]='unchanged' 72: else: 73: print '*** System error inhibiting file update for',self.filename,'***' 74: if pass_frame: self.pass_frame.fdict[self.name]='cancelled' 75: self.platform.os.remove(self.tmp_filename) 76: else: 77: if 'changes' in self.process.trace: 78: print 'File',self.filename,'is NEW' 79: if hasattr(self,'process') and 'sinks' in self.process.trace: 80: self.process.release_object(self) 81: 82: def raw_write(self,line): self.file.write(line) 83: def raw_eol(self): self.raw_write(self.eol) 84: