blob: 31be0ebbde2d278af73b9f956a32e8645b6e5584 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Parser-tokenizer link implementation */
3
Pablo Galindof2cf1e32019-04-13 17:05:14 +01004#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include "tokenizer.h"
6#include "node.h"
7#include "grammar.h"
8#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "errcode.h"
Martin v. Löwis00f1e3f2002-08-04 17:29:52 +000011#include "graminit.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012
Guido van Rossum3f5da241990-12-20 15:06:42 +000013
14/* Forward */
Christian Heimes4d6ec852008-03-26 22:34:47 +000015static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
Victor Stinner14e461d2013-08-26 22:28:21 +020016static int initerr(perrdetail *err_ret, PyObject * filename);
Guido van Rossum3f5da241990-12-20 15:06:42 +000017
Guido van Rossumdcfcd142019-01-31 03:40:27 -080018typedef struct {
19 int *items;
20 size_t size;
21 size_t num_items;
22} growable_int_array;
23
24static int
25growable_int_array_init(growable_int_array *arr, size_t initial_size) {
26 assert(initial_size > 0);
27 arr->items = malloc(initial_size * sizeof(*arr->items));
28 arr->size = initial_size;
29 arr->num_items = 0;
30
31 return arr->items != NULL;
32}
33
34static int
35growable_int_array_add(growable_int_array *arr, int item) {
36 if (arr->num_items >= arr->size) {
37 arr->size *= 2;
38 arr->items = realloc(arr->items, arr->size * sizeof(*arr->items));
39 if (!arr->items) {
40 return 0;
41 }
42 }
43
44 arr->items[arr->num_items] = item;
45 arr->num_items++;
46 return 1;
47}
48
49static void
50growable_int_array_deallocate(growable_int_array *arr) {
51 free(arr->items);
52}
53
Guido van Rossum3f5da241990-12-20 15:06:42 +000054/* Parse input coming from a string. Return error code, print some errors. */
Guido van Rossumbd0389d1994-08-29 12:25:45 +000055node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000056PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +000059}
60
61node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000062PyParser_ParseStringFlags(const char *s, grammar *g, int start,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +000064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 return PyParser_ParseStringFlagsFilename(s, NULL,
66 g, start, err_ret, flags);
Thomas Heller6b17abf2002-07-09 09:23:27 +000067}
68
69node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000070PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 grammar *g, int start,
72 perrdetail *err_ret, int flags)
Thomas Heller6b17abf2002-07-09 09:23:27 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 int iflags = flags;
75 return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start,
76 err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +000077}
78
79node *
Victor Stinner14e461d2013-08-26 22:28:21 +020080PyParser_ParseStringObject(const char *s, PyObject *filename,
81 grammar *g, int start,
82 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 struct tok_state *tok;
85 int exec_input = start == file_input;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000086
Victor Stinner7f2fee32011-04-05 00:39:01 +020087 if (initerr(err_ret, filename) < 0)
88 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 if (*flags & PyPARSE_IGNORE_COOKIE)
91 tok = PyTokenizer_FromUTF8(s, exec_input);
92 else
93 tok = PyTokenizer_FromString(s, exec_input);
94 if (tok == NULL) {
95 err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
96 return NULL;
97 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -080098 if (*flags & PyPARSE_TYPE_COMMENTS) {
99 tok->type_comments = 1;
100 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000101
Victor Stinner7f2fee32011-04-05 00:39:01 +0200102 Py_INCREF(err_ret->filename);
103 tok->filename = err_ret->filename;
Guido van Rossum495da292019-03-07 12:38:08 -0800104 if (*flags & PyPARSE_ASYNC_HACKS)
105 tok->async_hacks = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107}
108
Victor Stinner14e461d2013-08-26 22:28:21 +0200109node *
110PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str,
111 grammar *g, int start,
112 perrdetail *err_ret, int *flags)
113{
114 node *n;
115 PyObject *filename = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200116 if (filename_str != NULL) {
117 filename = PyUnicode_DecodeFSDefault(filename_str);
118 if (filename == NULL) {
119 err_ret->error = E_ERROR;
120 return NULL;
121 }
122 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200123 n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200124 Py_XDECREF(filename);
Victor Stinner14e461d2013-08-26 22:28:21 +0200125 return n;
126}
127
Guido van Rossum3f5da241990-12-20 15:06:42 +0000128/* Parse input coming from a file. Return error code, print some errors. */
129
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000130node *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000131PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300132 const char *ps1, const char *ps2,
133 perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 return PyParser_ParseFileFlags(fp, filename, NULL,
136 g, start, ps1, ps2, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +0000137}
138
139node *
Christian Heimes4d6ec852008-03-26 22:34:47 +0000140PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300142 const char *ps1, const char *ps2,
143 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +0000144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 int iflags = flags;
146 return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1,
147 ps2, err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +0000148}
149
150node *
Victor Stinner14e461d2013-08-26 22:28:21 +0200151PyParser_ParseFileObject(FILE *fp, PyObject *filename,
152 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300153 const char *ps1, const char *ps2,
154 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +0000155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 struct tok_state *tok;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000157
Victor Stinner7f2fee32011-04-05 00:39:01 +0200158 if (initerr(err_ret, filename) < 0)
159 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000160
Serhiy Storchakac6792272013-10-19 21:03:34 +0300161 if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 err_ret->error = E_NOMEM;
163 return NULL;
164 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800165 if (*flags & PyPARSE_TYPE_COMMENTS) {
166 tok->type_comments = 1;
167 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200168 Py_INCREF(err_ret->filename);
169 tok->filename = err_ret->filename;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000171}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172
Victor Stinner14e461d2013-08-26 22:28:21 +0200173node *
174PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
175 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300176 const char *ps1, const char *ps2,
177 perrdetail *err_ret, int *flags)
Victor Stinner14e461d2013-08-26 22:28:21 +0200178{
179 node *n;
180 PyObject *fileobj = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200181 if (filename != NULL) {
182 fileobj = PyUnicode_DecodeFSDefault(filename);
183 if (fileobj == NULL) {
184 err_ret->error = E_ERROR;
185 return NULL;
186 }
187 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200188 n = PyParser_ParseFileObject(fp, fileobj, enc, g,
189 start, ps1, ps2, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200190 Py_XDECREF(fileobj);
Victor Stinner14e461d2013-08-26 22:28:21 +0200191 return n;
192}
193
Neal Norwitze4993c72006-03-16 06:01:25 +0000194#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Brett Cannone3944a52009-04-01 05:08:41 +0000195#if 0
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200196static const char with_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000197"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
198
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200199static const char as_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000200"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
201
202static void
203warn(const char *msg, const char *filename, int lineno)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 if (filename == NULL)
206 filename = "<string>";
207 PySys_WriteStderr(msg, filename, lineno);
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000208}
Neal Norwitzfc85c922006-03-17 05:44:46 +0000209#endif
Brett Cannone3944a52009-04-01 05:08:41 +0000210#endif
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000211
Thomas Wouters89f507f2006-12-13 04:49:30 +0000212/* Parse input coming from the given tokenizer structure.
213 Return error code. */
214
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000215static node *
Tim Petersfe2127d2001-07-16 05:37:24 +0000216parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 int *flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 parser_state *ps;
220 node *n;
Brett Cannonb94767f2011-02-22 20:15:44 +0000221 int started = 0;
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000222 int col_offset, end_col_offset;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800223 growable_int_array type_ignores;
224
225 if (!growable_int_array_init(&type_ignores, 10)) {
226 err_ret->error = E_NOMEM;
227 PyTokenizer_Free(tok);
228 return NULL;
229 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 if ((ps = PyParser_New(g, start)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 err_ret->error = E_NOMEM;
233 PyTokenizer_Free(tok);
234 return NULL;
235 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000236#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 if (*flags & PyPARSE_BARRY_AS_BDFL)
238 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800239 if (*flags & PyPARSE_TYPE_COMMENTS)
240 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000241#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 for (;;) {
244 char *a, *b;
245 int type;
246 size_t len;
247 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400248 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800249 int lineno;
250 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 type = PyTokenizer_Get(tok, &a, &b);
253 if (type == ERRORTOKEN) {
254 err_ret->error = tok->done;
255 break;
256 }
257 if (type == ENDMARKER && started) {
258 type = NEWLINE; /* Add an extra newline */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 started = 0;
260 /* Add the right number of dedent tokens,
261 except if a certain flag is given --
262 codeop.py uses this. */
263 if (tok->indent &&
264 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
265 {
266 tok->pendin = -tok->indent;
267 tok->indent = 0;
268 }
269 }
270 else
271 started = 1;
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600272 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 str = (char *) PyObject_MALLOC(len + 1);
274 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 err_ret->error = E_NOMEM;
276 break;
277 }
278 if (len > 0)
279 strncpy(str, a, len);
280 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000281
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000282#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (type == NOTEQUAL) {
284 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
285 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100286 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 err_ret->error = E_SYNTAX;
288 break;
289 }
290 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
291 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100292 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300293 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 err_ret->error = E_SYNTAX;
295 break;
296 }
297 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000298#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800299
300 /* Nodes of type STRING, especially multi line strings
301 must be handled differently in order to get both
302 the starting line number and the column offset right.
303 (cf. issue 16806) */
304 lineno = type == STRING ? tok->first_lineno : tok->lineno;
305 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
306 if (a != NULL && a >= line_start) {
307 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700308 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600309 }
310 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600312 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000313
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000314 if (b != NULL && b >= tok->line_start) {
315 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
316 intptr_t, int);
317 }
318 else {
319 end_col_offset = -1;
320 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800321
322 if (type == TYPE_IGNORE) {
Guido van Rossumd2b4c192019-02-01 15:28:13 -0800323 PyObject_FREE(str);
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800324 if (!growable_int_array_add(&type_ignores, tok->lineno)) {
325 err_ret->error = E_NOMEM;
326 break;
327 }
328 continue;
329 }
330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 if ((err_ret->error =
332 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000333 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 &(err_ret->expected))) != E_OK) {
335 if (err_ret->error != E_DONE) {
336 PyObject_FREE(str);
337 err_ret->token = type;
338 }
339 break;
340 }
341 }
342
343 if (err_ret->error == E_DONE) {
344 n = ps->p_tree;
345 ps->p_tree = NULL;
Meador Ingefa21bf02012-01-19 01:08:41 -0600346
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800347 if (n->n_type == file_input) {
348 /* Put type_ignore nodes in the ENDMARKER of file_input. */
349 int num;
350 node *ch;
351 size_t i;
352
353 num = NCH(n);
354 ch = CHILD(n, num - 1);
355 REQ(ch, ENDMARKER);
356
357 for (i = 0; i < type_ignores.num_items; i++) {
358 PyNode_AddChild(ch, TYPE_IGNORE, NULL,
359 type_ignores.items[i], 0,
360 type_ignores.items[i], 0);
361 }
362 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800363
Meador Ingefa21bf02012-01-19 01:08:41 -0600364 /* Check that the source for a single input statement really
365 is a single statement by looking at what is left in the
366 buffer after parsing. Trailing whitespace and comments
367 are OK. */
368 if (start == single_input) {
369 char *cur = tok->cur;
370 char c = *tok->cur;
371
Benjamin Petersoncff92372012-01-19 17:46:13 -0500372 for (;;) {
373 while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
374 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600375
Benjamin Petersoncff92372012-01-19 17:46:13 -0500376 if (!c)
377 break;
378
379 if (c != '#') {
380 err_ret->error = E_BADSINGLE;
381 PyNode_Free(n);
382 n = NULL;
383 break;
384 }
385
386 /* Suck up comment. */
387 while (c && c != '\n')
388 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600389 }
390 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 }
392 else
393 n = NULL;
Christian Heimesb1b3efc2008-03-26 23:24:27 +0000394
Pablo Galindob9d2e972019-02-13 00:45:53 +0000395 growable_int_array_deallocate(&type_ignores);
396
Christian Heimes4d6ec852008-03-26 22:34:47 +0000397#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 *flags = ps->p_flags;
Christian Heimes4d6ec852008-03-26 22:34:47 +0000399#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (n == NULL) {
Benjamin Peterson758888d2011-05-30 11:12:38 -0500403 if (tok->done == E_EOF)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 err_ret->error = E_EOF;
405 err_ret->lineno = tok->lineno;
406 if (tok->buf != NULL) {
407 size_t len;
408 assert(tok->cur - tok->buf < INT_MAX);
Ammar Askar025eb982018-09-24 17:12:49 -0400409 /* if we've managed to parse a token, point the offset to its start,
410 * else use the current reading position of the tokenizer
411 */
412 err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 len = tok->inp - tok->buf;
414 err_ret->text = (char *) PyObject_MALLOC(len + 1);
415 if (err_ret->text != NULL) {
416 if (len > 0)
417 strncpy(err_ret->text, tok->buf, len);
418 err_ret->text[len] = '\0';
419 }
420 }
421 } else if (tok->encoding != NULL) {
422 /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was
423 * allocated using PyMem_
424 */
425 node* r = PyNode_New(encoding_decl);
426 if (r)
427 r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1);
428 if (!r || !r->n_str) {
429 err_ret->error = E_NOMEM;
430 if (r)
431 PyObject_FREE(r);
432 n = NULL;
433 goto done;
434 }
435 strcpy(r->n_str, tok->encoding);
436 PyMem_FREE(tok->encoding);
437 tok->encoding = NULL;
438 r->n_nchildren = 1;
439 r->n_child = n;
440 n = r;
441 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000442
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000443done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000445
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000446 if (n != NULL) {
447 _PyNode_FinalizeEndPos(n);
448 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450}
Guido van Rossum0c156a52001-10-20 14:27:56 +0000451
Victor Stinner7f2fee32011-04-05 00:39:01 +0200452static int
Victor Stinner14e461d2013-08-26 22:28:21 +0200453initerr(perrdetail *err_ret, PyObject *filename)
Guido van Rossum0c156a52001-10-20 14:27:56 +0000454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 err_ret->error = E_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 err_ret->lineno = 0;
457 err_ret->offset = 0;
458 err_ret->text = NULL;
459 err_ret->token = -1;
460 err_ret->expected = -1;
Victor Stinner14e461d2013-08-26 22:28:21 +0200461 if (filename) {
462 Py_INCREF(filename);
463 err_ret->filename = filename;
464 }
465 else {
Victor Stinner7f2fee32011-04-05 00:39:01 +0200466 err_ret->filename = PyUnicode_FromString("<string>");
Victor Stinner14e461d2013-08-26 22:28:21 +0200467 if (err_ret->filename == NULL) {
468 err_ret->error = E_ERROR;
469 return -1;
470 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200471 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200472 return 0;
Guido van Rossum0c156a52001-10-20 14:27:56 +0000473}