16 #define BYTES_FACTOR 1 / 8 * 9
17 #define BYTES_CHUNK 32
18 #define BYTES_ALIGN(len) PN_ALIGN(len + sizeof(struct PNBytes), BYTES_CHUNK) - sizeof(struct PNBytes)
28 unsigned k =
kh_get(str, t, str);
36 size_t len = strlen(str);
52 assert(len < 0x10000000);
66 int len = strlen(str);
67 int len2 = strlen(str2);
71 s->chars[len+len2] =
'\0';
86 va_start(args, format);
87 len = (
PN_SIZE)vsnprintf(NULL, 0, format, args);
91 va_start(args, format);
92 vsnprintf(s->chars, len + 1, format, args);
114 int i = 0, dec = 0, sign = 0, len =
PN_STR_LEN(
self);
117 sign = (str[0] ==
'-' ? -1 : 1);
118 if (str[0] ==
'-' || str[0] ==
'+') {
121 for (i = 0; i < len; i++)
122 if (str[i] <
'0' || str[i] >
'9')
124 if (i < 10 && i == len) {
157 for (i = 0; s[i]; i++)
158 if ((s[i] & 0xC0) != 0x80)
167 for (i = offset+1; s[i]; i++)
168 if ((s[i] & 0xC0) != 0x80)
189 070,070,070,070,070,070,070,070,070,070,070,070,070,070,070,070,
190 050,050,050,050,050,050,050,050,050,050,050,050,050,050,050,050,
191 030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,
192 030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,
193 204,204,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
194 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
195 174,158,158,158,158,158,158,158,158,158,158,158,158,142,126,126,
196 111, 95, 95, 95, 79,207,207,207,207,207,207,207,207,207,207,207,
198 0,1,1,1,8,7,6,4,5,4,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
199 1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
200 1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
201 1,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,
202 1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,8,7,6,4,5,4,3,2,1,1,1,1,
207 unsigned char data, byte;
208 unsigned long unic = 0;
209 while ((byte = *s++)) {
211 data =
utf8d[ byte - 0x80 ];
212 byte = (byte ^ (uint8_t)(data << 4));
214 unic = (unic << 6) | byte;
224 corrected = nilvalue;
230 }
else if (i > len) {
266 return potion_str2(P, str + startoffset, endoffset - startoffset);
296 size_t startoffset, endoffset;
307 return potion_str2(P, str + startoffset, endoffset - startoffset);
338 s->chars[
len] =
'\0';
366 va_start(args, format);
367 len = (
PN_SIZE)vsnprintf(NULL, 0, format, args);
370 if (s->len + len + 1 > s->siz) {
376 va_start(args, format);
377 vsnprintf(s->chars + s->len, len + 1, format, args);
397 if (s->len + len + 1 > s->siz) {
405 s->chars[s->len] =
'\0';
465 if (index >=
PN_STR_LEN(
self) || (
signed long)index < 0)
static PN potion_str_ord(Potion *P, PN cl, PN self, PN index)
static size_t potion_utf8char_nextchar(const char *s, size_t offset)
returns byte position of next utf8 char after s[offset]
#define DBG_CHECK_TYPE(obj, type)
byte strings are raw character data, volatile, may be appended/changed.
klib hash table library based on double hashing http://en.wikipedia.org/wiki/Double_hashing ...
PN potion_str_add(Potion *P, PN cl, PN self, PN x)
static PN potion_str_slice(Potion *P, PN cl, PN self, PN start, PN end)
static PN potion_str_at(Potion *P, PN cl, PN self, PN index)
#define PN_ALLOC_N(V, T, C)
#define PN_REALLOC(X, V, T, N)
PN potion_str(Potion *P, const char *str)
static const uint8_t utf8d[]
#define potion_method(RCV, MSG, FN, SIG)
void potion_bytes_obj_string(Potion *P, PN bytes, PN obj)
PN potion_bytes_append(Potion *P, PN cl, PN self, PN str)
PN_SIZE pn_printf(Potion *P, PN bytes, const char *format,...)
PN potion_str2(Potion *P, char *str, size_t len)
void potion_add_str(Potion *P, PN s)
static PN potion_fwd(PN)
the potion type is the 't' in the vtable tuple (m,t)
void potion_type_call_is(PN vt, PN cl)
sets the default call method of the PNVtable
static PN potion_bytes_at(Potion *P, PN cl, PN self, PN index)
static size_t potion_utf8char_offset(const char *s, size_t index)
returns byte position of the index-th utf8 char
#define kh_put(name, h, k, r)
PN potion_byte_str2(Potion *P, const char *str, size_t len)
static PN potion_str_eval(Potion *P, PN cl, PN self)
static PN potion_bytes_print(Potion *P, PN cl, PN self)
PN potion_str_format(Potion *P, const char *format,...)
static PN potion_bytes_length(Potion *P, PN cl, PN self)
static unsigned long potion_utf8char_decode(const char *s)
decode the utf8 codepoint at s, i.e. ord
PN potion_bytes_clone(Potion *P, PN cl, PN self)
static PN potion_str_length(Potion *P, PN cl, PN self)
the table class, based on khash
static PN potion_str_print(Potion *P, PN cl, PN self)
static PN potion_bytes_each(Potion *P, PN cl, PN self, PN block)
PN potion_strcat(Potion *P, char *str, char *str2)
#define PN_MEMCPY_N(X, Y, T, N)
PN potion_eval(Potion *P, PN bytes)
static PN potion_str_clone(Potion *P, PN cl, PN self)
strings are immutable UTF-8, the ID is incremental and they may be garbage collected.
PN potion_bytes_string(Potion *P, PN cl, PN self)
size_t potion_cp_strlen_utf8(const char *_s)
wonderful utf-8 counting trickery by colin percival
#define DBG_CHECK_INT(obj)
PN potion_bytes(Potion *P, size_t len)
static PN potion_str_number(Potion *P, PN cl, PN self)
PN potion_strtod(Potion *P, char *str, int len)
Convert string to double.
static PN potion_str_slice_index(PN index, size_t len, int nilvalue)
helper function for potion_str_slice to fix index.
static PN potion_str_bytes(Potion *P, PN cl, PN self)
void potion_str_hash_init(Potion *P)
the global interpreter state P. currently singleton (not threads yet)
#define kh_key(name, h, x)
PN potion_byte_str(Potion *P, const char *str)
#define PN_QUICK_FWD(t, obj)
PN_QUICK_FWD - doing a single fwd check after a possible realloc.
the central table type, based on core/khash.h
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
void potion_str_init(Potion *P)
void potion_allocation_error(void)
#define PN_CALLOC_N(V, T, C)
struct PNTable * strings
table of all strings
static PN potion_str_string(Potion *P, PN cl, PN self)
static PN potion_str_cmp(Potion *P, PN cl, PN self, PN str)
PN potion_lookup_str(Potion *P, const char *str)
#define kh_get(name, h, k)