text_file.py (4457B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\text_file.py 2 __revision__ = '$Id: text_file.py 82110 2010-06-20 13:38:51Z kristjan.jonsson $' 3 import sys 4 5 class TextFile: 6 default_options = {'strip_comments': 1, 7 'skip_blanks': 1, 8 'lstrip_ws': 0, 9 'rstrip_ws': 1, 10 'join_lines': 0, 11 'collapse_join': 0} 12 13 def __init__(self, filename = None, file = None, **options): 14 if filename is None and file is None: 15 raise RuntimeError, "you must supply either or both of 'filename' and 'file'" 16 for opt in self.default_options.keys(): 17 if opt in options: 18 setattr(self, opt, options[opt]) 19 else: 20 setattr(self, opt, self.default_options[opt]) 21 22 for opt in options.keys(): 23 if opt not in self.default_options: 24 raise KeyError, "invalid TextFile option '%s'" % opt 25 26 if file is None: 27 self.open(filename) 28 else: 29 self.filename = filename 30 self.file = file 31 self.current_line = 0 32 self.linebuf = [] 33 34 def open(self, filename): 35 self.filename = filename 36 self.file = open(self.filename, 'r') 37 self.current_line = 0 38 39 def close(self): 40 self.file.close() 41 self.file = None 42 self.filename = None 43 self.current_line = None 44 45 def gen_error(self, msg, line = None): 46 outmsg = [] 47 if line is None: 48 line = self.current_line 49 outmsg.append(self.filename + ', ') 50 if isinstance(line, (list, tuple)): 51 outmsg.append('lines %d-%d: ' % tuple(line)) 52 else: 53 outmsg.append('line %d: ' % line) 54 outmsg.append(str(msg)) 55 return ''.join(outmsg) 56 57 def error(self, msg, line = None): 58 raise ValueError, 'error: ' + self.gen_error(msg, line) 59 60 def warn(self, msg, line = None): 61 sys.stderr.write('warning: ' + self.gen_error(msg, line) + '\n') 62 63 def readline(self): 64 if self.linebuf: 65 line = self.linebuf[-1] 66 del self.linebuf[-1] 67 return line 68 buildup_line = '' 69 while 1: 70 line = self.file.readline() 71 if line == '': 72 line = None 73 if self.strip_comments and line: 74 pos = line.find('#') 75 if pos == -1: 76 pass 77 elif pos == 0 or line[pos - 1] != '\\': 78 eol = line[-1] == '\n' and '\n' or '' 79 line = line[0:pos] + eol 80 if line.strip() == '': 81 continue 82 else: 83 line = line.replace('\\#', '#') 84 if self.join_lines and buildup_line: 85 if line is None: 86 self.warn('continuation line immediately precedes end-of-file') 87 return buildup_line 88 if self.collapse_join: 89 line = line.lstrip() 90 line = buildup_line + line 91 if isinstance(self.current_line, list): 92 self.current_line[1] = self.current_line[1] + 1 93 else: 94 self.current_line = [self.current_line, self.current_line + 1] 95 else: 96 if line is None: 97 return 98 if isinstance(self.current_line, list): 99 self.current_line = self.current_line[1] + 1 100 else: 101 self.current_line = self.current_line + 1 102 if self.lstrip_ws and self.rstrip_ws: 103 line = line.strip() 104 elif self.lstrip_ws: 105 line = line.lstrip() 106 elif self.rstrip_ws: 107 line = line.rstrip() 108 if (line == '' or line == '\n') and self.skip_blanks: 109 continue 110 if self.join_lines: 111 if line[-1] == '\\': 112 buildup_line = line[:-1] 113 continue 114 if line[-2:] == '\\\n': 115 buildup_line = line[0:-2] + '\n' 116 continue 117 return line 118 119 def readlines(self): 120 lines = [] 121 while 1: 122 line = self.readline() 123 if line is None: 124 return lines 125 lines.append(line) 126 127 def unreadline(self, line): 128 self.linebuf.append(line)