| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- #include "pocketpy/objects/sourcedata.h"
- #include "pocketpy/common/sstream.h"
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- static void SourceData__ctor(struct SourceData* self,
- const char* source,
- const char* filename,
- enum py_CompileMode mode,
- bool is_dynamic) {
- self->filename = c11_string__new(filename);
- self->mode = mode;
- c11_vector__ctor(&self->line_starts, sizeof(const char*));
- // Skip utf8 BOM if there is any.
- if(strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
- // Drop all '\r'
- c11_sbuf ss;
- c11_sbuf__ctor(&ss);
- while(true) {
- char c = *source;
- if(c == '\0') break;
- if(c != '\r') c11_sbuf__write_char(&ss, c);
- source++;
- }
- self->source = c11_sbuf__submit(&ss);
- self->is_dynamic = is_dynamic;
- c11_vector__push(const char*, &self->line_starts, self->source->data);
- }
- static void SourceData__dtor(struct SourceData* self) {
- c11_string__delete(self->filename);
- c11_string__delete(self->source);
- c11_vector__dtor(&self->line_starts);
- }
- SourceData_ SourceData__rcnew(const char* source,
- const char* filename,
- enum py_CompileMode mode,
- bool is_dynamic) {
- SourceData_ self = malloc(sizeof(struct SourceData));
- SourceData__ctor(self, source, filename, mode, is_dynamic);
- self->rc.count = 1;
- self->rc.dtor = (void (*)(void*))SourceData__dtor;
- return self;
- }
- bool SourceData__get_line(const struct SourceData* self,
- int lineno,
- const char** st,
- const char** ed) {
- if(lineno < 0) return false;
- lineno -= 1;
- if(lineno < 0) lineno = 0;
- const char* _start = c11__getitem(const char*, &self->line_starts, lineno);
- const char* i = _start;
- // max 300 chars
- while(*i != '\n' && *i != '\0' && i - _start < 300)
- i++;
- *st = _start;
- *ed = i;
- return true;
- }
- void SourceData__snapshot(const struct SourceData* self,
- c11_sbuf* ss,
- int lineno,
- const char* cursor,
- const char* name) {
- pk_sprintf(ss, " File \"%s\", line %d", self->filename->data, lineno);
- if(name && *name) {
- c11_sbuf__write_cstr(ss, ", in ");
- c11_sbuf__write_cstr(ss, name);
- }
- c11_sbuf__write_char(ss, '\n');
- const char *st = NULL, *ed;
- if(SourceData__get_line(self, lineno, &st, &ed)) {
- while(st < ed && isblank(*st))
- ++st;
- if(st < ed) {
- c11_sbuf__write_cstr(ss, " ");
- c11_sbuf__write_cstrn(ss, st, ed - st);
- if(cursor && st <= cursor && cursor <= ed) {
- c11_sbuf__write_cstr(ss, "\n ");
- for(int i = 0; i < (cursor - st); ++i)
- c11_sbuf__write_char(ss, ' ');
- c11_sbuf__write_cstr(ss, "^");
- }
- } else {
- st = NULL;
- }
- }
- if(!st) { c11_sbuf__write_cstr(ss, " <?>"); }
- }
|