blob: 67e129d52441c767a7761f9c7d7036edc026f18b [file] [edit]
#include "Python.h"
#include "errcode.h"
#include "pycore_token.h"
#include "tokenizer.h"
#include "reader.h"
#include "reader_internal.h"
#include "../lexer/state.h"
_PyTokenizer_Info
_PyTokenizer_GetInfo(const struct tok_state *tok)
{
_PyTokenizer_Info info = {
.status = tok->done,
.location = {tok->lineno, tok->line_start < 0
? -1 : (int)(tok->cur - tok->line_start)},
.cursor = tok->cur,
.input_span = {tok->buf_offset, tok->inp},
.line_span = {tok->line_start, tok->inp},
.level = tok->level,
.delimiter_loc = {-1, -1},
.in_formatted_string = tok->ftstring_depth != 0,
.is_interactive = tok->reader->kind == _PYTOK_READER_INTERACTIVE,
.is_file = tok->fp != NULL && tok->fp != stdin,
.filename = tok->filename,
.module = tok->module,
.encoding = tok->encoding,
};
if (tok->level > 0) {
int level = tok->level - 1;
info.delimiter = tok->parenstack[level];
info.delimiter_loc = (_PyTok_Loc){
tok->parenlinenostack[level], tok->parencolstack[level]};
}
return info;
}
const char *
_PyToken_TextView(const struct tok_state *tok, const struct token *token,
Py_ssize_t *length)
{
assert(length != NULL);
if (token->span.start < 0) {
assert(token->span.start == -1 && token->span.end == -1);
*length = 0;
return "";
}
return _PyLexer_BufferSpanView(tok, token->span, length);
}
const char *
_PyTokenizer_SpanView(const struct tok_state *tok, _PyTok_Span span,
Py_ssize_t *length)
{
return _PyLexer_BufferSpanView(tok, span, length);
}
void
_PyToken_GetView(const struct tok_state *tok, const struct token *token,
_PyToken_View *view)
{
assert(view != NULL);
assert((token->span.start == -1 && token->span.end == -1) ||
_PyTok_SpanIsValid(token->span));
if (token->span.start >= 0) {
(void)_PyLexer_BufferPointer(tok, token->span.end);
}
view->text = token->span.start < 0
? NULL : _PyLexer_BufferPointer(tok, token->span.start);
view->length = token->span.end - token->span.start;
view->end_line = _PyLexer_BufferPointer(tok, tok->line_start);
view->line = ISSTRINGLIT(token->type)
? view->text - token->start_loc.byte_col : view->end_line;
view->line_length = tok->inp - tok->line_start +
(view->end_line - view->line);
view->implicit_newline = tok->implicit_newline;
view->at_eof = tok->done == E_EOF;
}
const char *
_PyTokenizer_LineView(const struct tok_state *tok, Py_ssize_t lineno,
Py_ssize_t *length)
{
const char *line = _PyTokenizer_RetainedSource(tok);
if (line == NULL) {
line = _PyLexer_BufferPointer(tok, tok->buf_offset);
}
for (Py_ssize_t i = 1; i < lineno; i++) {
const char *next = strchr(line, '\n');
if (next == NULL) {
break;
}
line = next + 1;
}
const char *end = strchr(line, '\n');
*length = end != NULL ? end - line : (Py_ssize_t)strlen(line);
return line;
}
const char *
_PyTokenizer_RetainedSource(const struct tok_state *tok)
{
if (tok->reader->kind == _PYTOK_READER_PREPARED) {
return _PyTok_SourceData(&tok->source);
}
if (tok->reader->kind == _PYTOK_READER_INTERACTIVE) {
return tok->source.bytes;
}
return NULL;
}
void
_PyTokenizer_SetContext(struct tok_state *tok, PyObject *filename,
PyObject *module)
{
Py_XINCREF(filename);
Py_XINCREF(module);
Py_XSETREF(tok->filename, filename);
Py_XSETREF(tok->module, module);
}
void
_PyTokenizer_SetOptions(struct tok_state *tok, int extra_tokens,
int type_comments)
{
tok->tok_extra_tokens = extra_tokens;
tok->type_comments = type_comments;
}
void
_PyTokenizer_ImplyDedents(struct tok_state *tok)
{
if (tok->indent != 0) {
tok->pendin = -tok->indent;
tok->indent = 0;
}
}
int
_PyTokenizer_HasTrailingStatement(const struct tok_state *tok)
{
const char *cur = _PyLexer_BufferPointer(tok, tok->cur);
char c = *cur;
for (;;) {
while (c == ' ' || c == '\t' || c == '\n' || c == '\014') {
c = *++cur;
}
if (!c) {
return 0;
}
if (c != '#') {
return 1;
}
while (c && c != '\n') {
c = *++cur;
}
}
}
int
_PyTokenizer_IsInteractive(const struct tok_state *tok)
{
return tok->prompt != NULL;
}
void
_PyTokenizer_StopInteractive(struct tok_state *tok)
{
tok->interactive_underflow = IUNDERFLOW_STOP;
}