<s> """<STR_LIT>""" <EOL> from __future__ import unicode_literals <EOL> from django . utils import six <EOL> from django . utils . six . moves import zip <EOL> ESCAPE_MAPPINGS = { <EOL> "<STR_LIT:A>" : None , <EOL> "<STR_LIT:b>" : None , <EOL> "<STR_LIT:B>" : None , <EOL> "<STR_LIT:d>" : "<STR_LIT:0>" , <EOL> "<STR_LIT:D>" : "<STR_LIT:x>" , <EOL> "<STR_LIT:s>" : "<STR_LIT:U+0020>" , <EOL> "<STR_LIT:S>" : "<STR_LIT:x>" , <EOL> "<STR_LIT:w>" : "<STR_LIT:x>" , <EOL> "<STR_LIT>" : "<STR_LIT:!>" , <EOL> "<STR_LIT>" : None , <EOL> } <EOL> class Choice ( list ) : <EOL> """<STR_LIT>""" <EOL> class Group ( list ) : <EOL> """<STR_LIT>""" <EOL> class NonCapture ( list ) : <EOL> """<STR_LIT>""" <EOL> def normalize ( pattern ) : <EOL> """<STR_LIT>""" <EOL> result = [ ] <EOL> non_capturing_groups = [ ] <EOL> consume_next = True <EOL> pattern_iter = next_char ( iter ( pattern ) ) <EOL> num_args = <NUM_LIT:0> <EOL> try : <EOL> ch , escaped = next ( pattern_iter ) <EOL> except StopIteration : <EOL> return [ ( '<STR_LIT>' , [ ] ) ] <EOL> try : <EOL> while True : <EOL> if escaped : <EOL> result . append ( ch ) <EOL> elif ch == '<STR_LIT:.>' : <EOL> result . append ( "<STR_LIT:.>" ) <EOL> elif ch == '<STR_LIT:|>' : <EOL> raise NotImplementedError <EOL> elif ch == "<STR_LIT>" : <EOL> pass <EOL> elif ch == '<STR_LIT:$>' : <EOL> break <EOL> elif ch == '<STR_LIT:)>' : <EOL> start = non_capturing_groups . pop ( ) <EOL> inner = NonCapture ( result [ start : ] ) <EOL> result = result [ : start ] + [ inner ] <EOL> elif ch == '<STR_LIT:[>' : <EOL> ch , escaped = next ( pattern_iter ) <EOL> result . append ( ch ) <EOL> ch , escaped = next ( pattern_iter ) <EOL> while escaped or ch != '<STR_LIT:]>' : <EOL> ch , escaped = next ( pattern_iter ) <EOL> elif ch == '<STR_LIT:(>' : <EOL> ch , escaped = next ( pattern_iter ) <EOL> if ch != '<STR_LIT:?>' or escaped : <EOL> name = "<STR_LIT>" % num_args <EOL> num_args += <NUM_LIT:1> <EOL> result . append ( Group ( ( ( "<STR_LIT>" % name ) , name ) ) ) <EOL> walk_to_end ( ch , pattern_iter ) <EOL> else : <EOL> ch , escaped = next ( pattern_iter ) <EOL> if ch in "<STR_LIT>" : <EOL> walk_to_end ( ch , pattern_iter ) <EOL> elif ch == '<STR_LIT::>' : <EOL> non_capturing_groups . append ( len ( result ) ) <EOL> elif ch != '<STR_LIT:P>' : <EOL> raise ValueError ( "<STR_LIT>" % ch ) <EOL> else : <EOL> ch , escaped = next ( pattern_iter ) <EOL> if ch not in ( '<STR_LIT:<>' , '<STR_LIT:=>' ) : <EOL> raise ValueError ( "<STR_LIT>" % ch ) <EOL> if ch == '<STR_LIT:<>' : <EOL> terminal_char = '<STR_LIT:>>' <EOL> else : <EOL> terminal_char = '<STR_LIT:)>' <EOL> name = [ ] <EOL> ch , escaped = next ( pattern_iter ) <EOL> while ch != terminal_char : <EOL> name . append ( ch ) <EOL> ch , escaped = next ( pattern_iter ) <EOL> param = '<STR_LIT>' . join ( name ) <EOL> if terminal_char != '<STR_LIT:)>' : <EOL> result . append ( Group ( ( ( "<STR_LIT>" % param ) , param ) ) ) <EOL> walk_to_end ( ch , pattern_iter ) <EOL> else : <EOL> result . append ( Group ( ( ( "<STR_LIT>" % param ) , None ) ) ) <EOL> elif ch in "<STR_LIT>" : <EOL> count , ch = get_quantifier ( ch , pattern_iter ) <EOL> if ch : <EOL> consume_next = False <EOL> if count == <NUM_LIT:0> : <EOL> if contains ( result [ - <NUM_LIT:1> ] , Group ) : <EOL> result [ - <NUM_LIT:1> ] = Choice ( [ None , result [ - <NUM_LIT:1> ] ] ) <EOL> else : <EOL> result . pop ( ) <EOL> elif count > <NUM_LIT:1> : <EOL> result . extend ( [ result [ - <NUM_LIT:1> ] ] * ( count - <NUM_LIT:1> ) ) <EOL> else : <EOL> result . append ( ch ) <EOL> if consume_next : <EOL> ch , escaped = next ( pattern_iter ) <EOL> else : <EOL> consume_next = True <EOL> except StopIteration : <EOL> pass <EOL> except NotImplementedError : <EOL> return [ ( '<STR_LIT>' , [ ] ) ] <EOL> return list ( zip ( * flatten_result ( result ) ) ) <EOL> def next_char ( input_iter ) : <EOL> """<STR_LIT>""" <EOL> for ch in input_iter : <EOL> if ch != '<STR_LIT:\\>' : <EOL> yield ch , False <EOL> continue <EOL> ch = next ( input_iter ) <EOL> representative = ESCAPE_MAPPINGS . get ( ch , ch ) <EOL> if representative is None : <EOL> continue <EOL> yield representative , True <EOL> def walk_to_end ( ch , input_iter ) : <EOL> """<STR_LIT>""" <EOL> if ch == '<STR_LIT:(>' : <EOL> nesting = <NUM_LIT:1> <EOL> else : <EOL> nesting = <NUM_LIT:0> <EOL> for ch , escaped in input_iter : <EOL> if escaped : <EOL> continue <EOL> elif ch == '<STR_LIT:(>' : <EOL> nesting += <NUM_LIT:1> <EOL> elif ch == '<STR_LIT:)>' : <EOL> if not nesting : <EOL> return <EOL> nesting -= <NUM_LIT:1> <EOL> def get_quantifier ( ch , input_iter ) : <EOL> """<STR_LIT>""" <EOL> if ch in '<STR_LIT>' : <EOL> try : <EOL> ch2 , escaped = next ( input_iter ) <EOL> except StopIteration : <EOL> ch2 = None <EOL> if ch2 == '<STR_LIT:?>' : <EOL> ch2 = None <EOL> if ch == '<STR_LIT:+>' : <EOL> return <NUM_LIT:1> , ch2 <EOL> return <NUM_LIT:0> , ch2 <EOL> quant = [ ] <EOL> while ch != '<STR_LIT:}>' : <EOL> ch , escaped = next ( input_iter ) <EOL> quant . append ( ch ) <EOL> quant = quant [ : - <NUM_LIT:1> ] <EOL> values = '<STR_LIT>' . join ( quant ) . split ( '<STR_LIT:U+002C>' ) <EOL> try : <EOL> ch , escaped = next ( input_iter ) <EOL> except StopIteration : <EOL> ch = None <EOL> if ch == '<STR_LIT:?>' : <EOL> ch = None <EOL> return int ( values [ <NUM_LIT:0> ] ) , ch <EOL> def contains ( source , inst ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( source , inst ) : <EOL> return True <EOL> if isinstance ( source , NonCapture ) : <EOL> for elt in source : <EOL> if contains ( elt , inst ) : <EOL> return True <EOL> return False <EOL> def flatten_result ( source ) : <EOL> """<STR_LIT>""" <EOL> if source is None : <EOL> return [ '<STR_LIT>' ] , [ [ ] ] <EOL> if isinstance ( source , Group ) : <EOL> if source [ <NUM_LIT:1> ] is None : <EOL> params = [ ] <EOL> else : <EOL> params = [ source [ <NUM_LIT:1> ] ] <EOL> return [ source [ <NUM_LIT:0> ] ] , [ params ] <EOL> result = [ '<STR_LIT>' ] <EOL> result_args = [ [ ] ] <EOL> pos = last = <NUM_LIT:0> <EOL> for pos , elt in enumerate ( source ) : <EOL> if isinstance ( elt , six . string_types ) : <EOL> continue <EOL> piece = '<STR_LIT>' . join ( source [ last : pos ] ) <EOL> if isinstance ( elt , Group ) : <EOL> piece += elt [ <NUM_LIT:0> ] <EOL> param = elt [ <NUM_LIT:1> ] <EOL> else : <EOL> param = None <EOL> last = pos + <NUM_LIT:1> <EOL> for i in range ( len ( result ) ) : <EOL> result [ i ] += piece <EOL> if param : <EOL> result_args [ i ] . append ( param ) <EOL> if isinstance ( elt , ( Choice , NonCapture ) ) : <EOL> if isinstance ( elt , NonCapture ) : <EOL> elt = [ elt ] <EOL> inner_result , inner_args = [ ] , [ ] <EOL> for item in elt : <EOL> res , args = flatten_result ( item ) <EOL> inner_result . extend ( res ) <EOL> inner_args . extend ( args ) <EOL> new_result = [ ] <EOL> new_args = [ ] <EOL> for item , args in zip ( result , result_args ) : <EOL> for i_item , i_args in zip ( inner_result , inner_args ) : <EOL> new_result . append ( item + i_item ) <EOL> new_args . append ( args [ : ] + i_args ) <EOL> result = new_result <EOL> result_args = new_args <EOL> if pos >= last : <EOL> piece = '<STR_LIT>' . join ( source [ last : ] ) <EOL> for i in range ( len ( result ) ) : <EOL> result [ i ] += piece <EOL> return result , result_args </s>
