def handle_cdata(pos, window, charpat, stopchars):
cdata = '<STR_LIT>'<EOL>cursor = start = pos<EOL>try:<EOL><INDENT>while True:<EOL><INDENT>while charpat.match(window[cursor]):<EOL><INDENT>cursor += <NUM_LIT:1><EOL><DEDENT>addchars = window[start:cursor]<EOL>cdata += addchars<EOL>if window[cursor] in stopchars:<EOL><INDENT>return cdata, cursor<EOL><DEDENT>elif window[cursor] == '<STR_LIT:&>':<EOL><INDENT>start = cursor = cursor + <NUM_LIT:1><EOL>if window[cursor] == '<STR_LIT:#>' and window[cursor + <NUM_LIT:1>] == '<STR_LIT:x>':<EOL><INDENT>start = cursor = cursor + <NUM_LIT:2><EOL>while True:<EOL><INDENT>if HEXCHARENTOK.match(window[cursor]):<EOL><INDENT>cursor += <NUM_LIT:1><EOL><DEDENT>elif window[cursor] == '<STR_LIT:;>':<EOL><INDENT>c = chr(int(window[start:cursor], <NUM_LIT:16>))<EOL>if not CHARACTER.match(c):<EOL><INDENT>raise RuntimeError('<STR_LIT>'.format('<STR_LIT:&>' + window[start:cursor] + '<STR_LIT:;>'))<EOL><DEDENT>cdata += c<EOL>break<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>'.format(window[cursor]))<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>while True:<EOL><INDENT>if NAMEDCHARENTOK.match(window[cursor]):<EOL><INDENT>cursor += <NUM_LIT:1><EOL><DEDENT>elif window[cursor] == '<STR_LIT:;>':<EOL><INDENT>for cn, c in CHARNAMES:<EOL><INDENT>if window[start:cursor] == cn:<EOL><INDENT>cdata += c<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>'.format(repr(window[start:cursor])))<EOL><DEDENT>break<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>'.format(window[cursor]), error_context(window, start, cursor))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>cursor += <NUM_LIT:1><EOL>start = cursor<EOL><DEDENT><DEDENT>except IndexError:<EOL><INDENT>return None, cursor<EOL><DEDENT>
Return (result, new_position) tuple.
Result is cdata string if possible and None if more input is needed
Or of course bad syntax can raise a RuntimeError