/src/cpython/Parser/lexer/buffer.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "Python.h" |
2 | | #include "errcode.h" |
3 | | |
4 | | #include "state.h" |
5 | | |
6 | | /* Traverse and remember all f-string buffers, in order to be able to restore |
7 | | them after reallocating tok->buf */ |
8 | | void |
9 | | _PyLexer_remember_fstring_buffers(struct tok_state *tok) |
10 | 0 | { |
11 | 0 | int index; |
12 | 0 | tokenizer_mode *mode; |
13 | |
|
14 | 0 | for (index = tok->tok_mode_stack_index; index >= 0; --index) { |
15 | 0 | mode = &(tok->tok_mode_stack[index]); |
16 | 0 | mode->start_offset = mode->start - tok->buf; |
17 | 0 | mode->multi_line_start_offset = mode->multi_line_start - tok->buf; |
18 | 0 | } |
19 | 0 | } |
20 | | |
21 | | /* Traverse and restore all f-string buffers after reallocating tok->buf */ |
22 | | void |
23 | | _PyLexer_restore_fstring_buffers(struct tok_state *tok) |
24 | 0 | { |
25 | 0 | int index; |
26 | 0 | tokenizer_mode *mode; |
27 | |
|
28 | 0 | for (index = tok->tok_mode_stack_index; index >= 0; --index) { |
29 | 0 | mode = &(tok->tok_mode_stack[index]); |
30 | 0 | mode->start = tok->buf + mode->start_offset; |
31 | 0 | mode->multi_line_start = tok->buf + mode->multi_line_start_offset; |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | | /* Read a line of text from TOK into S, using the stream in TOK. |
36 | | Return NULL on failure, else S. |
37 | | |
38 | | On entry, tok->decoding_buffer will be one of: |
39 | | 1) NULL: need to call tok->decoding_readline to get a new line |
40 | | 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and |
41 | | stored the result in tok->decoding_buffer |
42 | | 3) PyByteArrayObject *: previous call to tok_readline_recode did not have enough room |
43 | | (in the s buffer) to copy entire contents of the line read |
44 | | by tok->decoding_readline. tok->decoding_buffer has the overflow. |
45 | | In this case, tok_readline_recode is called in a loop (with an expanded buffer) |
46 | | until the buffer ends with a '\n' (or until the end of the file is |
47 | | reached): see tok_nextc and its calls to tok_reserve_buf. |
48 | | */ |
49 | | int |
50 | | _PyLexer_tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) |
51 | 0 | { |
52 | 0 | Py_ssize_t cur = tok->cur - tok->buf; |
53 | 0 | Py_ssize_t oldsize = tok->inp - tok->buf; |
54 | 0 | Py_ssize_t newsize = oldsize + Py_MAX(size, oldsize >> 1); |
55 | 0 | if (newsize > tok->end - tok->buf) { |
56 | 0 | char *newbuf = tok->buf; |
57 | 0 | Py_ssize_t start = tok->start == NULL ? -1 : tok->start - tok->buf; |
58 | 0 | Py_ssize_t line_start = tok->start == NULL ? -1 : tok->line_start - tok->buf; |
59 | 0 | Py_ssize_t multi_line_start = tok->multi_line_start - tok->buf; |
60 | 0 | _PyLexer_remember_fstring_buffers(tok); |
61 | 0 | newbuf = (char *)PyMem_Realloc(newbuf, newsize); |
62 | 0 | if (newbuf == NULL) { |
63 | 0 | tok->done = E_NOMEM; |
64 | 0 | return 0; |
65 | 0 | } |
66 | 0 | tok->buf = newbuf; |
67 | 0 | tok->cur = tok->buf + cur; |
68 | 0 | tok->inp = tok->buf + oldsize; |
69 | 0 | tok->end = tok->buf + newsize; |
70 | 0 | tok->start = start < 0 ? NULL : tok->buf + start; |
71 | 0 | tok->line_start = line_start < 0 ? NULL : tok->buf + line_start; |
72 | 0 | tok->multi_line_start = multi_line_start < 0 ? NULL : tok->buf + multi_line_start; |
73 | 0 | _PyLexer_restore_fstring_buffers(tok); |
74 | 0 | } |
75 | 0 | return 1; |
76 | 0 | } |