
/* Tokenizer implementation */

#include "Python.h"
#include "pgenheaders.h"

#include <ctype.h>
#include <assert.h>

#include "tokenizer.h"
#include "errcode.h"

#ifndef PGEN
#include "unicodeobject.h"
#include "bytesobject.h"
#include "fileobject.h"
#include "codecs.h"
#include "abstract.h"
#endif /* PGEN */

#define is_potential_identifier_start(c) (\
                          (c >= 'a' && c <= 'z')\
		       || (c >= 'A' && c <= 'Z')\
		       || c == '_'\
		       || (c >= 128))

#define is_potential_identifier_char(c) (\
                          (c >= 'a' && c <= 'z')\
		       || (c >= 'A' && c <= 'Z')\
		       || (c >= '0' && c <= '9')\
		       || c == '_'\
		       || (c >= 128))

extern char *PyOS_Readline(FILE *, FILE *, char *);
/* Return malloc'ed string including trailing \n;
   empty malloc'ed string for EOF;
   NULL if interrupted */

/* Don't ever change this -- it would break the portability of Python code */
#define TABSIZE 8

/* Forward */
static struct tok_state *tok_new(void);
static int tok_nextc(struct tok_state *tok);
static void tok_backup(struct tok_state *tok, int c);


/* Token names */

char *_PyParser_TokenNames[] = {
	"ENDMARKER",
	"NAME",
	"NUMBER",
	"STRING",
	"NEWLINE",
	"INDENT",
	"DEDENT",
	"LPAR",
	"RPAR",
	"LSQB",
	"RSQB",
	"COLON",
	"COMMA",
	"SEMI",
	"PLUS",
	"MINUS",
	"STAR",
	"SLASH",
	"VBAR",
	"AMPER",
	"LESS",
	"GREATER",
	"EQUAL",
	"DOT",
	"PERCENT",
	"LBRACE",
	"RBRACE",
	"EQEQUAL",
	"NOTEQUAL",
	"LESSEQUAL",
	"GREATEREQUAL",
	"TILDE",
	"CIRCUMFLEX",
	"LEFTSHIFT",
	"RIGHTSHIFT",
	"DOUBLESTAR",
	"PLUSEQUAL",
	"MINEQUAL",
	"STAREQUAL",
	"SLASHEQUAL",
	"PERCENTEQUAL",
	"AMPEREQUAL",
	"VBAREQUAL",
	"CIRCUMFLEXEQUAL",
	"LEFTSHIFTEQUAL",
	"RIGHTSHIFTEQUAL",
	"DOUBLESTAREQUAL",
	"DOUBLESLASH",
	"DOUBLESLASHEQUAL",
	"AT",
	"RARROW",
	"ELLIPSIS",
	/* This table must match the #defines in token.h! */
	"OP",
	"<ERRORTOKEN>",
	"<N_TOKENS>"
};


/* Create and initialize a new tok_state structure */

static struct tok_state *
tok_new(void)
{
	struct tok_state *tok = (struct tok_state *)PyMem_MALLOC(
                                                sizeof(struct tok_state));
	if (tok == NULL)
		return NULL;
	tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL;
	tok->done = E_OK;
	tok->fp = NULL;
	tok->input = NULL;
	tok->tabsize = TABSIZE;
	tok->indent = 0;
	tok->indstack[0] = 0;
	tok->atbol = 1;
	tok->pendin = 0;
	tok->prompt = tok->nextprompt = NULL;
	tok->lineno = 0;
	tok->level = 0;
	tok->filename = NULL;
	tok->altwarning = 1;
	tok->alterror = 1;
	tok->alttabsize = 1;
	tok->altindstack[0] = 0;
	tok->decoding_state = STATE_INIT;
	tok->decoding_erred = 0;
	tok->read_coding_spec = 0;
	tok->enc = NULL;
	tok->encoding = NULL;
        tok->cont_line = 0;
#ifndef PGEN
	tok->decoding_readline = NULL;
	tok->decoding_buffer = NULL;
#endif
	return tok;
}

static char *
new_string(const char *s, Py_ssize_t len)
{
	char* result = (char *)PyMem_MALLOC(len + 1);
	if (result != NULL) {
		memcpy(result, s, len);
		result[len] = '\0';
	}
	return result;
}

#ifdef PGEN

static char *
decoding_fgets(char *s, int size, struct tok_state *tok)
{
	return fgets(s, size, tok->fp);
}

static int
decoding_feof(struct tok_state *tok)
{
	return feof(tok->fp);
}

static char *
decode_str(const char *str, int exec_input, struct tok_state *tok)
{
	return new_string(str, strlen(str));
}

#else /* PGEN */

static char *
error_ret(struct tok_state *tok) /* XXX */
{
	tok->decoding_erred = 1;
	if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */
		PyMem_FREE(tok->buf);
	tok->buf = NULL;
	return NULL;		/* as if it were EOF */
}


static char *
get_normal_name(char *s)	/* for utf-8 and latin-1 */
{
	char buf[13];
	int i;
	for (i = 0; i < 12; i++) {
		int c = s[i];
		if (c == '\0')
			break;
		else if (c == '_')
			buf[i] = '-';
		else
			buf[i] = tolower(c);
	}
	buf[i] = '\0';
	if (strcmp(buf, "utf-8") == 0 ||
	    strncmp(buf, "utf-8-", 6) == 0)
		return "utf-8";
	else if (strcmp(buf, "latin-1") == 0 ||
		 strcmp(buf, "iso-8859-1") == 0 ||
		 strcmp(buf, "iso-latin-1") == 0 ||
		 strncmp(buf, "latin-1-", 8) == 0 ||
		 strncmp(buf, "iso-8859-1-", 11) == 0 ||
		 strncmp(buf, "iso-latin-1-", 12) == 0)
		return "iso-8859-1";
	else
		return s;
}

/* Return the coding spec in S, or NULL if none is found.  */

static char *
get_coding_spec(const char *s, Py_ssize_t size)
{
	Py_ssize_t i;
	/* Coding spec must be in a comment, and that comment must be
         * the only statement on the source code line. */
        for (i = 0; i < size - 6; i++) {
		if (s[i] == '#')
			break;
		if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014')
			return NULL;
	}
	for (; i < size - 6; i++) { /* XXX inefficient search */
		const char* t = s + i;
		if (strncmp(t, "coding", 6) == 0) {
			const char* begin = NULL;
			t += 6;
			if (t[0] != ':' && t[0] != '=')
				continue;
			do {
				t++;
			} while (t[0] == '\x20' || t[0] == '\t');

			begin = t;
			while (isalnum(Py_CHARMASK(t[0])) ||
			       t[0] == '-' || t[0] == '_' || t[0] == '.')
				t++;

			if (begin < t) {
				char* r = new_string(begin, t - begin);
				char* q = get_normal_name(r);
				if (r != q) {
					PyMem_FREE(r);
					r = new_string(q, strlen(q));
				}
				return r;
			}
		}
	}
	return NULL;
}

/* Check whether the line contains a coding spec. If it does,
   invoke the set_readline function for the new encoding.
   This function receives the tok_state and the new encoding.
   Return 1 on success, 0 on failure.  */

static int
check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok,
		  int set_readline(struct tok_state *, const char *))
{
	char * cs;
	int r = 1;

        if (tok->cont_line)
		/* It's a continuation line, so it can't be a coding spec. */
		return 1;
	cs = get_coding_spec(line, size);
	if (cs != NULL) {
		tok->read_coding_spec = 1;
		if (tok->encoding == NULL) {
			assert(tok->decoding_state == STATE_RAW);
			if (strcmp(cs, "utf-8") == 0) {
				tok->encoding = cs;
			} else {
				r = set_readline(tok, cs);
				if (r) {
					tok->encoding = cs;
					tok->decoding_state = STATE_NORMAL;
				}
				else
					PyMem_FREE(cs);
			}
		} else {	/* then, compare cs with BOM */
			r = (strcmp(tok->encoding, cs) == 0);
			PyMem_FREE(cs);
		}
	}
	if (!r) {
		cs = tok->encoding;
		if (!cs)
			cs = "with BOM";
		PyErr_Format(PyExc_SyntaxError, "encoding problem: %s", cs);
	}
	return r;
}

/* See whether the file starts with a BOM. If it does,
   invoke the set_readline function with the new encoding.
   Return 1 on success, 0 on failure.  */

static int
check_bom(int get_char(struct tok_state *),
	  void unget_char(int, struct tok_state *),
	  int set_readline(struct tok_state *, const char *),
	  struct tok_state *tok)
{
	int ch1, ch2, ch3;
	ch1 = get_char(tok);
	tok->decoding_state = STATE_RAW;
	if (ch1 == EOF) {
		return 1;
	} else if (ch1 == 0xEF) {
		ch2 = get_char(tok);
		if (ch2 != 0xBB) {
			unget_char(ch2, tok);
			unget_char(ch1, tok);
			return 1;
		}
		ch3 = get_char(tok);
		if (ch3 != 0xBF) {
			unget_char(ch3, tok);
			unget_char(ch2, tok);
			unget_char(ch1, tok);
			return 1;
		}
#if 0
	/* Disable support for UTF-16 BOMs until a decision
	   is made whether this needs to be supported.  */
	} else if (ch1 == 0xFE) {
		ch2 = get_char(tok);
		if (ch2 != 0xFF) {
			unget_char(ch2, tok);
			unget_char(ch1, tok);
			return 1;
		}
		if (!set_readline(tok, "utf-16-be"))
			return 0;
		tok->decoding_state = STATE_NORMAL;
	} else if (ch1 == 0xFF) {
		ch2 = get_char(tok);
		if (ch2 != 0xFE) {
			unget_char(ch2, tok);
			unget_char(ch1, tok);
			return 1;
		}
		if (!set_readline(tok, "utf-16-le"))
			return 0;
		tok->decoding_state = STATE_NORMAL;
#endif
	} else {
		unget_char(ch1, tok);
		return 1;
	}
	if (tok->encoding != NULL)
		PyMem_FREE(tok->encoding);
	tok->encoding = new_string("utf-8", 5);	/* resulting is in utf-8 */
	/* No need to set_readline: input is already utf-8 */
	return 1;
}

/* Read a line of text from TOK into S, using the stream in TOK.
   Return NULL on failure, else S.

   On entry, tok->decoding_buffer will be one of:
     1) NULL: need to call tok->decoding_readline to get a new line
     2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and
           stored the result in tok->decoding_buffer
     3) PyByteArrayObject *: previous call to fp_readl did not have enough room
           (in the s buffer) to copy entire contents of the line read
           by tok->decoding_readline.  tok->decoding_buffer has the overflow.
           In this case, fp_readl is called in a loop (with an expanded buffer)
           until the buffer ends with a '\n' (or until the end of the file is
           reached): see tok_nextc and its calls to decoding_fgets.
*/

static char *
fp_readl(char *s, int size, struct tok_state *tok)
{
	PyObject* bufobj;
	const char *buf;
	Py_ssize_t buflen;

	/* Ask for one less byte so we can terminate it */
	assert(size > 0);
	size--;

	if (tok->decoding_buffer) {
		bufobj = tok->decoding_buffer;
		Py_INCREF(bufobj);
	}
	else
	{
		bufobj = PyObject_CallObject(tok->decoding_readline, NULL);
		if (bufobj == NULL)
			goto error;
	}
	if (PyUnicode_CheckExact(bufobj))
	{
		buf = _PyUnicode_AsStringAndSize(bufobj, &buflen);
		if (buf == NULL) {
			goto error;
		}
	}
	else
	{
		buf = PyByteArray_AsString(bufobj);
		if (buf == NULL) {
			goto error;
		}
		buflen = PyByteArray_GET_SIZE(bufobj);
	}

	Py_XDECREF(tok->decoding_buffer);
	if (buflen > size) {
		/* Too many chars, the rest goes into tok->decoding_buffer */
		tok->decoding_buffer = PyByteArray_FromStringAndSize(buf+size,
								 buflen-size);
		if (tok->decoding_buffer == NULL)
			goto error;
		buflen = size;
	}
	else
		tok->decoding_buffer = NULL;

	memcpy(s, buf, buflen);
	s[buflen] = '\0';
	if (buflen == 0) /* EOF */
		s = NULL;
	Py_DECREF(bufobj);
	return s;

error:
	Py_XDECREF(bufobj);
	return error_ret(tok);
}

/* Set the readline function for TOK to a StreamReader's
   readline function. The StreamReader is named ENC.

   This function is called from check_bom and check_coding_spec.

   ENC is usually identical to the future value of tok->encoding,
   except for the (currently unsupported) case of UTF-16.

   Return 1 on success, 0 on failure. */

static int
fp_setreadl(struct tok_state *tok, const char* enc)
{
	PyObject *readline = NULL, *stream = NULL, *io = NULL;

	io = PyImport_ImportModuleNoBlock("io");
	if (io == NULL)
		goto cleanup;

	if (tok->filename)
		stream = PyObject_CallMethod(io, "open", "ssis",
					     tok->filename, "r", -1, enc);
	else
		stream = PyObject_CallMethod(io, "open", "isisOOO",
				fileno(tok->fp), "r", -1, enc, Py_None, Py_None, Py_False);
	if (stream == NULL)
		goto cleanup;

	Py_XDECREF(tok->decoding_readline);
	readline = PyObject_GetAttrString(stream, "readline");
	tok->decoding_readline = readline;

	/* The file has been reopened; parsing will restart from
	 * the beginning of the file, we have to reset the line number.
	 * But this function has been called from inside tok_nextc() which
	 * will increment lineno before it returns. So we set it -1 so that
	 * the next call to tok_nextc() will start with tok->lineno == 0.
	 */
	tok->lineno = -1;

  cleanup:
	Py_XDECREF(stream);
	Py_XDECREF(io);
	return readline != NULL;
}

/* Fetch the next byte from TOK. */

static int fp_getc(struct tok_state *tok) {
	return getc(tok->fp);
}

/* Unfetch the last byte back into TOK.  */

static void fp_ungetc(int c, struct tok_state *tok) {
	ungetc(c, tok->fp);
}

/* Check whether the characters at s start a valid
   UTF-8 sequence. Return the number of characters forming
   the sequence if yes, 0 if not.  */
static int valid_utf8(const unsigned char* s)
{
	int expected = 0;
	int length;
	if (*s < 0x80)
		/* single-byte code */
		return 1;
	if (*s < 0xc0)
		/* following byte */
		return 0;
	if (*s < 0xE0)
		expected = 1;
	else if (*s < 0xF0)
		expected = 2;
	else if (*s < 0xF8)
		expected = 3;
	else
		return 0;
	length = expected + 1;
	for (; expected; expected--)
		if (s[expected] < 0x80 || s[expected] >= 0xC0)
			return 0;
	return length;
}

/* Read a line of input from TOK. Determine encoding
   if necessary.  */

static char *
decoding_fgets(char *s, int size, struct tok_state *tok)
{
	char *line = NULL;
	int badchar = 0;
	for (;;) {
		if (tok->decoding_state == STATE_NORMAL) {
			/* We already have a codec associated with
			   this input. */
			line = fp_readl(s, size, tok);
			break;
		} else if (tok->decoding_state == STATE_RAW) {
			/* We want a 'raw' read. */
			line = Py_UniversalNewlineFgets(s, size,
							tok->fp, NULL);
			break;
		} else {
			/* We have not yet determined the encoding.
			   If an encoding is found, use the file-pointer
			   reader functions from now on. */
			if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok))
				return error_ret(tok);
			assert(tok->decoding_state != STATE_INIT);
		}
	}
	if (line != NULL && tok->lineno < 2 && !tok->read_coding_spec) {
		if (!check_coding_spec(line, strlen(line), tok, fp_setreadl)) {
			return error_ret(tok);
		}
	}
#ifndef PGEN
	/* The default encoding is UTF-8, so make sure we don't have any
           non-UTF-8 sequences in it. */
	if (line && !tok->encoding) {
		unsigned char *c;
		int length;
		for (c = (unsigned char *)line; *c; c += length)
			if (!(length = valid_utf8(c))) {
				badchar = *c;
				break;
			}
	}
	if (badchar) {
		char buf[500];
		/* Need to add 1 to the line number, since this line
		   has not been counted, yet.  */
		sprintf(buf,
			"Non-UTF-8 code starting with '\\x%.2x' "
			"in file %.200s on line %i, "
			"but no encoding declared; "
			"see http://python.org/dev/peps/pep-0263/ for details",
			badchar, tok->filename, tok->lineno + 1);
		PyErr_SetString(PyExc_SyntaxError, buf);
		return error_ret(tok);
	}
#endif
	return line;
}

static int
decoding_feof(struct tok_state *tok)
{
	if (tok->decoding_state != STATE_NORMAL) {
		return feof(tok->fp);
	} else {
		PyObject* buf = tok->decoding_buffer;
		if (buf == NULL) {
			buf = PyObject_CallObject(tok->decoding_readline, NULL);
			if (buf == NULL) {
				error_ret(tok);
				return 1;
			} else {
				tok->decoding_buffer = buf;
			}
		}
		return PyObject_Length(buf) == 0;
	}
}

/* Fetch a byte from TOK, using the string buffer. */

static int
buf_getc(struct tok_state *tok) {
	return Py_CHARMASK(*tok->str++);
}

/* Unfetch a byte from TOK, using the string buffer. */

static void
buf_ungetc(int c, struct tok_state *tok) {
	tok->str--;
	assert(Py_CHARMASK(*tok->str) == c);	/* tok->cur may point to read-only segment */
}

/* Set the readline function for TOK to ENC. For the string-based
   tokenizer, this means to just record the encoding. */

static int
buf_setreadl(struct tok_state *tok, const char* enc) {
	tok->enc = enc;
	return 1;
}

/* Return a UTF-8 encoding Python string object from the
   C byte string STR, which is encoded with ENC. */

static PyObject *
translate_into_utf8(const char* str, const char* enc) {
	PyObject *utf8;
	PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL);
	if (buf == NULL)
		return NULL;
	utf8 = PyUnicode_AsUTF8String(buf);
	Py_DECREF(buf);
	return utf8;
}


static char *
translate_newlines(const char *s, int exec_input, struct tok_state *tok) {
	int skip_next_lf = 0, needed_length = strlen(s) + 2, final_length;
	char *buf, *current;
	char c = '\0';
	buf = PyMem_MALLOC(needed_length);
	if (buf == NULL) {
		tok->done = E_NOMEM;
		return NULL;
	}
	for (current = buf; *s; s++, current++) {
		c = *s;
		if (skip_next_lf) {
			skip_next_lf = 0;
			if (c == '\n') {
				c = *++s;
				if (!c)
					break;
			}
		}
		if (c == '\r') {
			skip_next_lf = 1;
			c = '\n';
		}
		*current = c;
	}
	/* If this is exec input, add a newline to the end of the string if
	   there isn't one already. */
	if (exec_input && c != '\n') {
		*current = '\n';
		current++;
	}
	*current = '\0';
	final_length = current - buf + 1;
	if (final_length < needed_length && final_length)
		/* should never fail */
		buf = PyMem_REALLOC(buf, final_length);
	return buf;
}

/* Decode a byte string STR for use as the buffer of TOK.
   Look for encoding declarations inside STR, and record them
   inside TOK.  */

static const char *
decode_str(const char *input, int single, struct tok_state *tok)
{
	PyObject* utf8 = NULL;
	const char *str;
	const char *s;
	const char *newl[2] = {NULL, NULL};
	int lineno = 0;
	tok->input = str = translate_newlines(input, single, tok);
	if (str == NULL)
		return NULL;
	tok->enc = NULL;
	tok->str = str;
	if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok))
		return error_ret(tok);
	str = tok->str;		/* string after BOM if any */
	assert(str);
	if (tok->enc != NULL) {
		utf8 = translate_into_utf8(str, tok->enc);
		if (utf8 == NULL)
			return error_ret(tok);
		str = PyBytes_AsString(utf8);
	}
	for (s = str;; s++) {
		if (*s == '\0') break;
		else if (*s == '\n') {
			assert(lineno < 2);
			newl[lineno] = s;
			lineno++;
			if (lineno == 2) break;
		}
	}
	tok->enc = NULL;
	/* need to check line 1 and 2 separately since check_coding_spec
	   assumes a single line as input */
	if (newl[0]) {
		if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl))
			return error_ret(tok);
		if (tok->enc == NULL && newl[1]) {
			if (!check_coding_spec(newl[0]+1, newl[1] - newl[0],
					       tok, buf_setreadl))
				return error_ret(tok);
		}
	}
	if (tok->enc != NULL) {
		assert(utf8 == NULL);
		utf8 = translate_into_utf8(str, tok->enc);
		if (utf8 == NULL)
			return error_ret(tok);
		str = PyBytes_AS_STRING(utf8);
	}
	assert(tok->decoding_buffer == NULL);
	tok->decoding_buffer = utf8; /* CAUTION */
	return str;
}

#endif /* PGEN */

/* Set up tokenizer for string */

struct tok_state *
PyTokenizer_FromString(const char *str, int exec_input)
{
	struct tok_state *tok = tok_new();
	if (tok == NULL)
		return NULL;
	str = (char *)decode_str(str, exec_input, tok);
	if (str == NULL) {
		PyTokenizer_Free(tok);
		return NULL;
	}

	/* XXX: constify members. */
	tok->buf = tok->cur = tok->end = tok->inp = (char*)str;
	return tok;
}

struct tok_state *
PyTokenizer_FromUTF8(const char *str, int exec_input)
{
	struct tok_state *tok = tok_new();
	if (tok == NULL)
		return NULL;
#ifndef PGEN
	tok->input = str = translate_newlines(str, exec_input, tok);
#endif
	if (str == NULL) {
		PyTokenizer_Free(tok);
		return NULL;
	}
	tok->decoding_state = STATE_RAW;
	tok->read_coding_spec = 1;
	tok->enc = NULL;
	tok->str = str;
	tok->encoding = (char *)PyMem_MALLOC(6);
	if (!tok->encoding) {
		PyTokenizer_Free(tok);
		return NULL;
	}
	strcpy(tok->encoding, "utf-8");

	/* XXX: constify members. */
	tok->buf = tok->cur = tok->end = tok->inp = (char*)str;
	return tok;
}

/* Set up tokenizer for file */

struct tok_state *
PyTokenizer_FromFile(FILE *fp, char* enc, char *ps1, char *ps2)
{
	struct tok_state *tok = tok_new();
	if (tok == NULL)
		return NULL;
	if ((tok->buf = (char *)PyMem_MALLOC(BUFSIZ)) == NULL) {
		PyTokenizer_Free(tok);
		return NULL;
	}
	tok->cur = tok->inp = tok->buf;
	tok->end = tok->buf + BUFSIZ;
	tok->fp = fp;
	tok->prompt = ps1;
	tok->nextprompt = ps2;
	if (enc != NULL) {
		/* Must copy encoding declaration since it
		   gets copied into the parse tree. */
		tok->encoding = PyMem_MALLOC(strlen(enc)+1);
		if (!tok->encoding) {
			PyTokenizer_Free(tok);
			return NULL;
		}
		strcpy(tok->encoding, enc);
		tok->decoding_state = STATE_NORMAL;
	}
	return tok;
}


/* Free a tok_state structure */

void
PyTokenizer_Free(struct tok_state *tok)
{
	if (tok->encoding != NULL)
		PyMem_FREE(tok->encoding);
#ifndef PGEN
	Py_XDECREF(tok->decoding_readline);
	Py_XDECREF(tok->decoding_buffer);
#endif
	if (tok->fp != NULL && tok->buf != NULL)
		PyMem_FREE(tok->buf);
	if (tok->input)
		PyMem_FREE((char *)tok->input);
	PyMem_FREE(tok);
}

/* Get next char, updating state; error code goes into tok->done */

static int
tok_nextc(register struct tok_state *tok)
{
	for (;;) {
		if (tok->cur != tok->inp) {
			return Py_CHARMASK(*tok->cur++); /* Fast path */
		}
		if (tok->done != E_OK)
			return EOF;
		if (tok->fp == NULL) {
			char *end = strchr(tok->inp, '\n');
			if (end != NULL)
				end++;
			else {
				end = strchr(tok->inp, '\0');
				if (end == tok->inp) {
					tok->done = E_EOF;
					return EOF;
				}
			}
			if (tok->start == NULL)
				tok->buf = tok->cur;
			tok->line_start = tok->cur;
			tok->lineno++;
			tok->inp = end;
			return Py_CHARMASK(*tok->cur++);
		}
		if (tok->prompt != NULL) {
			char *newtok = PyOS_Readline(stdin, stdout, tok->prompt);
#ifndef PGEN
			if (tok->encoding && newtok && *newtok) {
				/* Recode to UTF-8 */
				Py_ssize_t buflen;
				const char* buf;
				PyObject *u = translate_into_utf8(newtok, tok->encoding);
				PyMem_FREE(newtok);
				if (!u) {
					tok->done = E_DECODE;
					return EOF;
				}
				buflen = PyBytes_GET_SIZE(u);
				buf = PyBytes_AS_STRING(u);
				if (!buf) {
					Py_DECREF(u);
					tok->done = E_DECODE;
					return EOF;
				}
				newtok = PyMem_MALLOC(buflen+1);
				strcpy(newtok, buf);
				Py_DECREF(u);
			}
#endif
			if (tok->nextprompt != NULL)
				tok->prompt = tok->nextprompt;
			if (newtok == NULL)
				tok->done = E_INTR;
			else if (*newtok == '\0') {
				PyMem_FREE(newtok);
				tok->done = E_EOF;
			}
			else if (tok->start != NULL) {
				size_t start = tok->start - tok->buf;
				size_t oldlen = tok->cur - tok->buf;
				size_t newlen = oldlen + strlen(newtok);
				char *buf = tok->buf;
				buf = (char *)PyMem_REALLOC(buf, newlen+1);
				tok->lineno++;
				if (buf == NULL) {
					PyMem_FREE(tok->buf);
					tok->buf = NULL;
					PyMem_FREE(newtok);
					tok->done = E_NOMEM;
					return EOF;
				}
				tok->buf = buf;
				tok->cur = tok->buf + oldlen;
				tok->line_start = tok->cur;
				strcpy(tok->buf + oldlen, newtok);
				PyMem_FREE(newtok);
				tok->inp = tok->buf + newlen;
				tok->end = tok->inp + 1;
				tok->start = tok->buf + start;
			}
			else {
				tok->lineno++;
				if (tok->buf != NULL)
					PyMem_FREE(tok->buf);
				tok->buf = newtok;
				tok->line_start = tok->buf;
				tok->cur = tok->buf;
				tok->line_start = tok->buf;
				tok->inp = strchr(tok->buf, '\0');
				tok->end = tok->inp + 1;
			}
		}
		else {
			int done = 0;
			Py_ssize_t cur = 0;
			char *pt;
			if (tok->start == NULL) {
				if (tok->buf == NULL) {
					tok->buf = (char *)
						PyMem_MALLOC(BUFSIZ);
					if (tok->buf == NULL) {
						tok->done = E_NOMEM;
						return EOF;
					}
					tok->end = tok->buf + BUFSIZ;
				}
				if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf),
					  tok) == NULL) {
					tok->done = E_EOF;
					done = 1;
				}
				else {
					tok->done = E_OK;
					tok->inp = strchr(tok->buf, '\0');
					done = tok->inp[-1] == '\n';
				}
			}
			else {
				cur = tok->cur - tok->buf;
				if (decoding_feof(tok)) {
					tok->done = E_EOF;
					done = 1;
				}
				else
					tok->done = E_OK;
			}
			tok->lineno++;
			/* Read until '\n' or EOF */
			while (!done) {
				Py_ssize_t curstart = tok->start == NULL ? -1 :
					          tok->start - tok->buf;
				Py_ssize_t curvalid = tok->inp - tok->buf;
				Py_ssize_t newsize = curvalid + BUFSIZ;
				char *newbuf = tok->buf;
				newbuf = (char *)PyMem_REALLOC(newbuf,
							       newsize);
				if (newbuf == NULL) {
					tok->done = E_NOMEM;
					tok->cur = tok->inp;
					return EOF;
				}
				tok->buf = newbuf;
				tok->inp = tok->buf + curvalid;
				tok->end = tok->buf + newsize;
				tok->start = curstart < 0 ? NULL :
					     tok->buf + curstart;
				if (decoding_fgets(tok->inp,
					       (int)(tok->end - tok->inp),
					       tok) == NULL) {
					/* Break out early on decoding
					   errors, as tok->buf will be NULL
					 */
					if (tok->decoding_erred)
						return EOF;
					/* Last line does not end in \n,
					   fake one */
					strcpy(tok->inp, "\n");
				}
				tok->inp = strchr(tok->inp, '\0');
				done = tok->inp[-1] == '\n';
			}
			if (tok->buf != NULL) {
				tok->cur = tok->buf + cur;
				tok->line_start = tok->cur;
				/* replace "\r\n" with "\n" */
				/* For Mac leave the \r, giving a syntax error */
				pt = tok->inp - 2;
				if (pt >= tok->buf && *pt == '\r') {
					*pt++ = '\n';
					*pt = '\0';
					tok->inp = pt;
				}
			}
		}
		if (tok->done != E_OK) {
			if (tok->prompt != NULL)
				PySys_WriteStderr("\n");
			tok->cur = tok->inp;
			return EOF;
		}
	}
	/*NOTREACHED*/
}


/* Back-up one character */

static void
tok_backup(register struct tok_state *tok, register int c)
{
	if (c != EOF) {
		if (--tok->cur < tok->buf)
			Py_FatalError("tok_backup: beginning of buffer");
		if (*tok->cur != c)
			*tok->cur = c;
	}
}


/* Return the token corresponding to a single character */

int
PyToken_OneChar(int c)
{
	switch (c) {
	case '(':	return LPAR;
	case ')':	return RPAR;
	case '[':	return LSQB;
	case ']':	return RSQB;
	case ':':	return COLON;
	case ',':	return COMMA;
	case ';':	return SEMI;
	case '+':	return PLUS;
	case '-':	return MINUS;
	case '*':	return STAR;
	case '/':	return SLASH;
	case '|':	return VBAR;
	case '&':	return AMPER;
	case '<':	return LESS;
	case '>':	return GREATER;
	case '=':	return EQUAL;
	case '.':	return DOT;
	case '%':	return PERCENT;
	case '{':	return LBRACE;
	case '}':	return RBRACE;
	case '^':	return CIRCUMFLEX;
	case '~':	return TILDE;
	case '@':       return AT;
	default:	return OP;
	}
}


int
PyToken_TwoChars(int c1, int c2)
{
	switch (c1) {
	case '=':
		switch (c2) {
		case '=':	return EQEQUAL;
		}
		break;
	case '!':
		switch (c2) {
		case '=':	return NOTEQUAL;
		}
		break;
	case '<':
		switch (c2) {
		case '>':	return NOTEQUAL;
		case '=':	return LESSEQUAL;
		case '<':	return LEFTSHIFT;
		}
		break;
	case '>':
		switch (c2) {
		case '=':	return GREATEREQUAL;
		case '>':	return RIGHTSHIFT;
		}
		break;
	case '+':
		switch (c2) {
		case '=':	return PLUSEQUAL;
		}
		break;
	case '-':
		switch (c2) {
		case '=':	return MINEQUAL;
		case '>':	return RARROW;
		}
		break;
	case '*':
		switch (c2) {
		case '*':	return DOUBLESTAR;
		case '=':	return STAREQUAL;
		}
		break;
	case '/':
		switch (c2) {
		case '/':	return DOUBLESLASH;
		case '=':	return SLASHEQUAL;
		}
		break;
	case '|':
		switch (c2) {
		case '=':	return VBAREQUAL;
		}
		break;
	case '%':
		switch (c2) {
		case '=':	return PERCENTEQUAL;
		}
		break;
	case '&':
		switch (c2) {
		case '=':	return AMPEREQUAL;
		}
		break;
	case '^':
		switch (c2) {
		case '=':	return CIRCUMFLEXEQUAL;
		}
		break;
	}
	return OP;
}

int
PyToken_ThreeChars(int c1, int c2, int c3)
{
	switch (c1) {
	case '<':
		switch (c2) {
		case '<':
			switch (c3) {
			case '=':
				return LEFTSHIFTEQUAL;
			}
			break;
		}
		break;
	case '>':
		switch (c2) {
		case '>':
			switch (c3) {
			case '=':
				return RIGHTSHIFTEQUAL;
			}
			break;
		}
		break;
	case '*':
		switch (c2) {
		case '*':
			switch (c3) {
			case '=':
				return DOUBLESTAREQUAL;
			}
			break;
		}
		break;
	case '/':
		switch (c2) {
		case '/':
			switch (c3) {
			case '=':
				return DOUBLESLASHEQUAL;
			}
			break;
		}
		break;
        case '.':
	        switch (c2) {
		case '.':
			switch (c3) {
			case '.':
				return ELLIPSIS;
			}
			break;
		}
		break;
	}
	return OP;
}

static int
indenterror(struct tok_state *tok)
{
	if (tok->alterror) {
		tok->done = E_TABSPACE;
		tok->cur = tok->inp;
		return 1;
	}
	if (tok->altwarning) {
		PySys_WriteStderr("%s: inconsistent use of tabs and spaces "
                                  "in indentation\n", tok->filename);
		tok->altwarning = 0;
	}
	return 0;
}

#ifdef PGEN
#define verify_identifier(tok) 1
#else
/* Verify that the identifier follows PEP 3131. */
static int
verify_identifier(struct tok_state *tok)
{
	PyObject *s;
	int result;
	s = PyUnicode_DecodeUTF8(tok->start, tok->cur - tok->start, NULL);
	if (s == NULL) {
		if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
			PyErr_Clear();
			tok->done = E_IDENTIFIER;
		} else {
			tok->done = E_ERROR;
		}
		return 0;
	}
	result = PyUnicode_IsIdentifier(s);
	Py_DECREF(s);
	if (result == 0)
		tok->done = E_IDENTIFIER;
	return result;
}
#endif

/* Get next token, after space stripping etc. */

static int
tok_get(register struct tok_state *tok, char **p_start, char **p_end)
{
	register int c;
	int blankline, nonascii;

	*p_start = *p_end = NULL;
  nextline:
	tok->start = NULL;
	blankline = 0;

	/* Get indentation level */
	if (tok->atbol) {
		register int col = 0;
		register int altcol = 0;
		tok->atbol = 0;
		for (;;) {
			c = tok_nextc(tok);
			if (c == ' ')
				col++, altcol++;
			else if (c == '\t') {
				col = (col/tok->tabsize + 1) * tok->tabsize;
				altcol = (altcol/tok->alttabsize + 1)
					* tok->alttabsize;
			}
			else if (c == '\014') /* Control-L (formfeed) */
				col = altcol = 0; /* For Emacs users */
			else
				break;
		}
		tok_backup(tok, c);
		if (c == '#' || c == '\n') {
			/* Lines with only whitespace and/or comments
			   shouldn't affect the indentation and are
			   not passed to the parser as NEWLINE tokens,
			   except *totally* empty lines in interactive
			   mode, which signal the end of a command group. */
			if (col == 0 && c == '\n' && tok->prompt != NULL)
				blankline = 0; /* Let it through */
			else
				blankline = 1; /* Ignore completely */
			/* We can't jump back right here since we still
			   may need to skip to the end of a comment */
		}
		if (!blankline && tok->level == 0) {
			if (col == tok->indstack[tok->indent]) {
				/* No change */
				if (altcol != tok->altindstack[tok->indent]) {
					if (indenterror(tok))
						return ERRORTOKEN;
				}
			}
			else if (col > tok->indstack[tok->indent]) {
				/* Indent -- always one */
				if (tok->indent+1 >= MAXINDENT) {
					tok->done = E_TOODEEP;
					tok->cur = tok->inp;
					return ERRORTOKEN;
				}
				if (altcol <= tok->altindstack[tok->indent]) {
					if (indenterror(tok))
						return ERRORTOKEN;
				}
				tok->pendin++;
				tok->indstack[++tok->indent] = col;
				tok->altindstack[tok->indent] = altcol;
			}
			else /* col < tok->indstack[tok->indent] */ {
				/* Dedent -- any number, must be consistent */
				while (tok->indent > 0 &&
					col < tok->indstack[tok->indent]) {
					tok->pendin--;
					tok->indent--;
				}
				if (col != tok->indstack[tok->indent]) {
					tok->done = E_DEDENT;
					tok->cur = tok->inp;
					return ERRORTOKEN;
				}
				if (altcol != tok->altindstack[tok->indent]) {
					if (indenterror(tok))
						return ERRORTOKEN;
				}
			}
		}
	}

	tok->start = tok->cur;

	/* Return pending indents/dedents */
	if (tok->pendin != 0) {
		if (tok->pendin < 0) {
			tok->pendin++;
			return DEDENT;
		}
		else {
			tok->pendin--;
			return INDENT;
		}
	}

 again:
	tok->start = NULL;
	/* Skip spaces */
	do {
		c = tok_nextc(tok);
	} while (c == ' ' || c == '\t' || c == '\014');

	/* Set start of current token */
	tok->start = tok->cur - 1;

	/* Skip comment */
	if (c == '#')
		while (c != EOF && c != '\n')
			c = tok_nextc(tok);

	/* Check for EOF and errors now */
	if (c == EOF) {
		return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN;
	}

	/* Identifier (most frequent token!) */
	nonascii = 0;
	if (is_potential_identifier_start(c)) {
		/* Process b"", r"" and br"" */
		if (c == 'b' || c == 'B') {
			c = tok_nextc(tok);
			if (c == '"' || c == '\'')
				goto letter_quote;
		}
		if (c == 'r' || c == 'R') {
			c = tok_nextc(tok);
			if (c == '"' || c == '\'')
				goto letter_quote;
	    }
		while (is_potential_identifier_char(c)) {
			if (c >= 128)
				nonascii = 1;
			c = tok_nextc(tok);
		}
		tok_backup(tok, c);
		if (nonascii &&
		    !verify_identifier(tok)) {
			tok->done = E_IDENTIFIER;
			return ERRORTOKEN;
		}
		*p_start = tok->start;
		*p_end = tok->cur;
		return NAME;
	}

	/* Newline */
	if (c == '\n') {
		tok->atbol = 1;
		if (blankline || tok->level > 0)
			goto nextline;
		*p_start = tok->start;
		*p_end = tok->cur - 1; /* Leave '\n' out of the string */
                tok->cont_line = 0;
		return NEWLINE;
	}

	/* Period or number starting with period? */
	if (c == '.') {
		c = tok_nextc(tok);
		if (isdigit(c)) {
			goto fraction;
		} else if (c == '.') {
			c = tok_nextc(tok);
			if (c == '.') {
				*p_start = tok->start;
				*p_end = tok->cur;
				return ELLIPSIS;
			} else {
				tok_backup(tok, c);
			}
			tok_backup(tok, '.');
		} else {
			tok_backup(tok, c);
		}
		*p_start = tok->start;
		*p_end = tok->cur;
		return DOT;
	}

	/* Number */
	if (isdigit(c)) {
		if (c == '0') {
			/* Hex, octal or binary -- maybe. */
			c = tok_nextc(tok);
			if (c == '.')
				goto fraction;
			if (c == 'j' || c == 'J')
				goto imaginary;
			if (c == 'x' || c == 'X') {

				/* Hex */
				c = tok_nextc(tok);
				if (!isxdigit(c)) {
					tok->done = E_TOKEN;
					tok_backup(tok, c);
					return ERRORTOKEN;
				}
				do {
					c = tok_nextc(tok);
				} while (isxdigit(c));
			}
                        else if (c == 'o' || c == 'O') {
				/* Octal */
				c = tok_nextc(tok);
				if (c < '0' || c >= '8') {
					tok->done = E_TOKEN;
					tok_backup(tok, c);
					return ERRORTOKEN;
				}
				do {
					c = tok_nextc(tok);
				} while ('0' <= c && c < '8');
			}
			else if (c == 'b' || c == 'B') {
				/* Binary */
				c = tok_nextc(tok);
				if (c != '0' && c != '1') {
					tok->done = E_TOKEN;
					tok_backup(tok, c);
					return ERRORTOKEN;
				}
				do {
					c = tok_nextc(tok);
				} while (c == '0' || c == '1');
			}
			else {
				int nonzero = 0;
				/* maybe old-style octal; c is first char of it */
				/* in any case, allow '0' as a literal */
				while (c == '0')
					c = tok_nextc(tok);
				while (isdigit(c)) {
					nonzero = 1;
					c = tok_nextc(tok);
				}
				if (c == '.')
					goto fraction;
				else if (c == 'e' || c == 'E')
					goto exponent;
				else if (c == 'j' || c == 'J')
					goto imaginary;
				else if (nonzero) {
					tok->done = E_TOKEN;
					tok_backup(tok, c);
					return ERRORTOKEN;
				}
			}
		}
		else {
			/* Decimal */
			do {
				c = tok_nextc(tok);
			} while (isdigit(c));
			{
				/* Accept floating point numbers. */
				if (c == '.') {
		fraction:
					/* Fraction */
					do {
						c = tok_nextc(tok);
					} while (isdigit(c));
				}
				if (c == 'e' || c == 'E') {
		exponent:
					/* Exponent part */
					c = tok_nextc(tok);
					if (c == '+' || c == '-')
						c = tok_nextc(tok);
					if (!isdigit(c)) {
						tok->done = E_TOKEN;
						tok_backup(tok, c);
						return ERRORTOKEN;
					}
					do {
						c = tok_nextc(tok);
					} while (isdigit(c));
				}
				if (c == 'j' || c == 'J')
					/* Imaginary part */
		imaginary:
					c = tok_nextc(tok);
			}
		}
		tok_backup(tok, c);
		*p_start = tok->start;
		*p_end = tok->cur;
		return NUMBER;
	}

  letter_quote:
	/* String */
	if (c == '\'' || c == '"') {
 		int quote = c;
		int quote_size = 1;             /* 1 or 3 */
		int end_quote_size = 0;

		/* Find the quote size and start of string */
		c = tok_nextc(tok);
		if (c == quote) {
 			c = tok_nextc(tok);
			if (c == quote)
				quote_size = 3;
			else
				end_quote_size = 1;     /* empty string found */
		}
		if (c != quote)
		    tok_backup(tok, c);

		/* Get rest of string */
		while (end_quote_size != quote_size) {
 			c = tok_nextc(tok);
  			if (c == EOF) {
				if (quote_size == 3)
 					tok->done = E_EOFS;
 				else
 					tok->done = E_EOLS;
 				tok->cur = tok->inp;
 				return ERRORTOKEN;
 			}
 			if (quote_size == 1 && c == '\n') {
 			    tok->done = E_EOLS;
 			    tok->cur = tok->inp;
 			    return ERRORTOKEN;
 			}
 			if (c == quote)
 			    end_quote_size += 1;
 			else {
 			    end_quote_size = 0;
 			    if (c == '\\')
 			        c = tok_nextc(tok);  /* skip escaped char */
 			}
 		}

		*p_start = tok->start;
		*p_end = tok->cur;
		return STRING;
	}

	/* Line continuation */
	if (c == '\\') {
		c = tok_nextc(tok);
		if (c != '\n') {
			tok->done = E_LINECONT;
			tok->cur = tok->inp;
			return ERRORTOKEN;
		}
                tok->cont_line = 1;
		goto again; /* Read next line */
	}

	/* Check for two-character token */
	{
		int c2 = tok_nextc(tok);
		int token = PyToken_TwoChars(c, c2);
		if (token != OP) {
			int c3 = tok_nextc(tok);
			int token3 = PyToken_ThreeChars(c, c2, c3);
			if (token3 != OP) {
				token = token3;
			} else {
				tok_backup(tok, c3);
			}
			*p_start = tok->start;
			*p_end = tok->cur;
			return token;
		}
		tok_backup(tok, c2);
	}

	/* Keep track of parentheses nesting level */
	switch (c) {
	case '(':
	case '[':
	case '{':
		tok->level++;
		break;
	case ')':
	case ']':
	case '}':
		tok->level--;
		break;
	}

	/* Punctuation character */
	*p_start = tok->start;
	*p_end = tok->cur;
	return PyToken_OneChar(c);
}

int
PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end)
{
	int result = tok_get(tok, p_start, p_end);
	if (tok->decoding_erred) {
		result = ERRORTOKEN;
		tok->done = E_DECODE;
	}
	return result;
}

/* Get -*- encoding -*- from a Python file.

   PyTokenizer_FindEncoding returns NULL when it can't find the encoding in
   the first or second line of the file (in which case the encoding
   should be assumed to be PyUnicode_GetDefaultEncoding()).

   The char * returned is malloc'ed via PyMem_MALLOC() and thus must be freed
   by the caller.
*/
char *
PyTokenizer_FindEncoding(int fd)
{
	struct tok_state *tok;
	FILE *fp;
	char *p_start =NULL , *p_end =NULL , *encoding = NULL;

	fd = dup(fd);
	if (fd < 0) {
		return NULL;
	}
	fp = fdopen(fd, "r");
	if (fp == NULL) {
		return NULL;
	}
	tok = PyTokenizer_FromFile(fp, NULL, NULL, NULL);
	if (tok == NULL) {
		fclose(fp);
		return NULL;
	}
	while (tok->lineno < 2 && tok->done == E_OK) {
		PyTokenizer_Get(tok, &p_start, &p_end);
	}
	fclose(fp);
	if (tok->encoding) {
            encoding = (char *)PyMem_MALLOC(strlen(tok->encoding) + 1);
            if (encoding)
                strcpy(encoding, tok->encoding);
        }
	PyTokenizer_Free(tok);
	return encoding;
}

#ifdef Py_DEBUG

void
tok_dump(int type, char *start, char *end)
{
	printf("%s", _PyParser_TokenNames[type]);
	if (type == NAME || type == NUMBER || type == STRING || type == OP)
		printf("(%.*s)", (int)(end - start), start);
}

#endif
