Line data Source code
1 :
2 : /* Tokenizer implementation */
3 :
4 : #include "Python.h"
5 : #include "pgenheaders.h"
6 :
7 : #include <ctype.h>
8 : #include <assert.h>
9 :
10 : #include "tokenizer.h"
11 : #include "errcode.h"
12 :
13 : #ifndef PGEN
14 : #include "unicodeobject.h"
15 : #include "stringobject.h"
16 : #include "fileobject.h"
17 : #include "codecs.h"
18 : #include "abstract.h"
19 : #include "pydebug.h"
20 : #endif /* PGEN */
21 :
22 : extern char *PyOS_Readline(FILE *, FILE *, char *);
23 : /* Return malloc'ed string including trailing \n;
24 : empty malloc'ed string for EOF;
25 : NULL if interrupted */
26 :
27 : /* Don't ever change this -- it would break the portability of Python code */
28 : #define TABSIZE 8
29 :
30 : /* Forward */
31 : static struct tok_state *tok_new(void);
32 : static int tok_nextc(struct tok_state *tok);
33 : static void tok_backup(struct tok_state *tok, int c);
34 :
35 : /* Token names */
36 :
37 : char *_PyParser_TokenNames[] = {
38 : "ENDMARKER",
39 : "NAME",
40 : "NUMBER",
41 : "STRING",
42 : "NEWLINE",
43 : "INDENT",
44 : "DEDENT",
45 : "LPAR",
46 : "RPAR",
47 : "LSQB",
48 : "RSQB",
49 : "COLON",
50 : "COMMA",
51 : "SEMI",
52 : "PLUS",
53 : "MINUS",
54 : "STAR",
55 : "SLASH",
56 : "VBAR",
57 : "AMPER",
58 : "LESS",
59 : "GREATER",
60 : "EQUAL",
61 : "DOT",
62 : "PERCENT",
63 : "BACKQUOTE",
64 : "LBRACE",
65 : "RBRACE",
66 : "EQEQUAL",
67 : "NOTEQUAL",
68 : "LESSEQUAL",
69 : "GREATEREQUAL",
70 : "TILDE",
71 : "CIRCUMFLEX",
72 : "LEFTSHIFT",
73 : "RIGHTSHIFT",
74 : "DOUBLESTAR",
75 : "PLUSEQUAL",
76 : "MINEQUAL",
77 : "STAREQUAL",
78 : "SLASHEQUAL",
79 : "PERCENTEQUAL",
80 : "AMPEREQUAL",
81 : "VBAREQUAL",
82 : "CIRCUMFLEXEQUAL",
83 : "LEFTSHIFTEQUAL",
84 : "RIGHTSHIFTEQUAL",
85 : "DOUBLESTAREQUAL",
86 : "DOUBLESLASH",
87 : "DOUBLESLASHEQUAL",
88 : "AT",
89 : /* This table must match the #defines in token.h! */
90 : "OP",
91 : "<ERRORTOKEN>",
92 : "<N_TOKENS>"
93 : };
94 :
95 : /* Create and initialize a new tok_state structure */
96 :
97 : static struct tok_state *
98 63 : tok_new(void)
99 : {
100 63 : struct tok_state *tok = (struct tok_state *)PyMem_MALLOC(
101 : sizeof(struct tok_state));
102 63 : if (tok == NULL)
103 0 : return NULL;
104 63 : tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL;
105 63 : tok->done = E_OK;
106 63 : tok->fp = NULL;
107 63 : tok->input = NULL;
108 63 : tok->tabsize = TABSIZE;
109 63 : tok->indent = 0;
110 63 : tok->indstack[0] = 0;
111 63 : tok->atbol = 1;
112 63 : tok->pendin = 0;
113 63 : tok->prompt = tok->nextprompt = NULL;
114 63 : tok->lineno = 0;
115 63 : tok->level = 0;
116 63 : tok->filename = NULL;
117 63 : tok->altwarning = 0;
118 63 : tok->alterror = 0;
119 63 : tok->alttabsize = 1;
120 63 : tok->altindstack[0] = 0;
121 63 : tok->decoding_state = 0;
122 63 : tok->decoding_erred = 0;
123 63 : tok->read_coding_spec = 0;
124 63 : tok->encoding = NULL;
125 63 : tok->cont_line = 0;
126 : #ifndef PGEN
127 63 : tok->decoding_readline = NULL;
128 63 : tok->decoding_buffer = NULL;
129 : #endif
130 63 : return tok;
131 : }
132 :
133 : static char *
134 0 : new_string(const char *s, Py_ssize_t len)
135 : {
136 0 : char* result = (char *)PyMem_MALLOC(len + 1);
137 0 : if (result != NULL) {
138 0 : memcpy(result, s, len);
139 0 : result[len] = '\0';
140 : }
141 0 : return result;
142 : }
143 :
144 : #ifdef PGEN
145 :
146 : static char *
147 : decoding_fgets(char *s, int size, struct tok_state *tok)
148 : {
149 : return fgets(s, size, tok->fp);
150 : }
151 :
152 : static int
153 : decoding_feof(struct tok_state *tok)
154 : {
155 : return feof(tok->fp);
156 : }
157 :
158 : static char *
159 : decode_str(const char *str, int exec_input, struct tok_state *tok)
160 : {
161 : return new_string(str, strlen(str));
162 : }
163 :
164 : #else /* PGEN */
165 :
166 : static char *
167 0 : error_ret(struct tok_state *tok) /* XXX */
168 : {
169 0 : tok->decoding_erred = 1;
170 0 : if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */
171 0 : PyMem_FREE(tok->buf);
172 0 : tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL;
173 0 : tok->done = E_DECODE;
174 0 : return NULL; /* as if it were EOF */
175 : }
176 :
177 :
178 : static char *
179 0 : get_normal_name(char *s) /* for utf-8 and latin-1 */
180 : {
181 : char buf[13];
182 : int i;
183 0 : for (i = 0; i < 12; i++) {
184 0 : int c = s[i];
185 0 : if (c == '\0')
186 0 : break;
187 0 : else if (c == '_')
188 0 : buf[i] = '-';
189 : else
190 0 : buf[i] = tolower(c);
191 : }
192 0 : buf[i] = '\0';
193 0 : if (strcmp(buf, "utf-8") == 0 ||
194 0 : strncmp(buf, "utf-8-", 6) == 0)
195 0 : return "utf-8";
196 0 : else if (strcmp(buf, "latin-1") == 0 ||
197 0 : strcmp(buf, "iso-8859-1") == 0 ||
198 0 : strcmp(buf, "iso-latin-1") == 0 ||
199 0 : strncmp(buf, "latin-1-", 8) == 0 ||
200 0 : strncmp(buf, "iso-8859-1-", 11) == 0 ||
201 0 : strncmp(buf, "iso-latin-1-", 12) == 0)
202 0 : return "iso-8859-1";
203 : else
204 0 : return s;
205 : }
206 :
207 : /* Return the coding spec in S, or NULL if none is found. */
208 :
209 : static char *
210 85 : get_coding_spec(const char *s, Py_ssize_t size)
211 : {
212 : Py_ssize_t i;
213 : /* Coding spec must be in a comment, and that comment must be
214 : * the only statement on the source code line. */
215 85 : for (i = 0; i < size - 6; i++) {
216 71 : if (s[i] == '#')
217 42 : break;
218 29 : if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014')
219 29 : return NULL;
220 : }
221 1195 : for (; i < size - 6; i++) { /* XXX inefficient search */
222 1139 : const char* t = s + i;
223 1139 : if (strncmp(t, "coding", 6) == 0) {
224 0 : const char* begin = NULL;
225 0 : t += 6;
226 0 : if (t[0] != ':' && t[0] != '=')
227 0 : continue;
228 : do {
229 0 : t++;
230 0 : } while (t[0] == '\x20' || t[0] == '\t');
231 :
232 0 : begin = t;
233 0 : while (Py_ISALNUM(t[0]) ||
234 0 : t[0] == '-' || t[0] == '_' || t[0] == '.')
235 0 : t++;
236 :
237 0 : if (begin < t) {
238 0 : char* r = new_string(begin, t - begin);
239 : char* q;
240 0 : if (!r)
241 0 : return NULL;
242 0 : q = get_normal_name(r);
243 0 : if (r != q) {
244 0 : PyMem_FREE(r);
245 0 : r = new_string(q, strlen(q));
246 : }
247 0 : return r;
248 : }
249 : }
250 : }
251 56 : return NULL;
252 : }
253 :
254 : /* Check whether the line contains a coding spec. If it does,
255 : invoke the set_readline function for the new encoding.
256 : This function receives the tok_state and the new encoding.
257 : Return 1 on success, 0 on failure. */
258 :
259 : static int
260 85 : check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok,
261 : int set_readline(struct tok_state *, const char *))
262 : {
263 : char * cs;
264 85 : int r = 1;
265 :
266 85 : if (tok->cont_line) {
267 : /* It's a continuation line, so it can't be a coding spec. */
268 0 : tok->read_coding_spec = 1;
269 0 : return 1;
270 : }
271 85 : cs = get_coding_spec(line, size);
272 85 : if (!cs) {
273 : Py_ssize_t i;
274 85 : for (i = 0; i < size; i++) {
275 85 : if (line[i] == '#' || line[i] == '\n' || line[i] == '\r')
276 : break;
277 43 : if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') {
278 : /* Stop checking coding spec after a line containing
279 : * anything except a comment. */
280 43 : tok->read_coding_spec = 1;
281 43 : break;
282 : }
283 : }
284 : } else {
285 0 : tok->read_coding_spec = 1;
286 0 : if (tok->encoding == NULL) {
287 : assert(tok->decoding_state == 1); /* raw */
288 0 : if (strcmp(cs, "utf-8") == 0 ||
289 0 : strcmp(cs, "iso-8859-1") == 0) {
290 0 : tok->encoding = cs;
291 : } else {
292 : #ifdef Py_USING_UNICODE
293 0 : r = set_readline(tok, cs);
294 0 : if (r) {
295 0 : tok->encoding = cs;
296 0 : tok->decoding_state = -1;
297 : }
298 : else {
299 0 : PyErr_Format(PyExc_SyntaxError,
300 : "encoding problem: %s", cs);
301 0 : PyMem_FREE(cs);
302 : }
303 : #else
304 : /* Without Unicode support, we cannot
305 : process the coding spec. Since there
306 : won't be any Unicode literals, that
307 : won't matter. */
308 : PyMem_FREE(cs);
309 : #endif
310 : }
311 : } else { /* then, compare cs with BOM */
312 0 : r = (strcmp(tok->encoding, cs) == 0);
313 0 : if (!r)
314 0 : PyErr_Format(PyExc_SyntaxError,
315 : "encoding problem: %s with BOM", cs);
316 0 : PyMem_FREE(cs);
317 : }
318 : }
319 85 : return r;
320 : }
321 :
322 : /* See whether the file starts with a BOM. If it does,
323 : invoke the set_readline function with the new encoding.
324 : Return 1 on success, 0 on failure. */
325 :
326 : static int
327 63 : check_bom(int get_char(struct tok_state *),
328 : void unget_char(int, struct tok_state *),
329 : int set_readline(struct tok_state *, const char *),
330 : struct tok_state *tok)
331 : {
332 : int ch1, ch2, ch3;
333 63 : ch1 = get_char(tok);
334 63 : tok->decoding_state = 1;
335 63 : if (ch1 == EOF) {
336 3 : return 1;
337 60 : } else if (ch1 == 0xEF) {
338 0 : ch2 = get_char(tok);
339 0 : if (ch2 != 0xBB) {
340 0 : unget_char(ch2, tok);
341 0 : unget_char(ch1, tok);
342 0 : return 1;
343 : }
344 0 : ch3 = get_char(tok);
345 0 : if (ch3 != 0xBF) {
346 0 : unget_char(ch3, tok);
347 0 : unget_char(ch2, tok);
348 0 : unget_char(ch1, tok);
349 0 : return 1;
350 : }
351 : #if 0
352 : /* Disable support for UTF-16 BOMs until a decision
353 : is made whether this needs to be supported. */
354 : } else if (ch1 == 0xFE) {
355 : ch2 = get_char(tok);
356 : if (ch2 != 0xFF) {
357 : unget_char(ch2, tok);
358 : unget_char(ch1, tok);
359 : return 1;
360 : }
361 : if (!set_readline(tok, "utf-16-be"))
362 : return 0;
363 : tok->decoding_state = -1;
364 : } else if (ch1 == 0xFF) {
365 : ch2 = get_char(tok);
366 : if (ch2 != 0xFE) {
367 : unget_char(ch2, tok);
368 : unget_char(ch1, tok);
369 : return 1;
370 : }
371 : if (!set_readline(tok, "utf-16-le"))
372 : return 0;
373 : tok->decoding_state = -1;
374 : #endif
375 : } else {
376 60 : unget_char(ch1, tok);
377 60 : return 1;
378 : }
379 0 : if (tok->encoding != NULL)
380 0 : PyMem_FREE(tok->encoding);
381 0 : tok->encoding = new_string("utf-8", 5); /* resulting is in utf-8 */
382 0 : return 1;
383 : }
384 :
385 : /* Read a line of text from TOK into S, using the stream in TOK.
386 : Return NULL on failure, else S.
387 :
388 : On entry, tok->decoding_buffer will be one of:
389 : 1) NULL: need to call tok->decoding_readline to get a new line
390 : 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and
391 : stored the result in tok->decoding_buffer
392 : 3) PyStringObject *: previous call to fp_readl did not have enough room
393 : (in the s buffer) to copy entire contents of the line read
394 : by tok->decoding_readline. tok->decoding_buffer has the overflow.
395 : In this case, fp_readl is called in a loop (with an expanded buffer)
396 : until the buffer ends with a '\n' (or until the end of the file is
397 : reached): see tok_nextc and its calls to decoding_fgets.
398 : */
399 :
400 : static char *
401 0 : fp_readl(char *s, int size, struct tok_state *tok)
402 : {
403 : #ifndef Py_USING_UNICODE
404 : /* In a non-Unicode built, this should never be called. */
405 : Py_FatalError("fp_readl should not be called in this build.");
406 : return NULL; /* Keep compiler happy (not reachable) */
407 : #else
408 0 : PyObject* utf8 = NULL;
409 0 : PyObject* buf = tok->decoding_buffer;
410 : char *str;
411 : Py_ssize_t utf8len;
412 :
413 : /* Ask for one less byte so we can terminate it */
414 : assert(size > 0);
415 0 : size--;
416 :
417 0 : if (buf == NULL) {
418 0 : buf = PyObject_CallObject(tok->decoding_readline, NULL);
419 0 : if (buf == NULL)
420 0 : return error_ret(tok);
421 0 : if (!PyUnicode_Check(buf)) {
422 0 : Py_DECREF(buf);
423 0 : PyErr_SetString(PyExc_SyntaxError,
424 : "codec did not return a unicode object");
425 0 : return error_ret(tok);
426 : }
427 : } else {
428 0 : tok->decoding_buffer = NULL;
429 0 : if (PyString_CheckExact(buf))
430 0 : utf8 = buf;
431 : }
432 0 : if (utf8 == NULL) {
433 0 : utf8 = PyUnicode_AsUTF8String(buf);
434 0 : Py_DECREF(buf);
435 0 : if (utf8 == NULL)
436 0 : return error_ret(tok);
437 : }
438 0 : str = PyString_AsString(utf8);
439 0 : utf8len = PyString_GET_SIZE(utf8);
440 0 : if (utf8len > size) {
441 0 : tok->decoding_buffer = PyString_FromStringAndSize(str+size, utf8len-size);
442 0 : if (tok->decoding_buffer == NULL) {
443 0 : Py_DECREF(utf8);
444 0 : return error_ret(tok);
445 : }
446 0 : utf8len = size;
447 : }
448 0 : memcpy(s, str, utf8len);
449 0 : s[utf8len] = '\0';
450 0 : Py_DECREF(utf8);
451 0 : if (utf8len == 0)
452 0 : return NULL; /* EOF */
453 0 : return s;
454 : #endif
455 : }
456 :
457 : /* Set the readline function for TOK to a StreamReader's
458 : readline function. The StreamReader is named ENC.
459 :
460 : This function is called from check_bom and check_coding_spec.
461 :
462 : ENC is usually identical to the future value of tok->encoding,
463 : except for the (currently unsupported) case of UTF-16.
464 :
465 : Return 1 on success, 0 on failure. */
466 :
467 : static int
468 0 : fp_setreadl(struct tok_state *tok, const char* enc)
469 : {
470 : PyObject *reader, *stream, *readline;
471 :
472 : /* XXX: constify filename argument. */
473 0 : stream = PyFile_FromFile(tok->fp, (char*)tok->filename, "rb", NULL);
474 0 : if (stream == NULL)
475 0 : return 0;
476 :
477 0 : reader = PyCodec_StreamReader(enc, stream, NULL);
478 0 : Py_DECREF(stream);
479 0 : if (reader == NULL)
480 0 : return 0;
481 :
482 0 : readline = PyObject_GetAttrString(reader, "readline");
483 0 : Py_DECREF(reader);
484 0 : if (readline == NULL)
485 0 : return 0;
486 :
487 0 : tok->decoding_readline = readline;
488 0 : return 1;
489 : }
490 :
491 : /* Fetch the next byte from TOK. */
492 :
493 36 : static int fp_getc(struct tok_state *tok) {
494 36 : return getc(tok->fp);
495 : }
496 :
497 : /* Unfetch the last byte back into TOK. */
498 :
499 33 : static void fp_ungetc(int c, struct tok_state *tok) {
500 33 : ungetc(c, tok->fp);
501 33 : }
502 :
503 : /* Read a line of input from TOK. Determine encoding
504 : if necessary. */
505 :
506 : static char *
507 14686 : decoding_fgets(char *s, int size, struct tok_state *tok)
508 : {
509 14686 : char *line = NULL;
510 14686 : int badchar = 0;
511 : for (;;) {
512 14722 : if (tok->decoding_state < 0) {
513 : /* We already have a codec associated with
514 : this input. */
515 0 : line = fp_readl(s, size, tok);
516 0 : break;
517 14722 : } else if (tok->decoding_state > 0) {
518 : /* We want a 'raw' read. */
519 14686 : line = Py_UniversalNewlineFgets(s, size,
520 : tok->fp, NULL);
521 14686 : break;
522 : } else {
523 : /* We have not yet determined the encoding.
524 : If an encoding is found, use the file-pointer
525 : reader functions from now on. */
526 36 : if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok))
527 0 : return error_ret(tok);
528 : assert(tok->decoding_state != 0);
529 : }
530 36 : }
531 14686 : if (line != NULL && tok->lineno < 2 && !tok->read_coding_spec) {
532 58 : if (!check_coding_spec(line, strlen(line), tok, fp_setreadl)) {
533 0 : return error_ret(tok);
534 : }
535 : }
536 : #ifndef PGEN
537 : /* The default encoding is ASCII, so make sure we don't have any
538 : non-ASCII bytes in it. */
539 14686 : if (line && !tok->encoding) {
540 : unsigned char *c;
541 441001 : for (c = (unsigned char *)line; *c; c++)
542 426351 : if (*c > 127) {
543 0 : badchar = *c;
544 0 : break;
545 : }
546 : }
547 14686 : if (badchar) {
548 : char buf[500];
549 : /* Need to add 1 to the line number, since this line
550 : has not been counted, yet. */
551 0 : sprintf(buf,
552 : "Non-ASCII character '\\x%.2x' "
553 : "in file %.200s on line %i, "
554 : "but no encoding declared; "
555 : "see http://python.org/dev/peps/pep-0263/ for details",
556 0 : badchar, tok->filename, tok->lineno + 1);
557 0 : PyErr_SetString(PyExc_SyntaxError, buf);
558 0 : return error_ret(tok);
559 : }
560 : #endif
561 14686 : return line;
562 : }
563 :
564 : static int
565 1734 : decoding_feof(struct tok_state *tok)
566 : {
567 1734 : if (tok->decoding_state >= 0) {
568 1734 : return feof(tok->fp);
569 : } else {
570 0 : PyObject* buf = tok->decoding_buffer;
571 0 : if (buf == NULL) {
572 0 : buf = PyObject_CallObject(tok->decoding_readline, NULL);
573 0 : if (buf == NULL) {
574 0 : error_ret(tok);
575 0 : return 1;
576 : } else {
577 0 : tok->decoding_buffer = buf;
578 : }
579 : }
580 0 : return PyObject_Length(buf) == 0;
581 : }
582 : }
583 :
584 : /* Fetch a byte from TOK, using the string buffer. */
585 :
586 : static int
587 27 : buf_getc(struct tok_state *tok) {
588 27 : return Py_CHARMASK(*tok->str++);
589 : }
590 :
591 : /* Unfetch a byte from TOK, using the string buffer. */
592 :
593 : static void
594 27 : buf_ungetc(int c, struct tok_state *tok) {
595 27 : tok->str--;
596 : assert(Py_CHARMASK(*tok->str) == c); /* tok->cur may point to read-only segment */
597 27 : }
598 :
599 : /* Set the readline function for TOK to ENC. For the string-based
600 : tokenizer, this means to just record the encoding. */
601 :
602 : static int
603 0 : buf_setreadl(struct tok_state *tok, const char* enc) {
604 0 : tok->enc = enc;
605 0 : return 1;
606 : }
607 :
608 : /* Return a UTF-8 encoding Python string object from the
609 : C byte string STR, which is encoded with ENC. */
610 :
611 : #ifdef Py_USING_UNICODE
612 : static PyObject *
613 0 : translate_into_utf8(const char* str, const char* enc) {
614 : PyObject *utf8;
615 0 : PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL);
616 0 : if (buf == NULL)
617 0 : return NULL;
618 0 : utf8 = PyUnicode_AsUTF8String(buf);
619 0 : Py_DECREF(buf);
620 0 : return utf8;
621 : }
622 : #endif
623 :
624 :
625 : static char *
626 27 : translate_newlines(const char *s, int exec_input, struct tok_state *tok) {
627 27 : int skip_next_lf = 0, needed_length = strlen(s) + 2, final_length;
628 : char *buf, *current;
629 27 : char c = '\0';
630 27 : buf = PyMem_MALLOC(needed_length);
631 27 : if (buf == NULL) {
632 0 : tok->done = E_NOMEM;
633 0 : return NULL;
634 : }
635 50448 : for (current = buf; *s; s++, current++) {
636 50421 : c = *s;
637 50421 : if (skip_next_lf) {
638 0 : skip_next_lf = 0;
639 0 : if (c == '\n') {
640 0 : c = *++s;
641 0 : if (!c)
642 0 : break;
643 : }
644 : }
645 50421 : if (c == '\r') {
646 0 : skip_next_lf = 1;
647 0 : c = '\n';
648 : }
649 50421 : *current = c;
650 : }
651 : /* If this is exec input, add a newline to the end of the string if
652 : there isn't one already. */
653 27 : if (exec_input && c != '\n') {
654 0 : *current = '\n';
655 0 : current++;
656 : }
657 27 : *current = '\0';
658 27 : final_length = current - buf + 1;
659 27 : if (final_length < needed_length && final_length)
660 : /* should never fail */
661 27 : buf = PyMem_REALLOC(buf, final_length);
662 27 : return buf;
663 : }
664 :
665 : /* Decode a byte string STR for use as the buffer of TOK.
666 : Look for encoding declarations inside STR, and record them
667 : inside TOK. */
668 :
669 : static const char *
670 27 : decode_str(const char *input, int single, struct tok_state *tok)
671 : {
672 27 : PyObject* utf8 = NULL;
673 : const char *str;
674 : const char *s;
675 27 : const char *newl[2] = {NULL, NULL};
676 27 : int lineno = 0;
677 27 : tok->input = str = translate_newlines(input, single, tok);
678 27 : if (str == NULL)
679 0 : return NULL;
680 27 : tok->enc = NULL;
681 27 : tok->str = str;
682 27 : if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok))
683 0 : return error_ret(tok);
684 27 : str = tok->str; /* string after BOM if any */
685 : assert(str);
686 : #ifdef Py_USING_UNICODE
687 27 : if (tok->enc != NULL) {
688 0 : utf8 = translate_into_utf8(str, tok->enc);
689 0 : if (utf8 == NULL)
690 0 : return error_ret(tok);
691 0 : str = PyString_AsString(utf8);
692 : }
693 : #endif
694 2016 : for (s = str;; s++) {
695 2016 : if (*s == '\0') break;
696 2016 : else if (*s == '\n') {
697 : assert(lineno < 2);
698 54 : newl[lineno] = s;
699 54 : lineno++;
700 54 : if (lineno == 2) break;
701 : }
702 1989 : }
703 27 : tok->enc = NULL;
704 : /* need to check line 1 and 2 separately since check_coding_spec
705 : assumes a single line as input */
706 27 : if (newl[0]) {
707 27 : if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl))
708 0 : return error_ret(tok);
709 27 : if (tok->enc == NULL && !tok->read_coding_spec && newl[1]) {
710 0 : if (!check_coding_spec(newl[0]+1, newl[1] - newl[0],
711 : tok, buf_setreadl))
712 0 : return error_ret(tok);
713 : }
714 : }
715 : #ifdef Py_USING_UNICODE
716 27 : if (tok->enc != NULL) {
717 : assert(utf8 == NULL);
718 0 : utf8 = translate_into_utf8(str, tok->enc);
719 0 : if (utf8 == NULL)
720 0 : return error_ret(tok);
721 0 : str = PyString_AsString(utf8);
722 : }
723 : #endif
724 : assert(tok->decoding_buffer == NULL);
725 27 : tok->decoding_buffer = utf8; /* CAUTION */
726 27 : return str;
727 : }
728 :
729 : #endif /* PGEN */
730 :
731 : /* Set up tokenizer for string */
732 :
733 : struct tok_state *
734 27 : PyTokenizer_FromString(const char *str, int exec_input)
735 : {
736 27 : struct tok_state *tok = tok_new();
737 27 : if (tok == NULL)
738 0 : return NULL;
739 27 : str = (char *)decode_str(str, exec_input, tok);
740 27 : if (str == NULL) {
741 0 : PyTokenizer_Free(tok);
742 0 : return NULL;
743 : }
744 :
745 : /* XXX: constify members. */
746 27 : tok->buf = tok->cur = tok->end = tok->inp = (char*)str;
747 27 : return tok;
748 : }
749 :
750 :
751 : /* Set up tokenizer for file */
752 :
753 : struct tok_state *
754 36 : PyTokenizer_FromFile(FILE *fp, char *ps1, char *ps2)
755 : {
756 36 : struct tok_state *tok = tok_new();
757 36 : if (tok == NULL)
758 0 : return NULL;
759 36 : if ((tok->buf = (char *)PyMem_MALLOC(BUFSIZ)) == NULL) {
760 0 : PyTokenizer_Free(tok);
761 0 : return NULL;
762 : }
763 36 : tok->cur = tok->inp = tok->buf;
764 36 : tok->end = tok->buf + BUFSIZ;
765 36 : tok->fp = fp;
766 36 : tok->prompt = ps1;
767 36 : tok->nextprompt = ps2;
768 36 : return tok;
769 : }
770 :
771 :
772 : /* Free a tok_state structure */
773 :
774 : void
775 63 : PyTokenizer_Free(struct tok_state *tok)
776 : {
777 63 : if (tok->encoding != NULL)
778 0 : PyMem_FREE(tok->encoding);
779 : #ifndef PGEN
780 63 : Py_XDECREF(tok->decoding_readline);
781 63 : Py_XDECREF(tok->decoding_buffer);
782 : #endif
783 63 : if (tok->fp != NULL && tok->buf != NULL)
784 36 : PyMem_FREE(tok->buf);
785 63 : if (tok->input)
786 27 : PyMem_FREE((char *)tok->input);
787 63 : PyMem_FREE(tok);
788 63 : }
789 :
790 : #if !defined(PGEN) && defined(Py_USING_UNICODE)
791 : static int
792 0 : tok_stdin_decode(struct tok_state *tok, char **inp)
793 : {
794 : PyObject *enc, *sysstdin, *decoded, *utf8;
795 : const char *encoding;
796 : char *converted;
797 :
798 0 : if (PySys_GetFile((char *)"stdin", NULL) != stdin)
799 0 : return 0;
800 0 : sysstdin = PySys_GetObject("stdin");
801 0 : if (sysstdin == NULL || !PyFile_Check(sysstdin))
802 0 : return 0;
803 :
804 0 : enc = ((PyFileObject *)sysstdin)->f_encoding;
805 0 : if (enc == NULL || !PyString_Check(enc))
806 0 : return 0;
807 0 : Py_INCREF(enc);
808 :
809 0 : encoding = PyString_AsString(enc);
810 0 : decoded = PyUnicode_Decode(*inp, strlen(*inp), encoding, NULL);
811 0 : if (decoded == NULL)
812 0 : goto error_clear;
813 :
814 0 : utf8 = PyUnicode_AsEncodedString(decoded, "utf-8", NULL);
815 0 : Py_DECREF(decoded);
816 0 : if (utf8 == NULL)
817 0 : goto error_clear;
818 :
819 : assert(PyString_Check(utf8));
820 0 : converted = new_string(PyString_AS_STRING(utf8),
821 : PyString_GET_SIZE(utf8));
822 0 : Py_DECREF(utf8);
823 0 : if (converted == NULL)
824 0 : goto error_nomem;
825 :
826 0 : PyMem_FREE(*inp);
827 0 : *inp = converted;
828 0 : if (tok->encoding != NULL)
829 0 : PyMem_FREE(tok->encoding);
830 0 : tok->encoding = new_string(encoding, strlen(encoding));
831 0 : if (tok->encoding == NULL)
832 0 : goto error_nomem;
833 :
834 0 : Py_DECREF(enc);
835 0 : return 0;
836 :
837 : error_nomem:
838 0 : Py_DECREF(enc);
839 0 : tok->done = E_NOMEM;
840 0 : return -1;
841 :
842 : error_clear:
843 0 : Py_DECREF(enc);
844 0 : if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
845 0 : tok->done = E_ERROR;
846 0 : return -1;
847 : }
848 : /* Fallback to iso-8859-1: for backward compatibility */
849 0 : PyErr_Clear();
850 0 : return 0;
851 : }
852 : #endif
853 :
854 : /* Get next char, updating state; error code goes into tok->done */
855 :
856 : static int
857 563929 : tok_nextc(register struct tok_state *tok)
858 : {
859 : for (;;) {
860 563929 : if (tok->cur != tok->inp) {
861 547677 : return Py_CHARMASK(*tok->cur++); /* Fast path */
862 : }
863 16252 : if (tok->done != E_OK)
864 123 : return EOF;
865 16129 : if (tok->fp == NULL) {
866 1443 : char *end = strchr(tok->inp, '\n');
867 1443 : if (end != NULL)
868 1416 : end++;
869 : else {
870 27 : end = strchr(tok->inp, '\0');
871 27 : if (end == tok->inp) {
872 27 : tok->done = E_EOF;
873 27 : return EOF;
874 : }
875 : }
876 1416 : if (tok->start == NULL)
877 1416 : tok->buf = tok->cur;
878 1416 : tok->line_start = tok->cur;
879 1416 : tok->lineno++;
880 1416 : tok->inp = end;
881 1416 : return Py_CHARMASK(*tok->cur++);
882 : }
883 14686 : if (tok->prompt != NULL) {
884 0 : char *newtok = PyOS_Readline(stdin, stdout, tok->prompt);
885 0 : if (tok->nextprompt != NULL)
886 0 : tok->prompt = tok->nextprompt;
887 0 : if (newtok == NULL)
888 0 : tok->done = E_INTR;
889 0 : else if (*newtok == '\0') {
890 0 : PyMem_FREE(newtok);
891 0 : tok->done = E_EOF;
892 : }
893 : #if !defined(PGEN) && defined(Py_USING_UNICODE)
894 0 : else if (tok_stdin_decode(tok, &newtok) != 0)
895 0 : PyMem_FREE(newtok);
896 : #endif
897 0 : else if (tok->start != NULL) {
898 0 : size_t start = tok->start - tok->buf;
899 0 : size_t oldlen = tok->cur - tok->buf;
900 0 : size_t newlen = oldlen + strlen(newtok);
901 0 : char *buf = tok->buf;
902 0 : buf = (char *)PyMem_REALLOC(buf, newlen+1);
903 0 : tok->lineno++;
904 0 : if (buf == NULL) {
905 0 : PyMem_FREE(tok->buf);
906 0 : tok->buf = NULL;
907 0 : PyMem_FREE(newtok);
908 0 : tok->done = E_NOMEM;
909 0 : return EOF;
910 : }
911 0 : tok->buf = buf;
912 0 : tok->cur = tok->buf + oldlen;
913 0 : tok->line_start = tok->cur;
914 0 : strcpy(tok->buf + oldlen, newtok);
915 0 : PyMem_FREE(newtok);
916 0 : tok->inp = tok->buf + newlen;
917 0 : tok->end = tok->inp + 1;
918 0 : tok->start = tok->buf + start;
919 : }
920 : else {
921 0 : tok->lineno++;
922 0 : if (tok->buf != NULL)
923 0 : PyMem_FREE(tok->buf);
924 0 : tok->buf = newtok;
925 0 : tok->cur = tok->buf;
926 0 : tok->line_start = tok->buf;
927 0 : tok->inp = strchr(tok->buf, '\0');
928 0 : tok->end = tok->inp + 1;
929 : }
930 : }
931 : else {
932 14686 : int done = 0;
933 14686 : Py_ssize_t cur = 0;
934 : char *pt;
935 14686 : if (tok->start == NULL) {
936 12952 : if (tok->buf == NULL) {
937 0 : tok->buf = (char *)
938 0 : PyMem_MALLOC(BUFSIZ);
939 0 : if (tok->buf == NULL) {
940 0 : tok->done = E_NOMEM;
941 0 : return EOF;
942 : }
943 0 : tok->end = tok->buf + BUFSIZ;
944 : }
945 12952 : if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf),
946 : tok) == NULL) {
947 36 : if (!tok->decoding_erred)
948 36 : tok->done = E_EOF;
949 36 : done = 1;
950 : }
951 : else {
952 12916 : tok->done = E_OK;
953 12916 : tok->inp = strchr(tok->buf, '\0');
954 12916 : done = tok->inp == tok->buf || tok->inp[-1] == '\n';
955 : }
956 : }
957 : else {
958 1734 : cur = tok->cur - tok->buf;
959 1734 : if (decoding_feof(tok)) {
960 0 : tok->done = E_EOF;
961 0 : done = 1;
962 : }
963 : else
964 1734 : tok->done = E_OK;
965 : }
966 14686 : tok->lineno++;
967 : /* Read until '\n' or EOF */
968 31106 : while (!done) {
969 3468 : Py_ssize_t curstart = tok->start == NULL ? -1 :
970 1734 : tok->start - tok->buf;
971 1734 : Py_ssize_t curvalid = tok->inp - tok->buf;
972 1734 : Py_ssize_t newsize = curvalid + BUFSIZ;
973 1734 : char *newbuf = tok->buf;
974 1734 : newbuf = (char *)PyMem_REALLOC(newbuf,
975 : newsize);
976 1734 : if (newbuf == NULL) {
977 0 : tok->done = E_NOMEM;
978 0 : tok->cur = tok->inp;
979 0 : return EOF;
980 : }
981 1734 : tok->buf = newbuf;
982 1734 : tok->cur = tok->buf + cur;
983 1734 : tok->line_start = tok->cur;
984 1734 : tok->inp = tok->buf + curvalid;
985 1734 : tok->end = tok->buf + newsize;
986 3468 : tok->start = curstart < 0 ? NULL :
987 1734 : tok->buf + curstart;
988 1734 : if (decoding_fgets(tok->inp,
989 1734 : (int)(tok->end - tok->inp),
990 : tok) == NULL) {
991 : /* Break out early on decoding
992 : errors, as tok->buf will be NULL
993 : */
994 0 : if (tok->decoding_erred)
995 0 : return EOF;
996 : /* Last line does not end in \n,
997 : fake one */
998 0 : strcpy(tok->inp, "\n");
999 : }
1000 1734 : tok->inp = strchr(tok->inp, '\0');
1001 1734 : done = tok->inp[-1] == '\n';
1002 : }
1003 14686 : if (tok->buf != NULL) {
1004 14686 : tok->cur = tok->buf + cur;
1005 14686 : tok->line_start = tok->cur;
1006 : /* replace "\r\n" with "\n" */
1007 : /* For Mac leave the \r, giving a syntax error */
1008 14686 : pt = tok->inp - 2;
1009 14686 : if (pt >= tok->buf && *pt == '\r') {
1010 0 : *pt++ = '\n';
1011 0 : *pt = '\0';
1012 0 : tok->inp = pt;
1013 : }
1014 : }
1015 : }
1016 14686 : if (tok->done != E_OK) {
1017 36 : if (tok->prompt != NULL)
1018 0 : PySys_WriteStderr("\n");
1019 36 : tok->cur = tok->inp;
1020 36 : return EOF;
1021 : }
1022 14650 : }
1023 : /*NOTREACHED*/
1024 : }
1025 :
1026 :
1027 : /* Back-up one character */
1028 :
1029 : static void
1030 72384 : tok_backup(register struct tok_state *tok, register int c)
1031 : {
1032 72384 : if (c != EOF) {
1033 72321 : if (--tok->cur < tok->buf)
1034 0 : Py_FatalError("tok_backup: beginning of buffer");
1035 72321 : if (*tok->cur != c)
1036 0 : *tok->cur = c;
1037 : }
1038 72384 : }
1039 :
1040 :
1041 : /* Return the token corresponding to a single character */
1042 :
1043 : int
1044 20938 : PyToken_OneChar(int c)
1045 : {
1046 20938 : switch (c) {
1047 4974 : case '(': return LPAR;
1048 4974 : case ')': return RPAR;
1049 516 : case '[': return LSQB;
1050 516 : case ']': return RSQB;
1051 2973 : case ':': return COLON;
1052 3685 : case ',': return COMMA;
1053 0 : case ';': return SEMI;
1054 131 : case '+': return PLUS;
1055 114 : case '-': return MINUS;
1056 36 : case '*': return STAR;
1057 1 : case '/': return SLASH;
1058 4 : case '|': return VBAR;
1059 3 : case '&': return AMPER;
1060 5 : case '<': return LESS;
1061 6 : case '>': return GREATER;
1062 2686 : case '=': return EQUAL;
1063 0 : case '.': return DOT;
1064 193 : case '%': return PERCENT;
1065 0 : case '`': return BACKQUOTE;
1066 47 : case '{': return LBRACE;
1067 47 : case '}': return RBRACE;
1068 0 : case '^': return CIRCUMFLEX;
1069 0 : case '~': return TILDE;
1070 27 : case '@': return AT;
1071 0 : default: return OP;
1072 : }
1073 : }
1074 :
1075 :
1076 : int
1077 21762 : PyToken_TwoChars(int c1, int c2)
1078 : {
1079 21762 : switch (c1) {
1080 : case '=':
1081 3301 : switch (c2) {
1082 615 : case '=': return EQEQUAL;
1083 : }
1084 2686 : break;
1085 : case '!':
1086 103 : switch (c2) {
1087 103 : case '=': return NOTEQUAL;
1088 : }
1089 0 : break;
1090 : case '<':
1091 12 : switch (c2) {
1092 0 : case '>': return NOTEQUAL;
1093 4 : case '=': return LESSEQUAL;
1094 3 : case '<': return LEFTSHIFT;
1095 : }
1096 5 : break;
1097 : case '>':
1098 18 : switch (c2) {
1099 10 : case '=': return GREATEREQUAL;
1100 2 : case '>': return RIGHTSHIFT;
1101 : }
1102 6 : break;
1103 : case '+':
1104 174 : switch (c2) {
1105 43 : case '=': return PLUSEQUAL;
1106 : }
1107 131 : break;
1108 : case '-':
1109 116 : switch (c2) {
1110 2 : case '=': return MINEQUAL;
1111 : }
1112 114 : break;
1113 : case '*':
1114 77 : switch (c2) {
1115 40 : case '*': return DOUBLESTAR;
1116 1 : case '=': return STAREQUAL;
1117 : }
1118 36 : break;
1119 : case '/':
1120 2 : switch (c2) {
1121 1 : case '/': return DOUBLESLASH;
1122 0 : case '=': return SLASHEQUAL;
1123 : }
1124 1 : break;
1125 : case '|':
1126 4 : switch (c2) {
1127 0 : case '=': return VBAREQUAL;
1128 : }
1129 4 : break;
1130 : case '%':
1131 193 : switch (c2) {
1132 0 : case '=': return PERCENTEQUAL;
1133 : }
1134 193 : break;
1135 : case '&':
1136 3 : switch (c2) {
1137 0 : case '=': return AMPEREQUAL;
1138 : }
1139 3 : break;
1140 : case '^':
1141 0 : switch (c2) {
1142 0 : case '=': return CIRCUMFLEXEQUAL;
1143 : }
1144 0 : break;
1145 : }
1146 20938 : return OP;
1147 : }
1148 :
1149 : int
1150 824 : PyToken_ThreeChars(int c1, int c2, int c3)
1151 : {
1152 824 : switch (c1) {
1153 : case '<':
1154 7 : switch (c2) {
1155 : case '<':
1156 3 : switch (c3) {
1157 : case '=':
1158 0 : return LEFTSHIFTEQUAL;
1159 : }
1160 3 : break;
1161 : }
1162 7 : break;
1163 : case '>':
1164 12 : switch (c2) {
1165 : case '>':
1166 2 : switch (c3) {
1167 : case '=':
1168 2 : return RIGHTSHIFTEQUAL;
1169 : }
1170 0 : break;
1171 : }
1172 10 : break;
1173 : case '*':
1174 41 : switch (c2) {
1175 : case '*':
1176 40 : switch (c3) {
1177 : case '=':
1178 0 : return DOUBLESTAREQUAL;
1179 : }
1180 40 : break;
1181 : }
1182 41 : break;
1183 : case '/':
1184 1 : switch (c2) {
1185 : case '/':
1186 1 : switch (c3) {
1187 : case '=':
1188 0 : return DOUBLESLASHEQUAL;
1189 : }
1190 1 : break;
1191 : }
1192 1 : break;
1193 : }
1194 822 : return OP;
1195 : }
1196 :
1197 : static int
1198 0 : indenterror(struct tok_state *tok)
1199 : {
1200 0 : if (tok->alterror) {
1201 0 : tok->done = E_TABSPACE;
1202 0 : tok->cur = tok->inp;
1203 0 : return 1;
1204 : }
1205 0 : if (tok->altwarning) {
1206 0 : PySys_WriteStderr("%s: inconsistent use of tabs and spaces "
1207 : "in indentation\n", tok->filename);
1208 0 : tok->altwarning = 0;
1209 : }
1210 0 : return 0;
1211 : }
1212 :
1213 : /* Get next token, after space stripping etc. */
1214 :
1215 : static int
1216 74459 : tok_get(register struct tok_state *tok, char **p_start, char **p_end)
1217 : {
1218 : register int c;
1219 : int blankline;
1220 :
1221 74459 : *p_start = *p_end = NULL;
1222 : nextline:
1223 80282 : tok->start = NULL;
1224 80282 : blankline = 0;
1225 :
1226 : /* Get indentation level */
1227 80282 : if (tok->atbol) {
1228 14384 : register int col = 0;
1229 14384 : register int altcol = 0;
1230 14384 : tok->atbol = 0;
1231 : for (;;) {
1232 67661 : c = tok_nextc(tok);
1233 67661 : if (c == ' ')
1234 53277 : col++, altcol++;
1235 14384 : else if (c == '\t') {
1236 0 : col = (col/tok->tabsize + 1) * tok->tabsize;
1237 0 : altcol = (altcol/tok->alttabsize + 1)
1238 0 : * tok->alttabsize;
1239 : }
1240 14384 : else if (c == '\014') /* Control-L (formfeed) */
1241 0 : col = altcol = 0; /* For Emacs users */
1242 : else
1243 14384 : break;
1244 53277 : }
1245 14384 : tok_backup(tok, c);
1246 14384 : if (c == '#' || c == '\n') {
1247 : /* Lines with only whitespace and/or comments
1248 : shouldn't affect the indentation and are
1249 : not passed to the parser as NEWLINE tokens,
1250 : except *totally* empty lines in interactive
1251 : mode, which signal the end of a command group. */
1252 5243 : if (col == 0 && c == '\n' && tok->prompt != NULL)
1253 0 : blankline = 0; /* Let it through */
1254 : else
1255 5243 : blankline = 1; /* Ignore completely */
1256 : /* We can't jump back right here since we still
1257 : may need to skip to the end of a comment */
1258 : }
1259 14384 : if (!blankline && tok->level == 0) {
1260 8561 : if (col == tok->indstack[tok->indent]) {
1261 : /* No change */
1262 3508 : if (altcol != tok->altindstack[tok->indent]) {
1263 0 : if (indenterror(tok))
1264 0 : return ERRORTOKEN;
1265 : }
1266 : }
1267 5053 : else if (col > tok->indstack[tok->indent]) {
1268 : /* Indent -- always one */
1269 2769 : if (tok->indent+1 >= MAXINDENT) {
1270 0 : tok->done = E_TOODEEP;
1271 0 : tok->cur = tok->inp;
1272 0 : return ERRORTOKEN;
1273 : }
1274 2769 : if (altcol <= tok->altindstack[tok->indent]) {
1275 0 : if (indenterror(tok))
1276 0 : return ERRORTOKEN;
1277 : }
1278 2769 : tok->pendin++;
1279 2769 : tok->indstack[++tok->indent] = col;
1280 2769 : tok->altindstack[tok->indent] = altcol;
1281 : }
1282 : else /* col < tok->indstack[tok->indent] */ {
1283 : /* Dedent -- any number, must be consistent */
1284 12093 : while (tok->indent > 0 &&
1285 4756 : col < tok->indstack[tok->indent]) {
1286 2769 : tok->pendin--;
1287 2769 : tok->indent--;
1288 : }
1289 2284 : if (col != tok->indstack[tok->indent]) {
1290 0 : tok->done = E_DEDENT;
1291 0 : tok->cur = tok->inp;
1292 0 : return ERRORTOKEN;
1293 : }
1294 2284 : if (altcol != tok->altindstack[tok->indent]) {
1295 0 : if (indenterror(tok))
1296 0 : return ERRORTOKEN;
1297 : }
1298 : }
1299 : }
1300 : }
1301 :
1302 80282 : tok->start = tok->cur;
1303 :
1304 : /* Return pending indents/dedents */
1305 80282 : if (tok->pendin != 0) {
1306 5538 : if (tok->pendin < 0) {
1307 2769 : tok->pendin++;
1308 2769 : return DEDENT;
1309 : }
1310 : else {
1311 2769 : tok->pendin--;
1312 2769 : return INDENT;
1313 : }
1314 : }
1315 :
1316 : again:
1317 74755 : tok->start = NULL;
1318 : /* Skip spaces */
1319 : do {
1320 92272 : c = tok_nextc(tok);
1321 92272 : } while (c == ' ' || c == '\t' || c == '\014');
1322 :
1323 : /* Set start of current token */
1324 74755 : tok->start = tok->cur - 1;
1325 :
1326 : /* Skip comment, while looking for tab-setting magic */
1327 74755 : if (c == '#') {
1328 : static char *tabforms[] = {
1329 : "tab-width:", /* Emacs */
1330 : ":tabstop=", /* vim, full form */
1331 : ":ts=", /* vim, abbreviated form */
1332 : "set tabsize=", /* will vi never die? */
1333 : /* more templates can be added here to support other editors */
1334 : };
1335 : char cbuf[80];
1336 : char *tp, **cp;
1337 2786 : tp = cbuf;
1338 : do {
1339 100161 : *tp++ = c = tok_nextc(tok);
1340 197549 : } while (c != EOF && c != '\n' &&
1341 197549 : (size_t)(tp - cbuf + 1) < sizeof(cbuf));
1342 2786 : *tp = '\0';
1343 16716 : for (cp = tabforms;
1344 : cp < tabforms + sizeof(tabforms)/sizeof(tabforms[0]);
1345 11144 : cp++) {
1346 11144 : if ((tp = strstr(cbuf, *cp))) {
1347 0 : int newsize = atoi(tp + strlen(*cp));
1348 :
1349 0 : if (newsize >= 1 && newsize <= 40) {
1350 0 : tok->tabsize = newsize;
1351 0 : if (Py_VerboseFlag)
1352 0 : PySys_WriteStderr(
1353 : "Tab size set to %d\n",
1354 : newsize);
1355 : }
1356 : }
1357 : }
1358 5660 : while (c != EOF && c != '\n')
1359 88 : c = tok_nextc(tok);
1360 : }
1361 :
1362 : /* Check for EOF and errors now */
1363 74755 : if (c == EOF) {
1364 123 : return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN;
1365 : }
1366 :
1367 : /* Identifier (most frequent token!) */
1368 74632 : if (Py_ISALPHA(c) || c == '_') {
1369 : /* Process r"", u"" and ur"" */
1370 29247 : switch (c) {
1371 : case 'b':
1372 : case 'B':
1373 454 : c = tok_nextc(tok);
1374 454 : if (c == 'r' || c == 'R')
1375 93 : c = tok_nextc(tok);
1376 454 : if (c == '"' || c == '\'')
1377 : goto letter_quote;
1378 451 : break;
1379 : case 'r':
1380 : case 'R':
1381 2250 : c = tok_nextc(tok);
1382 2250 : if (c == '"' || c == '\'')
1383 : goto letter_quote;
1384 2206 : break;
1385 : case 'u':
1386 : case 'U':
1387 194 : c = tok_nextc(tok);
1388 194 : if (c == 'r' || c == 'R')
1389 0 : c = tok_nextc(tok);
1390 194 : if (c == '"' || c == '\'')
1391 : goto letter_quote;
1392 194 : break;
1393 : }
1394 220786 : while (c != EOF && (Py_ISALNUM(c) || c == '_')) {
1395 162386 : c = tok_nextc(tok);
1396 : }
1397 29200 : tok_backup(tok, c);
1398 29200 : *p_start = tok->start;
1399 29200 : *p_end = tok->cur;
1400 29200 : return NAME;
1401 : }
1402 :
1403 : /* Newline */
1404 45385 : if (c == '\n') {
1405 14321 : tok->atbol = 1;
1406 14321 : if (blankline || tok->level > 0)
1407 : goto nextline;
1408 8498 : *p_start = tok->start;
1409 8498 : *p_end = tok->cur - 1; /* Leave '\n' out of the string */
1410 8498 : tok->cont_line = 0;
1411 8498 : return NEWLINE;
1412 : }
1413 :
1414 : /* Period or number starting with period? */
1415 31064 : if (c == '.') {
1416 6220 : c = tok_nextc(tok);
1417 6220 : if (isdigit(c)) {
1418 0 : goto fraction;
1419 : }
1420 : else {
1421 6220 : tok_backup(tok, c);
1422 6220 : *p_start = tok->start;
1423 6220 : *p_end = tok->cur;
1424 6220 : return DOT;
1425 : }
1426 : }
1427 :
1428 : /* Number */
1429 24844 : if (isdigit(c)) {
1430 759 : if (c == '0') {
1431 : /* Hex, octal or binary -- maybe. */
1432 268 : c = tok_nextc(tok);
1433 268 : if (c == '.')
1434 1 : goto fraction;
1435 : #ifndef WITHOUT_COMPLEX
1436 267 : if (c == 'j' || c == 'J')
1437 : goto imaginary;
1438 : #endif
1439 270 : if (c == 'x' || c == 'X') {
1440 :
1441 : /* Hex */
1442 3 : c = tok_nextc(tok);
1443 3 : if (!isxdigit(c)) {
1444 0 : tok->done = E_TOKEN;
1445 0 : tok_backup(tok, c);
1446 0 : return ERRORTOKEN;
1447 : }
1448 : do {
1449 6 : c = tok_nextc(tok);
1450 6 : } while (isxdigit(c));
1451 : }
1452 264 : else if (c == 'o' || c == 'O') {
1453 : /* Octal */
1454 0 : c = tok_nextc(tok);
1455 0 : if (c < '0' || c >= '8') {
1456 0 : tok->done = E_TOKEN;
1457 0 : tok_backup(tok, c);
1458 0 : return ERRORTOKEN;
1459 : }
1460 : do {
1461 0 : c = tok_nextc(tok);
1462 0 : } while ('0' <= c && c < '8');
1463 : }
1464 264 : else if (c == 'b' || c == 'B') {
1465 : /* Binary */
1466 0 : c = tok_nextc(tok);
1467 0 : if (c != '0' && c != '1') {
1468 0 : tok->done = E_TOKEN;
1469 0 : tok_backup(tok, c);
1470 0 : return ERRORTOKEN;
1471 : }
1472 : do {
1473 0 : c = tok_nextc(tok);
1474 0 : } while (c == '0' || c == '1');
1475 : }
1476 : else {
1477 264 : int found_decimal = 0;
1478 : /* Octal; c is first char of it */
1479 : /* There's no 'isoctdigit' macro, sigh */
1480 528 : while ('0' <= c && c < '8') {
1481 0 : c = tok_nextc(tok);
1482 : }
1483 264 : if (isdigit(c)) {
1484 0 : found_decimal = 1;
1485 : do {
1486 0 : c = tok_nextc(tok);
1487 0 : } while (isdigit(c));
1488 : }
1489 264 : if (c == '.')
1490 0 : goto fraction;
1491 264 : else if (c == 'e' || c == 'E')
1492 : goto exponent;
1493 : #ifndef WITHOUT_COMPLEX
1494 264 : else if (c == 'j' || c == 'J')
1495 : goto imaginary;
1496 : #endif
1497 264 : else if (found_decimal) {
1498 0 : tok->done = E_TOKEN;
1499 0 : tok_backup(tok, c);
1500 0 : return ERRORTOKEN;
1501 : }
1502 : }
1503 267 : if (c == 'l' || c == 'L')
1504 0 : c = tok_nextc(tok);
1505 : }
1506 : else {
1507 : /* Decimal */
1508 : do {
1509 526 : c = tok_nextc(tok);
1510 526 : } while (isdigit(c));
1511 491 : if (c == 'l' || c == 'L')
1512 0 : c = tok_nextc(tok);
1513 : else {
1514 : /* Accept floating point numbers. */
1515 491 : if (c == '.') {
1516 : fraction:
1517 : /* Fraction */
1518 : do {
1519 2 : c = tok_nextc(tok);
1520 2 : } while (isdigit(c));
1521 : }
1522 492 : if (c == 'e' || c == 'E') {
1523 : int e;
1524 : exponent:
1525 0 : e = c;
1526 : /* Exponent part */
1527 0 : c = tok_nextc(tok);
1528 0 : if (c == '+' || c == '-') {
1529 0 : c = tok_nextc(tok);
1530 0 : if (!isdigit(c)) {
1531 0 : tok->done = E_TOKEN;
1532 0 : tok_backup(tok, c);
1533 0 : return ERRORTOKEN;
1534 : }
1535 0 : } else if (!isdigit(c)) {
1536 0 : tok_backup(tok, c);
1537 0 : tok_backup(tok, e);
1538 0 : *p_start = tok->start;
1539 0 : *p_end = tok->cur;
1540 0 : return NUMBER;
1541 : }
1542 : do {
1543 0 : c = tok_nextc(tok);
1544 0 : } while (isdigit(c));
1545 : }
1546 : #ifndef WITHOUT_COMPLEX
1547 492 : if (c == 'j' || c == 'J')
1548 : /* Imaginary part */
1549 : imaginary:
1550 0 : c = tok_nextc(tok);
1551 : #endif
1552 : }
1553 : }
1554 759 : tok_backup(tok, c);
1555 759 : *p_start = tok->start;
1556 759 : *p_end = tok->cur;
1557 759 : return NUMBER;
1558 : }
1559 :
1560 : letter_quote:
1561 : /* String */
1562 24132 : if (c == '\'' || c == '"') {
1563 2359 : Py_ssize_t quote2 = tok->cur - tok->start + 1;
1564 2359 : int quote = c;
1565 2359 : int triple = 0;
1566 2359 : int tripcount = 0;
1567 : for (;;) {
1568 93572 : c = tok_nextc(tok);
1569 93572 : if (c == '\n') {
1570 1733 : if (!triple) {
1571 0 : tok->done = E_EOLS;
1572 0 : tok_backup(tok, c);
1573 0 : return ERRORTOKEN;
1574 : }
1575 1733 : tripcount = 0;
1576 1733 : tok->cont_line = 1; /* multiline string. */
1577 : }
1578 91839 : else if (c == EOF) {
1579 0 : if (triple)
1580 0 : tok->done = E_EOFS;
1581 : else
1582 0 : tok->done = E_EOLS;
1583 0 : tok->cur = tok->inp;
1584 0 : return ERRORTOKEN;
1585 : }
1586 91839 : else if (c == quote) {
1587 3507 : tripcount++;
1588 3507 : if (tok->cur - tok->start == quote2) {
1589 418 : c = tok_nextc(tok);
1590 418 : if (c == quote) {
1591 357 : triple = 1;
1592 357 : tripcount = 0;
1593 357 : continue;
1594 : }
1595 61 : tok_backup(tok, c);
1596 : }
1597 3150 : if (!triple || tripcount == 3)
1598 : break;
1599 : }
1600 88332 : else if (c == '\\') {
1601 108 : tripcount = 0;
1602 108 : c = tok_nextc(tok);
1603 108 : if (c == EOF) {
1604 0 : tok->done = E_EOLS;
1605 0 : tok->cur = tok->inp;
1606 0 : return ERRORTOKEN;
1607 : }
1608 : }
1609 : else
1610 88224 : tripcount = 0;
1611 91213 : }
1612 2359 : *p_start = tok->start;
1613 2359 : *p_end = tok->cur;
1614 2359 : return STRING;
1615 : }
1616 :
1617 : /* Line continuation */
1618 21773 : if (c == '\\') {
1619 11 : c = tok_nextc(tok);
1620 11 : if (c != '\n') {
1621 0 : tok->done = E_LINECONT;
1622 0 : tok->cur = tok->inp;
1623 0 : return ERRORTOKEN;
1624 : }
1625 11 : tok->cont_line = 1;
1626 11 : goto again; /* Read next line */
1627 : }
1628 :
1629 : /* Check for two-character token */
1630 : {
1631 21762 : int c2 = tok_nextc(tok);
1632 21762 : int token = PyToken_TwoChars(c, c2);
1633 : #ifndef PGEN
1634 21762 : if (Py_Py3kWarningFlag && token == NOTEQUAL && c == '<') {
1635 0 : if (PyErr_WarnExplicit(PyExc_DeprecationWarning,
1636 : "<> not supported in 3.x; use !=",
1637 : tok->filename, tok->lineno,
1638 : NULL, NULL)) {
1639 0 : return ERRORTOKEN;
1640 : }
1641 : }
1642 : #endif
1643 21762 : if (token != OP) {
1644 824 : int c3 = tok_nextc(tok);
1645 824 : int token3 = PyToken_ThreeChars(c, c2, c3);
1646 824 : if (token3 != OP) {
1647 2 : token = token3;
1648 : } else {
1649 822 : tok_backup(tok, c3);
1650 : }
1651 824 : *p_start = tok->start;
1652 824 : *p_end = tok->cur;
1653 824 : return token;
1654 : }
1655 20938 : tok_backup(tok, c2);
1656 : }
1657 :
1658 : /* Keep track of parentheses nesting level */
1659 20938 : switch (c) {
1660 : case '(':
1661 : case '[':
1662 : case '{':
1663 5537 : tok->level++;
1664 5537 : break;
1665 : case ')':
1666 : case ']':
1667 : case '}':
1668 5537 : tok->level--;
1669 5537 : break;
1670 : }
1671 :
1672 : /* Punctuation character */
1673 20938 : *p_start = tok->start;
1674 20938 : *p_end = tok->cur;
1675 20938 : return PyToken_OneChar(c);
1676 : }
1677 :
1678 : int
1679 74459 : PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end)
1680 : {
1681 74459 : int result = tok_get(tok, p_start, p_end);
1682 74459 : if (tok->decoding_erred) {
1683 0 : result = ERRORTOKEN;
1684 0 : tok->done = E_DECODE;
1685 : }
1686 74459 : return result;
1687 : }
1688 :
1689 : /* This function is only called from parsetok. However, it cannot live
1690 : there, as it must be empty for PGEN, and we can check for PGEN only
1691 : in this file. */
1692 :
1693 : #if defined(PGEN) || !defined(Py_USING_UNICODE)
1694 : char*
1695 : PyTokenizer_RestoreEncoding(struct tok_state* tok, int len, int* offset)
1696 : {
1697 : return NULL;
1698 : }
1699 : #else
1700 : #ifdef Py_USING_UNICODE
1701 : static PyObject *
1702 0 : dec_utf8(const char *enc, const char *text, size_t len) {
1703 0 : PyObject *ret = NULL;
1704 0 : PyObject *unicode_text = PyUnicode_DecodeUTF8(text, len, "replace");
1705 0 : if (unicode_text) {
1706 0 : ret = PyUnicode_AsEncodedString(unicode_text, enc, "replace");
1707 0 : Py_DECREF(unicode_text);
1708 : }
1709 0 : if (!ret) {
1710 0 : PyErr_Clear();
1711 : }
1712 0 : return ret;
1713 : }
1714 : char *
1715 0 : PyTokenizer_RestoreEncoding(struct tok_state* tok, int len, int *offset)
1716 : {
1717 0 : char *text = NULL;
1718 0 : if (tok->encoding) {
1719 : /* convert source to original encondig */
1720 0 : PyObject *lineobj = dec_utf8(tok->encoding, tok->buf, len);
1721 0 : if (lineobj != NULL) {
1722 0 : int linelen = PyString_Size(lineobj);
1723 0 : const char *line = PyString_AsString(lineobj);
1724 0 : text = PyObject_MALLOC(linelen + 1);
1725 0 : if (text != NULL && line != NULL) {
1726 0 : if (linelen)
1727 0 : strncpy(text, line, linelen);
1728 0 : text[linelen] = '\0';
1729 : }
1730 0 : Py_DECREF(lineobj);
1731 :
1732 : /* adjust error offset */
1733 0 : if (*offset > 1) {
1734 0 : PyObject *offsetobj = dec_utf8(tok->encoding,
1735 0 : tok->buf, *offset-1);
1736 0 : if (offsetobj) {
1737 0 : *offset = PyString_Size(offsetobj) + 1;
1738 0 : Py_DECREF(offsetobj);
1739 : }
1740 : }
1741 :
1742 : }
1743 : }
1744 0 : return text;
1745 :
1746 : }
1747 : #endif /* defined(Py_USING_UNICODE) */
1748 : #endif
1749 :
1750 :
1751 : #ifdef Py_DEBUG
1752 :
1753 : void
1754 : tok_dump(int type, char *start, char *end)
1755 : {
1756 : printf("%s", _PyParser_TokenNames[type]);
1757 : if (type == NAME || type == NUMBER || type == STRING || type == OP)
1758 : printf("(%.*s)", (int)(end - start), start);
1759 : }
1760 :
1761 : #endif
|