mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			160 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| 
 | |
| import tokenize
 | |
| import string
 | |
| 
 | |
| TABSONLY = 'TABSONLY'
 | |
| SPACESONLY = 'SPACESONLY'
 | |
| MIXED = 'MIXED'
 | |
| 
 | |
| class PyText:
 | |
| 	def __init__(self, fnm, optdict):
 | |
| 		self.optdict = optdict
 | |
| 		self.fnm = fnm
 | |
| 		self.txt = open(self.fnm, 'r').readlines()
 | |
| 		self.indents = [(0, 0, )]
 | |
| 		self.lnndx = 0
 | |
| 		self.indentndx = 0
 | |
| 	def getline(self):
 | |
| 		if self.lnndx < len(self.txt):
 | |
| 			txt = self.txt[self.lnndx]
 | |
| 			self.lnndx = self.lnndx + 1
 | |
| 		else:
 | |
| 			txt = ''
 | |
| 		return txt
 | |
| 	def tokeneater(self, type, token, start, end, line):
 | |
| 		if type == tokenize.INDENT:
 | |
| 			(lvl, s) = self.indents[-1]
 | |
| 			self.indents[-1] = (lvl, s, start[0]-1)
 | |
| 			self.indents.append((lvl+1, start[0]-1,))
 | |
| 		elif type == tokenize.DEDENT:
 | |
| 			(lvl, s) = self.indents[-1]
 | |
| 			self.indents[-1] = (lvl, s, start[0]-1)
 | |
| 			self.indents.append((lvl-1, start[0]-1,))
 | |
| 		elif type == tokenize.ENDMARKER:
 | |
| 			(lvl, s) = self.indents[-1]
 | |
| 			self.indents[-1] = (lvl, s, len(self.txt))
 | |
| 	def split(self, ln):
 | |
| 		content = string.lstrip(ln)
 | |
| 		if not content:
 | |
| 			return ('', '\n')
 | |
| 		lead = ln[:len(ln) - len(content)]
 | |
| 		lead = string.expandtabs(lead)
 | |
| 		return (lead, content)
 | |
| 		
 | |
| 	def process(self):
 | |
| 		style = self.optdict.get('style', TABSONLY)
 | |
| 		indent = string.atoi(self.optdict.get('indent', '4'))
 | |
| 		tabsz = string.atoi(self.optdict.get('tabs', '8'))
 | |
| 		print 'file %s -> style %s, tabsize %d, indent %d' % (self.fnm, style, tabsz, indent)
 | |
| 		tokenize.tokenize(self.getline, self.tokeneater)
 | |
| 		#import pprint
 | |
| 		#pprint.pprint(self.indents)
 | |
| 		new = []
 | |
| 		for (lvl, s, e) in self.indents:
 | |
| 			if s >= len(self.txt):
 | |
| 				break
 | |
| 			if s == e:
 | |
| 				continue
 | |
| 			oldlead, content = self.split(self.txt[s])
 | |
| 			#print "oldlead", len(oldlead), `oldlead`
 | |
| 			if style == TABSONLY:
 | |
| 				newlead = '\t'*lvl
 | |
| 			elif style == SPACESONLY:
 | |
| 				newlead = ' '*(indent*lvl)
 | |
| 			else:
 | |
| 				sz = indent*lvl
 | |
| 				t,spcs = divmod(sz, tabsz)
 | |
| 				newlead = '\t'*t + ' '*spcs
 | |
| 			new.append(newlead + content)
 | |
| 			for ln in self.txt[s+1:e]:
 | |
| 				lead, content = self.split(ln)
 | |
| 				#print "lead:", len(lead)
 | |
| 				new.append(newlead + lead[len(oldlead):] + content)
 | |
| 		self.save(new)
 | |
| 		#print "---", self.fnm
 | |
| 		#for ln in new:
 | |
| 		#    print ln,
 | |
| 		#print
 | |
| 		
 | |
| 	def save(self, txt):
 | |
| 		bakname = os.path.splitext(self.fnm)[0]+'.bak'
 | |
| 		print "backing up", self.fnm, "to", bakname
 | |
| 		#print os.getcwd()
 | |
| 		try:
 | |
| 			os.rename(self.fnm, bakname)
 | |
| 		except os.error:
 | |
| 			os.remove(bakname)
 | |
| 			os.rename(self.fnm, bakname)
 | |
| 		open(self.fnm, 'w').writelines(txt)
 | |
| 		
 | |
| def test():
 | |
| 	tc = PyText('test1.py')
 | |
| 	tc.process()
 | |
| 	tc = PyText('test1.py')
 | |
| 	tc.process(style=TABSONLY)
 | |
| 	tc = PyText('test1.py')
 | |
| 	tc.process(style=MIXED, indent=4, tabs=8)
 | |
| 	tc = PyText('test1.py')
 | |
| 	tc.process(style=MIXED, indent=2, tabs=8)
 | |
| 	
 | |
| def cleanfile(fnm, d):
 | |
| 	if os.path.isdir(fnm) and not os.path.islink(fnm):
 | |
| 		names = os.listdir(fnm)
 | |
| 		for name in names:
 | |
| 			fullnm = os.path.join(fnm, name)
 | |
| 			if (os.path.isdir(fullnm) and not os.path.islink(fullnm)) or \
 | |
| 			    os.path.normcase(fullnm[-3:]) == ".py":
 | |
| 				cleanfile(fullnm, d)
 | |
| 		return
 | |
| 	tc = PyText(fnm, d)
 | |
| 	tc.process()
 | |
| 	
 | |
| usage="""\
 | |
| %s [options] [path...]
 | |
|  options
 | |
|   -T : reformat to TABS ONLY
 | |
|   -S : reformat to SPACES ONLY ( -i option is important)
 | |
|   -M : reformat to MIXED SPACES / TABS ( -t and -i options important)
 | |
|   -t<n> : tab is worth <n> characters
 | |
|   -i<n> : indents should be <n> characters 
 | |
|   -h : print this text
 | |
|  path is file or directory
 | |
| """
 | |
| if __name__ == '__main__':
 | |
| 	import sys, getopt, os
 | |
| 	opts, args = getopt.getopt(sys.argv[1:], "TSMht:i:")
 | |
| 	d = {}
 | |
| 	print `opts`
 | |
| 	for opt in opts:
 | |
| 		if opt[0] == '-T':
 | |
| 			d['style'] = TABSONLY
 | |
| 		elif opt[0] == '-S':
 | |
| 			d['style'] = SPACESONLY
 | |
| 		elif opt[0] == '-M':
 | |
| 			d['style'] = MIXED
 | |
| 		elif opt[0] == '-t':
 | |
| 			d['tabs'] = opt[1]
 | |
| 		elif opt[0] == '-i':
 | |
| 			d['indent'] = opt[1]
 | |
| 		elif opt[0] == '-h':
 | |
| 			print usage % sys.argv[0]
 | |
| 			sys.exit(0)
 | |
| 	if not args:
 | |
| 		print usage % sys.argv[0]
 | |
| 	for arg in args:
 | |
| 		cleanfile(arg, d)
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | |
| 		
 | 
