cell_t *new_string(secd_t *secd, const char *str) { size_t size = strlen(str) + 1; cell_t *cell = new_string_of_size(secd, size); strcpy(strmem(cell), str); return cell; }
inline static token_t lexstring(secd_parser_t *p) { size_t bufsize = 32; /* initial size since string size is not limited */ size_t read_count = 0; /* to be freed after p->strtok is consumed: */ cell_t *strbuf = new_string_of_size(p->secd, bufsize); share_cell(p->secd, strbuf); char *buf = strmem(strbuf); while (1) { nextchar(p); switch (p->lc) { case '\\': nextchar(p); switch (p->lc) { case 'a' : buf[read_count++] = '\x07'; break; case 'b' : buf[read_count++] = '\x08'; break; case 't' : buf[read_count++] = '\x09'; break; case 'n' : buf[read_count++] = '\x0A'; break; case 'x': { char hexbuf[10]; char *hxb = hexbuf; nextchar(p); if (!isxdigit(p->lc)) goto cleanup_and_exit; do { *hxb++ = p->lc; nextchar(p); } while ((hxb - hexbuf < 9) && isxdigit(p->lc)); if (p->lc != ';') goto cleanup_and_exit; *hxb = '\0'; unichar_t charcode = (int)strtol(hexbuf, NULL, 16); char *after = utf8cpy(buf + read_count, charcode); if (!after) goto cleanup_and_exit; read_count = after - buf; } break; default: buf[read_count++] = p->lc; } break; case '"': nextchar(p); buf[read_count] = '\0'; p->strtok = strbuf; /* don't forget to free */ return (p->token = TOK_STR); default: buf[read_count] = p->lc; ++read_count; } if (read_count + 4 >= bufsize) { // +4 because of utf8cpy /* reallocate */ size_t newbufsize = 2 * bufsize; cell_t *newstrbuf = new_string_of_size(p->secd, newbufsize); if (is_error(newstrbuf)) { secd_errorf(p->secd, "lexstring: not enough memory for a string\n"); goto cleanup_and_exit; } //errorf(";# reallocating string to %lu", newbufsize); char *newbuf = strmem(newstrbuf); memcpy(newbuf, buf, bufsize); assign_cell(p->secd, &strbuf, newstrbuf); buf = newbuf; bufsize = newbufsize; } } cleanup_and_exit: drop_cell(p->secd, strbuf); return (p->token = TOK_ERR); }
cell_t *new_bytevector_of_size(secd_t *secd, size_t size) { cell_t *c = new_string_of_size(secd, size); c->type = CELL_BYTES; return c; }