From 9d6f044d33e66714008353955b740ff765258e26 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 13 Jun 2024 10:46:22 +0800 Subject: [PATCH] Squashed commit of the following: commit b584de5c3d4603a476cdd60830289104784a4942 Author: blueloveTH Date: Thu Jun 13 10:46:07 2024 +0800 some fix commit 1fe8a3280949d724ddab9c6b1476e1b55c5beb9d Author: blueloveTH Date: Wed Jun 12 22:08:09 2024 +0800 backup --- compile_flags.txt | 3 +- include/pocketpy/common/sstream.h | 70 ++++++++++++++++++++--- include/pocketpy/common/utils.h | 5 ++ include/pocketpy/common/vector.h | 3 + src/common/sourcedata.c | 39 +++++++------ src/common/sstream.c | 93 +++++++++++++++++++++---------- tests/80_traceback.py | 11 +++- 7 files changed, 166 insertions(+), 58 deletions(-) diff --git a/compile_flags.txt b/compile_flags.txt index 6a6ce7ea..ac20b509 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,9 +1,8 @@ --xc++ - -Wall -W* -std=c++17 +-std=c11 -stdlib=libc++ -Iinclude/ diff --git a/include/pocketpy/common/sstream.h b/include/pocketpy/common/sstream.h index d0b7cfc5..5f66d97d 100644 --- a/include/pocketpy/common/sstream.h +++ b/include/pocketpy/common/sstream.h @@ -6,21 +6,77 @@ extern "C" { #include "pocketpy/common/vector.h" #include "pocketpy/common/str.h" +#include "pocketpy/common/utils.h" + #include typedef struct pkpy_SStream { c11_vector data; } pkpy_SStream; +typedef struct pkpy_AnyStr { + int type; + union { + int _int; + int64_t _int64; + float _float; + double _double; + char _char; + unsigned char _hex; + const pkpy_Str* _str; + c11_string _sv; + const char* _cstr; + void* _ptr; + }; +} pkpy_AnyStr; + +inline pkpy_AnyStr pkpy_AnyStr__int(int x) { return (pkpy_AnyStr){.type = 1, ._int = x}; } +inline pkpy_AnyStr pkpy_AnyStr__int64(int64_t x) { return (pkpy_AnyStr){.type = 2, ._int64 = x}; } +inline pkpy_AnyStr pkpy_AnyStr__float(float x) { return (pkpy_AnyStr){.type = 3, ._float = x}; } +inline pkpy_AnyStr pkpy_AnyStr__double(double x) { return (pkpy_AnyStr){.type = 4, ._double = x}; } +inline pkpy_AnyStr pkpy_AnyStr__char(char x) { return (pkpy_AnyStr){.type = 5, ._char = x}; } +inline pkpy_AnyStr pkpy_AnyStr__hex(unsigned char x) { return (pkpy_AnyStr){.type = 6, ._hex = x}; } +inline pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { return (pkpy_AnyStr){.type = 7, ._str = x}; } +inline pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { return (pkpy_AnyStr){.type = 8, ._sv = x}; } +inline pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { return (pkpy_AnyStr){.type = 9, ._cstr = x}; } +inline pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { return (pkpy_AnyStr){.type = 10, ._ptr = x}; } + void pkpy_SStream__ctor(pkpy_SStream* self); void pkpy_SStream__dtor(pkpy_SStream* self); -void pkpy_SStream__append_cstr(pkpy_SStream* self, const char* str); -void pkpy_SStream__append_cstrn(pkpy_SStream* self, const char* str, int n); -void pkpy_SStream__append_Str(pkpy_SStream* self, const pkpy_Str* str); -void pkpy_SStream__append_char(pkpy_SStream* self, char c); -void pkpy_SStream__append_int(pkpy_SStream* self, int i); -void pkpy_SStream__append_int64(pkpy_SStream* self, int64_t i); -pkpy_Str pkpy_SStream__to_Str(const pkpy_SStream* self); +void pkpy_SStream__write_char(pkpy_SStream* self, char); +void pkpy_SStream__write_int(pkpy_SStream* self, int); +void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t); +void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str*); +void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string); +void pkpy_SStream__write_cstr(pkpy_SStream* self, const char*); +void pkpy_SStream__write_cstrn(pkpy_SStream* self, const char*, int); +void pkpy_SStream__write_any(pkpy_SStream* self, const char* fmt, const pkpy_AnyStr* args, int n); + +// Submit the stream and return the final string. The stream becomes invalid after this call +pkpy_Str pkpy_SStream__submit(pkpy_SStream* self); + +#define pkpy__anystr(x) _Generic((x), \ + int: pkpy_AnyStr__int, \ + int64_t: pkpy_AnyStr__int64, \ + float: pkpy_AnyStr__float, \ + double: pkpy_AnyStr__double, \ + char: pkpy_AnyStr__char, \ + unsigned char: pkpy_AnyStr__hex, \ + const pkpy_Str*: pkpy_AnyStr__str, \ + c11_string: pkpy_AnyStr__sv, \ + const char*: pkpy_AnyStr__cstr, \ + void*: pkpy_AnyStr__ptr \ +)(x) + +#define pkpy__anystr_list_1(a) (pkpy_AnyStr[]){pkpy__anystr(a)}, 1 +#define pkpy__anystr_list_2(a, b) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b)}, 2 +#define pkpy__anystr_list_3(a, b, c) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b), pkpy__anystr(c)}, 3 +#define pkpy__anystr_list_4(a, b, c, d) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b), pkpy__anystr(c), pkpy__anystr(d)}, 4 + +#define pkpy__anystr_list_dispatcher(...) PK_NARGS_SEQ(__VA_ARGS__, pkpy__anystr_list_4, pkpy__anystr_list_3, pkpy__anystr_list_2, pkpy__anystr_list_1, 0) +#define pkpy__anystr_list(...) pkpy__anystr_list_dispatcher(__VA_ARGS__)(__VA_ARGS__) + +#define pkpy_SStream__write(self, fmt, ...) pkpy_SStream__write_any(self, fmt, pkpy__anystr_list(__VA_ARGS__)) #ifdef __cplusplus } diff --git a/include/pocketpy/common/utils.h b/include/pocketpy/common/utils.h index 52d4bfc2..d395c654 100644 --- a/include/pocketpy/common/utils.h +++ b/include/pocketpy/common/utils.h @@ -24,6 +24,11 @@ extern const char* kPlatformStrings[]; #define PK_MIN(a, b) ((a) < (b) ? (a) : (b)) #define PK_MAX(a, b) ((a) > (b) ? (a) : (b)) +// NARGS +#define PK_NARGS_SEQ(_1, _2, _3, _4, N, ...) N +#define PK_NARGS(...) PK_NARGS_SEQ(__VA_ARGS__, 4, 3, 2, 1, 0) +#define PK_NPTRS(...) PK_NARGS_SEQ(__VA_ARGS__, int****, int***, int**, int*, int) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/pocketpy/common/vector.h b/include/pocketpy/common/vector.h index 0c5d0bb7..1620520d 100644 --- a/include/pocketpy/common/vector.h +++ b/include/pocketpy/common/vector.h @@ -4,6 +4,9 @@ extern "C" { #endif +#include +#include + typedef struct c11_array{ void* data; int count; diff --git a/src/common/sourcedata.c b/src/common/sourcedata.c index 40929655..496ea12c 100644 --- a/src/common/sourcedata.c +++ b/src/common/sourcedata.c @@ -22,7 +22,7 @@ void pkpy_SourceData__ctor(struct pkpy_SourceData* self, for(int i = 0; i < source_size; ++i) len -= (source[i] == '\r'); - char *buf = malloc(len + 1), *p = buf; + char *buf = (char*)malloc(len + 1), *p = buf; buf[len] = '\0'; for(; index < source_size; ++index) { if(source[index] != '\r') *(p++) = source[index]; @@ -57,39 +57,44 @@ bool pkpy_SourceData__get_line(const struct pkpy_SourceData* self, int lineno, c pkpy_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData* self, int lineno, const char* cursor, const char* name) { pkpy_SStream ss; pkpy_SStream__ctor(&ss); - pkpy_SStream__append_cstr(&ss, " File \""); - pkpy_SStream__append_Str(&ss, &self->filename); - pkpy_SStream__append_cstr(&ss, "\", line "); - pkpy_SStream__append_int(&ss, lineno); + + // pkpy_SStream__write_cstr(&ss, " File \""); + // pkpy_SStream__write_Str(&ss, &self->filename); + // pkpy_SStream__write_cstr(&ss, "\", line "); + // pkpy_SStream__write_int(&ss, lineno); + + pkpy_SStream__write(&ss, + " File \"{}\", line {}", + &self->filename, + lineno + ); if(name) { - pkpy_SStream__append_cstr(&ss, ", in "); - pkpy_SStream__append_cstr(&ss, name); + pkpy_SStream__write_cstr(&ss, ", in "); + pkpy_SStream__write_cstr(&ss, name); } if(!self->is_precompiled) { - pkpy_SStream__append_char(&ss, '\n'); + pkpy_SStream__write_char(&ss, '\n'); const char *st = NULL, *ed; if(pkpy_SourceData__get_line(self, lineno, &st, &ed)) { while(st < ed && isblank(*st)) ++st; if(st < ed) { - pkpy_SStream__append_cstr(&ss, " "); - pkpy_SStream__append_cstrn(&ss, st, ed - st); + pkpy_SStream__write_cstr(&ss, " "); + pkpy_SStream__write_cstrn(&ss, st, ed - st); if(cursor && st <= cursor && cursor <= ed) { - pkpy_SStream__append_cstr(&ss, "\n "); + pkpy_SStream__write_cstr(&ss, "\n "); for(int i = 0; i < (cursor - st); ++i) - pkpy_SStream__append_char(&ss, ' '); - pkpy_SStream__append_cstr(&ss, "^"); + pkpy_SStream__write_char(&ss, ' '); + pkpy_SStream__write_cstr(&ss, "^"); } } else { st = NULL; } } - if(!st) { pkpy_SStream__append_cstr(&ss, " "); } + if(!st) { pkpy_SStream__write_cstr(&ss, " "); } } - pkpy_Str res = pkpy_SStream__to_Str(&ss); - pkpy_SStream__dtor(&ss); - return res; + return pkpy_SStream__submit(&ss); } diff --git a/src/common/sstream.c b/src/common/sstream.c index 08091c3d..6ba3a7ba 100644 --- a/src/common/sstream.c +++ b/src/common/sstream.c @@ -1,5 +1,8 @@ #include "pocketpy/common/sstream.h" +#include "pocketpy/common/utils.h" + #include +#include void pkpy_SStream__ctor(pkpy_SStream* self) { c11_vector__ctor(&self->data, sizeof(char)); @@ -9,40 +12,72 @@ void pkpy_SStream__dtor(pkpy_SStream* self) { c11_vector__dtor(&self->data); } -void pkpy_SStream__append_cstr(pkpy_SStream* self, const char* str) { - for (int i = 0; str[i] != '\0'; i++) { - c11_vector__push(char, &self->data, str[i]); - } -} - -void pkpy_SStream__append_cstrn(pkpy_SStream* self, const char* str, int n) { - for (int i = 0; i < n; i++) { - c11_vector__push(char, &self->data, str[i]); - } -} - -void pkpy_SStream__append_Str(pkpy_SStream* self, const pkpy_Str* str) { - pkpy_SStream__append_cstr(self, pkpy_Str__data(str)); -} - -void pkpy_SStream__append_char(pkpy_SStream* self, char c) { +void pkpy_SStream__write_char(pkpy_SStream* self, char c) { c11_vector__push(char, &self->data, c); } -void pkpy_SStream__append_int(pkpy_SStream* self, int i) { - char str[12]; // sign + 10 digits + null terminator - sprintf(str, "%d", i); - pkpy_SStream__append_cstr(self, str); +void pkpy_SStream__write_int(pkpy_SStream* self, int i) { + char buf[12]; // sign + 10 digits + null terminator + snprintf(buf, sizeof(buf), "%d", i); + pkpy_SStream__write_cstr(self, buf); } -void pkpy_SStream__append_int64(pkpy_SStream* self, int64_t i) { - char str[23]; // sign + 21 digits + null terminator - sprintf(str, "%lld", i); - pkpy_SStream__append_cstr(self, str); +void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t i) { + char buf[23]; // sign + 21 digits + null terminator + snprintf(buf, sizeof(buf), "%lld", i); + pkpy_SStream__write_cstr(self, buf); } -pkpy_Str pkpy_SStream__to_Str(const pkpy_SStream* self) { - pkpy_Str res; - pkpy_Str__ctor2(&res, self->data.data, self->data.count); - return res; +void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str* str) { + pkpy_SStream__write_cstr(self, pkpy_Str__data(str)); +} + +void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string sv) { + pkpy_SStream__write_cstrn(self, sv.data, sv.size); +} + +void pkpy_SStream__write_cstr(pkpy_SStream* self, const char* str) { + pkpy_SStream__write_cstrn(self, str, strlen(str)); +} + +void pkpy_SStream__write_cstrn(pkpy_SStream* self, const char* str, int n) { + c11_vector__extend(char, &self->data, str, n); +} + +void pkpy_SStream__write_any(pkpy_SStream* self, const char* fmt, const pkpy_AnyStr* args, int n){ + int i = 0; + while(*fmt){ + if(*fmt == '{' && fmt[1] == '}'){ + assert(i < n); + switch(args[i].type){ + case 1: pkpy_SStream__write_int(self, args[i]._int); break; + case 2: pkpy_SStream__write_int64(self, args[i]._int64); break; + case 3: assert(0); break; + case 4: assert(0); break; + case 5: pkpy_SStream__write_char(self, args[i]._char); break; + case 6: assert(0); break; + case 7: pkpy_SStream__write_Str(self, args[i]._str); break; + case 8: pkpy_SStream__write_sv(self, args[i]._sv); break; + case 9: pkpy_SStream__write_cstr(self, args[i]._cstr); break; + case 10: assert(0); break; + default: assert(0); break; + } + fmt += 2; + i++; + }else{ + pkpy_SStream__write_char(self, *fmt); + fmt++; + } + } +} + +pkpy_Str pkpy_SStream__submit(pkpy_SStream* self) { + c11_vector__push(char, &self->data, '\0'); + pkpy_Str retval = { + .size = self->data.count - 1, + .is_ascii = false, // need to check + .is_sso = false, + ._ptr = (char*)self->data.data + }; + return retval; } diff --git a/tests/80_traceback.py b/tests/80_traceback.py index b1df66fd..d44ae1a7 100644 --- a/tests/80_traceback.py +++ b/tests/80_traceback.py @@ -4,11 +4,16 @@ try: a = {'123': 4} b = a[6] except KeyError: - s = traceback.format_exc() + actual = traceback.format_exc() -ok = s == '''Traceback (most recent call last): +expected = '''Traceback (most recent call last): File "80_traceback.py", line 5 b = a[6] KeyError: 6''' -assert ok, s \ No newline at end of file +if actual != expected: + print('--- ACTUAL RESULT -----') + print(actual) + print('--- EXPECTED RESULT ---') + print(expected) + exit(1) \ No newline at end of file