Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Parser/lexer/state.c
Line
Count
Source
1
#include "Python.h"
2
#include "pycore_token.h"
3
#include "errcode.h"
4
5
#include "state.h"
6
#include "../tokenizer/helpers.h"
7
#include "../tokenizer/reader.h"
8
9
ftstring_state *
10
_PyLexer_PushFTString(struct tok_state *tok)
11
21.7k
{
12
21.7k
    assert(tok->ftstring_depth >= 0 && tok->ftstring_depth <= tok->ftstring_capacity);
13
21.7k
    int next_depth = tok->ftstring_depth + 1;
14
21.7k
    if (next_depth >= MAXFTSTRINGLEVEL) {
15
1
        _PyTokenizer_syntaxerror(
16
1
            tok, "too many nested f-strings or t-strings");
17
1
        return NULL;
18
1
    }
19
21.7k
    if (tok->ftstring_depth == tok->ftstring_capacity) {
20
1.82k
        int capacity = Py_MIN(Py_MAX(tok->ftstring_capacity * 2, 4),
21
1.82k
                              MAXFTSTRINGLEVEL);
22
1.82k
        size_t size = (size_t)capacity * sizeof(*tok->ftstring_stack);
23
1.82k
        ftstring_state *stack;
24
1.82k
        if (tok->ftstring_stack == tok->ftstring_stack_inline) {
25
858
            stack = PyMem_Malloc(size);
26
858
            if (stack != NULL) {
27
858
                memcpy(stack, tok->ftstring_stack,
28
858
                       (size_t)tok->ftstring_depth * sizeof(*stack));
29
858
            }
30
858
        }
31
970
        else {
32
970
            stack = PyMem_Realloc(tok->ftstring_stack, size);
33
970
        }
34
1.82k
        if (stack == NULL) {
35
0
            PyErr_NoMemory();
36
0
            tok->done = E_NOMEM;
37
0
            return NULL;
38
0
        }
39
1.82k
        tok->ftstring_stack = stack;
40
1.82k
        tok->ftstring_capacity = capacity;
41
1.82k
    }
42
21.7k
    ftstring_state *state = &tok->ftstring_stack[tok->ftstring_depth];
43
21.7k
    tok->ftstring_depth = next_depth;
44
21.7k
    *state = (ftstring_state){0};
45
21.7k
    return state;
46
21.7k
}
47
48
void
49
_PyLexer_PopFTString(struct tok_state *tok)
50
14.4k
{
51
14.4k
    ftstring_state *state = _PyLexer_CurrentFTString(tok);
52
14.4k
    assert(state != NULL);
53
14.4k
    PyMem_Free(state->comments);
54
14.4k
    tok->ftstring_depth--;
55
14.4k
}
56
57
/* Free a tok_state structure */
58
void
59
_PyTokenizer_Free(struct tok_state *tok)
60
76.0k
{
61
76.0k
    Py_XDECREF(tok->filename);
62
76.0k
    Py_XDECREF(tok->module);
63
76.0k
    _PyTok_ReaderFree(tok);
64
76.0k
    _PyTok_SourceClear(&tok->source);
65
83.3k
    for (int i = 0; i < tok->ftstring_depth; i++) {
66
7.27k
        PyMem_Free(tok->ftstring_stack[i].comments);
67
7.27k
    }
68
76.0k
    if (tok->ftstring_stack != tok->ftstring_stack_inline) {
69
858
        PyMem_Free(tok->ftstring_stack);
70
858
    }
71
76.0k
    PyMem_Free(tok);
72
76.0k
}
73
74
void
75
1.80M
_PyToken_Init(struct token *token) {
76
1.80M
    *token = (struct token){
77
1.80M
        .type = -1,
78
1.80M
        .span = {-1, -1},
79
1.80M
        .start_loc = {-1, -1},
80
1.80M
        .end_loc = {-1, -1},
81
1.80M
    };
82
1.80M
}
83
84
int
85
_PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, _PyTok_Off start, _PyTok_Off end)
86
2.01M
{
87
2.01M
    token->level = tok->level;
88
2.01M
    token->is_raw = 0;
89
2.01M
    token->is_incomplete = 0;
90
2.01M
    assert((start == -1 && end == -1) || (start >= 0 && end >= start));
91
2.01M
    token->span = (_PyTok_Span){start, end};
92
2.01M
    if (start >= 0) {
93
1.92M
        token->start_loc = tok->start_loc;
94
1.92M
        token->end_loc = (_PyTok_Loc){tok->lineno, _PyLexer_ByteColumn(tok)};
95
1.92M
    }
96
91.9k
    else {
97
91.9k
        token->start_loc = token->end_loc = (_PyTok_Loc){tok->lineno, -1};
98
91.9k
    }
99
2.01M
    return type;
100
2.01M
}