Entirely rewritten parseaddr() function by Sjoerd Mullender.

(Includes a patch he sent me a few days later.)
This commit is contained in:
Guido van Rossum 1997-09-15 14:12:54 +00:00
parent a1dbe50ec2
commit 7883e1dfbd
1 changed files with 95 additions and 56 deletions

View File

@ -307,90 +307,129 @@ def unquote(str):
# Parse an address into (name, address) tuple # Parse an address into (name, address) tuple
# (By Sjoerd Mullender)
error = 'parseaddr.error'
specials = regex.compile('[][()<>,.;:@\\" \000-\037\177-\377]')
def quote(str):
return '"%s"' % string.join(
string.split(
string.join(
string.split(str, '\\'),
'\\\\'),
'"'),
'\\"')
def parseaddr(address): def parseaddr(address):
import string token = [] # the current token
str = '' tokens = [] # the list of tokens
email = ''
comment = ''
backslash = 0 backslash = 0
dquote = 0 dquote = 0
was_quoted = 0
space = 0 space = 0
paren = 0 paren = 0
bracket = 0
seen_bracket = 0
for c in address: for c in address:
if backslash: if backslash:
str = str + c token.append(c)
backslash = 0 backslash = 0
continue
if c == '\\': if c == '\\':
backslash = 1 backslash = 1
was_quoted = 1
continue continue
if dquote: if dquote:
if c == '"': if c == '"':
dquote = 0 dquote = 0
else: else:
str = str + c token.append(c)
continue continue
if c == '"': if c == '"':
dquote = 1 dquote = 1
was_quoted = 1
continue
if paren:
if c == '(':
paren = paren + 1
elif c == ')':
paren = paren - 1
if paren == 0:
token = string.join(token, '')
tokens.append((2, token))
token = []
continue
token.append(c)
continue
if c == '(':
paren = 1
token = string.join(token, '')
tokens.append((was_quoted, token))
was_quoted = 0
token = []
continue continue
if c in string.whitespace: if c in string.whitespace:
space = 1 space = 1
continue continue
if space: if c in '<>@,;:.[]':
str = str + ' ' token = string.join(token, '')
tokens.append((was_quoted, token))
was_quoted = 0
token = []
tokens.append((0, c))
space = 0 space = 0
if paren:
if c == '(':
paren = paren + 1
str = str + c
continue continue
if c == ')': if space:
paren = paren - 1 token = string.join(token, '')
if paren == 0: tokens.append((was_quoted, token))
comment = comment + str was_quoted = 0
str = '' token = []
space = 0
token.append(c)
token = string.join(token, '')
tokens.append((was_quoted, token))
if (0, '<') in tokens:
name = []
addr = []
cur = name
for token in tokens:
if token[1] == '':
continue continue
if c == '(': if token == (0, '<'):
paren = paren + 1 if addr:
if bracket: raise error, 'syntax error'
email = email + str cur = addr
str = '' elif token == (0, '>'):
elif not seen_bracket: if cur is not addr:
email = email + str raise error, 'syntax error'
str = '' cur = name
continue elif token[0] == 2:
if bracket: if cur is name:
if c == '>': name.append('(' + token[1] + ')')
bracket = 0
email = email + str
str = ''
continue
if c == '<':
bracket = 1
seen_bracket = 1
comment = comment + str
str = ''
email = ''
continue
if c == '#' and not bracket and not paren:
# rest is comment
break
str = str + c
if str:
if seen_bracket:
if bracket:
email = str
else: else:
comment = comment + str name.append(token[1])
elif token[0] == 1 and cur is addr:
if specials.search(token[1]) >= 0:
cur.append(quote(token[1]))
else: else:
if paren: cur.append(token[1])
comment = comment + str
else: else:
email = email + str cur.append(token[1])
return string.strip(comment), string.strip(email) else:
name = []
addr = []
for token in tokens:
if token[1] == '':
continue
if token[0] == 2:
name.append(token[1])
elif token[0] == 1:
if specials.search(token[1]) >= 0:
addr.append(quote(token[1]))
else:
addr.append(token[1])
else:
addr.append(token[1])
return string.join(name, ' '), string.join(addr, '')
# Parse a date field # Parse a date field