mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			135 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #! /usr/bin/env python
 | |
| 
 | |
| # Conversions to/from quoted-printable transport encoding as per RFC-1521
 | |
| # (Dec 1991 version).
 | |
| 
 | |
| ESCAPE = '='
 | |
| MAXLINESIZE = 76
 | |
| HEX = '0123456789ABCDEF'
 | |
| 
 | |
| def needsquoting(c, quotetabs):
 | |
| 	if c == '\t':
 | |
| 		return not quotetabs
 | |
| 	return c == ESCAPE or not(' ' <= c <= '~')
 | |
| 
 | |
| def quote(c):
 | |
| 	if c == ESCAPE:
 | |
| 		return ESCAPE * 2
 | |
| 	else:
 | |
| 		i = ord(c)
 | |
| 		return ESCAPE + HEX[i/16] + HEX[i%16]
 | |
| 
 | |
| def encode(input, output, quotetabs):
 | |
| 	while 1:
 | |
| 		line = input.readline()
 | |
| 		if not line: break
 | |
| 		new = ''
 | |
| 		last = line[-1:]
 | |
| 		if last == '\n': line = line[:-1]
 | |
| 		else: last = ''
 | |
| 		prev = ''
 | |
| 		for c in line:
 | |
| 			if needsquoting(c, quotetabs):
 | |
| 				c = quote(c)
 | |
| 			if len(new) + len(c) >= MAXLINESIZE:
 | |
| 				output.write(new + ESCAPE + '\n')
 | |
| 				new = ''
 | |
| 			new = new + c
 | |
| 			prev = c
 | |
| 		if prev in (' ', '\t'):
 | |
| 			output.write(new + ESCAPE + '\n\n')
 | |
| 		else:
 | |
| 			output.write(new + '\n')
 | |
| 
 | |
| def decode(input, output):
 | |
| 	new = ''
 | |
| 	while 1:
 | |
| 		line = input.readline()
 | |
| 		if not line: break
 | |
| 		i, n = 0, len(line)
 | |
| 		if n > 0 and line[n-1] == '\n':
 | |
| 			partial = 0; n = n-1
 | |
| 			# Strip trailing whitespace
 | |
| 			while n > 0 and line[n-1] in (' ', '\t'):
 | |
| 				n = n-1
 | |
| 		else:
 | |
| 			partial = 1
 | |
| 		while i < n:
 | |
| 			c = line[i]
 | |
| 			if c <> ESCAPE:
 | |
| 				new = new + c; i = i+1
 | |
| 			elif i+1 == n and not partial:
 | |
| 				partial = 1; break
 | |
| 			elif i+1 < n and line[i+1] == ESCAPE:
 | |
| 				new = new + ESCAPE; i = i+2
 | |
| 			elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]):
 | |
| 				new = new + chr(unhex(line[i+1:i+3])); i = i+3
 | |
| 			else: # Bad escape sequence -- leave it in
 | |
| 				new = new + c; i = i+1
 | |
| 		if not partial:
 | |
| 			output.write(new + '\n')
 | |
| 			new = ''
 | |
| 	if new:
 | |
| 		output.write(new)
 | |
| 
 | |
| def ishex(c):
 | |
| 	return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
 | |
| 
 | |
| def unhex(s):
 | |
| 	bits = 0
 | |
| 	for c in s:
 | |
| 		if '0' <= c <= '9':
 | |
| 			i = ord('0')
 | |
| 		elif 'a' <= c <= 'f':
 | |
| 			i = ord('a')-10
 | |
| 		elif 'A' <= c <= 'F':
 | |
| 			i = ord('A')-10
 | |
| 		else:
 | |
| 			break
 | |
| 		bits = bits*16 + (ord(c) - i)
 | |
| 	return bits
 | |
| 
 | |
| def test():
 | |
| 	import sys
 | |
| 	import getopt
 | |
| 	try:
 | |
| 		opts, args = getopt.getopt(sys.argv[1:], 'td')
 | |
| 	except getopt.error, msg:
 | |
| 		sys.stdout = sys.stderr
 | |
| 		print msg
 | |
| 		print "usage: quopri [-t | -d] [file] ..."
 | |
| 		print "-t: quote tabs"
 | |
| 		print "-d: decode; default encode"
 | |
| 		sys.exit(2)
 | |
| 	deco = 0
 | |
| 	tabs = 0
 | |
| 	for o, a in opts:
 | |
| 		if o == '-t': tabs = 1
 | |
| 		if o == '-d': deco = 1
 | |
| 	if tabs and deco:
 | |
| 		sys.stdout = sys.stderr
 | |
| 		print "-t and -d are mutually exclusive"
 | |
| 		sys.exit(2)
 | |
| 	if not args: args = ['-']
 | |
| 	sts = 0
 | |
| 	for file in args:
 | |
| 		if file == '-':
 | |
| 			fp = sys.stdin
 | |
| 		else:
 | |
| 			try:
 | |
| 				fp = open(file)
 | |
| 			except IOError, msg:
 | |
| 				sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
 | |
| 				sts = 1
 | |
| 				continue
 | |
| 		if deco:
 | |
| 			decode(fp, sys.stdout)
 | |
| 		else:
 | |
| 			encode(fp, sys.stdout, tabs)
 | |
| 		if fp is not sys.stdin:
 | |
| 			fp.close()
 | |
| 	if sts:
 | |
| 		sys.exit(sts)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
| 	test()
 | 
