blob: 0fd9fe1877bed2be926d689bc113aa522adba39d [file]
#ifndef Py_TOKENIZER_SOURCE_H
#define Py_TOKENIZER_SOURCE_H
#include "Python.h"
#include "types.h"
typedef struct {
char *bytes;
_PyTok_Off base_offset;
_PyTok_Off len;
_PyTok_Off cap;
int nlines;
} _PyTok_SourceText;
static inline const char *
_PyTok_SourceData(const _PyTok_SourceText *source)
{
return source->bytes != NULL ? source->bytes : "";
}
/* Convert positions within the retained source window. Pointers and views
are borrowed; append, discard, and clear invalidate them. */
static inline const char *
_PyTok_SourcePointer(const _PyTok_SourceText *source, _PyTok_Off offset)
{
assert(offset >= source->base_offset);
assert(offset - source->base_offset <= source->len);
return _PyTok_SourceData(source) + (offset - source->base_offset);
}
static inline unsigned char
_PyTok_SourceByte(const _PyTok_SourceText *source, _PyTok_Off offset)
{
assert(offset >= source->base_offset);
assert(offset - source->base_offset < source->len);
return (unsigned char)source->bytes[offset - source->base_offset];
}
static inline const char *
_PyTok_SourceSpanView(const _PyTok_SourceText *source, _PyTok_Span span,
Py_ssize_t *length)
{
assert(length != NULL);
assert(_PyTok_SpanIsValid(span));
assert(span.end - source->base_offset <= source->len);
*length = span.end - span.start;
return _PyTok_SourcePointer(source, span.start);
}
/* Return the first matching offset within span, or -1 if absent. */
static inline _PyTok_Off
_PyTok_SourceFindByte(const _PyTok_SourceText *source, _PyTok_Span span,
int byte)
{
Py_ssize_t length;
const char *data = _PyTok_SourceSpanView(source, span, &length);
const char *found = memchr(data, byte, length);
return found != NULL ? span.start + (found - data) : -1;
}
PyAPI_FUNC(void) _PyTok_SourceInit(_PyTok_SourceText *);
/* Clear invalidates all spans and views for the source. */
PyAPI_FUNC(void) _PyTok_SourceClear(_PyTok_SourceText *);
/* Discard the retained window and invalidate its spans and views.
Keep its allocation and advance the logical base to the end of the window. */
PyAPI_FUNC(void) _PyTok_SourceDiscard(_PyTok_SourceText *);
/* Append one nonempty logical line and return its start offset. The input may
contain one newline, as its final byte. An unterminated line must be the
final line. The input must not point into source storage. */
PyAPI_FUNC(_PyTok_Off) _PyTok_SourceAppendLine(
_PyTok_SourceText *source, const char *bytes, Py_ssize_t len);
/* Return borrowed bytes excluding '\n', writing the byte length to *len.
Line numbers are 1-based and clamp to the first or final line; a trailing
'\n' adds an empty final line. The view need not be NUL-terminated.
This does not set an exception. Append, discard, and clear invalidate the view. */
PyAPI_FUNC(const char *) _PyTok_SourceLineView(
const _PyTok_SourceText *source, Py_ssize_t lineno, Py_ssize_t *len);
#endif