Coverage Report

Created: 2026-10-17 06:15

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
20.2k
{
12
20.2k
    assert(tok->ftstring_depth >= 0 && tok->ftstring_depth <= tok->ftstring_capacity);
13
20.2k
    int next_depth = tok->ftstring_depth + 1;
14
20.2k
    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
20.2k
    if (tok->ftstring_depth == tok->ftstring_capacity) {
20
1.76k
        int capacity = Py_MIN(Py_MAX(tok->ftstring_capacity * 2, 4),
21
1.76k
                              MAXFTSTRINGLEVEL);
22
1.76k
        size_t size = (size_t)capacity * sizeof(*tok->ftstring_stack);
23
1.76k
        ftstring_state *stack;
24
1.76k
        if (tok->ftstring_stack == tok->ftstring_stack_inline) {
25
847
            stack = PyMem_Malloc(size);
26
847
            if (stack != NULL) {
27
847
                memcpy(stack, tok->ftstring_stack,
28
847
                       (size_t)tok->ftstring_depth * sizeof(*stack));
29
847
            }
30
847
        }
31
913
        else {
32
913
            stack = PyMem_Realloc(tok->ftstring_stack, size);
33
913
        }
34
1.76k
        if (stack == NULL) {
35
0
            PyErr_NoMemory();
36
0
            tok->done = E_NOMEM;
37
0
            return NULL;
38
0
        }
39
1.76k
        tok->ftstring_stack = stack;
40
1.76k
        tok->ftstring_capacity = capacity;
41
1.76k
    }
42
20.2k
    ftstring_state *state = &tok->ftstring_stack[tok->ftstring_depth];
43
20.2k
    tok->ftstring_depth = next_depth;
44
20.2k
    *state = (ftstring_state){0};
45
20.2k
    return state;
46
20.2k
}
47
48
void
49
_PyLexer_PopFTString(struct tok_state *tok)
50
13.5k
{
51
13.5k
    ftstring_state *state = _PyLexer_CurrentFTString(tok);
52
13.5k
    assert(state != NULL);
53
13.5k
    PyMem_Free(state->comments);
54
13.5k
    tok->ftstring_depth--;
55
13.5k
}
56
57
/* Free a tok_state structure */
58
void
59
_PyTokenizer_Free(struct tok_state *tok)
60
65.0k
{
61
65.0k
    Py_XDECREF(tok->filename);
62
65.0k
    Py_XDECREF(tok->module);
63
65.0k
    _PyTok_ReaderFree(tok);
64
65.0k
    _PyTok_SourceClear(&tok->source);
65
71.8k
    for (int i = 0; i < tok->ftstring_depth; i++) {
66
6.77k
        PyMem_Free(tok->ftstring_stack[i].comments);
67
6.77k
    }
68
65.0k
    if (tok->ftstring_stack != tok->ftstring_stack_inline) {
69
847
        PyMem_Free(tok->ftstring_stack);
70
847
    }
71
65.0k
    PyMem_Free(tok);
72
65.0k
}
73
74
void
75
1.69M
_PyToken_Init(struct token *token) {
76
1.69M
    *token = (struct token){
77
1.69M
        .type = -1,
78
1.69M
        .span = {-1, -1},
79
1.69M
        .start_loc = {-1, -1},
80
1.69M
        .end_loc = {-1, -1},
81
1.69M
    };
82
1.69M
}
83
84
int
85
_PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, _PyTok_Off start, _PyTok_Off end)
86
1.86M
{
87
1.86M
    token->level = tok->level;
88
1.86M
    token->is_raw = 0;
89
1.86M
    assert((start == -1 && end == -1) || (start >= 0 && end >= start));
90
1.86M
    token->span = (_PyTok_Span){start, end};
91
1.86M
    if (start >= 0) {
92
1.78M
        token->start_loc = tok->start_loc;
93
1.78M
        token->end_loc = (_PyTok_Loc){tok->lineno, _PyLexer_ByteColumn(tok)};
94
1.78M
    }
95
81.9k
    else {
96
81.9k
        token->start_loc = token->end_loc = (_PyTok_Loc){tok->lineno, -1};
97
81.9k
    }
98
1.86M
    return type;
99
1.86M
}