xrope is now the internal representation of pic_str
This commit is contained in:
parent
8e511bc410
commit
8586dc9057
|
@ -36,6 +36,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "xhash/xhash.h"
|
#include "xhash/xhash.h"
|
||||||
#include "xfile/xfile.h"
|
#include "xfile/xfile.h"
|
||||||
|
#include "xrope/xrope.h"
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 201112L
|
#if __STDC_VERSION__ >= 201112L
|
||||||
# define NORETURN _Noreturn
|
# define NORETURN _Noreturn
|
||||||
|
|
|
@ -11,8 +11,7 @@ extern "C" {
|
||||||
|
|
||||||
struct pic_string {
|
struct pic_string {
|
||||||
PIC_OBJECT_HEADER
|
PIC_OBJECT_HEADER
|
||||||
char *str;
|
xrope *rope;
|
||||||
size_t len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define pic_str_p(v) (pic_type(v) == PIC_TT_STRING)
|
#define pic_str_p(v) (pic_type(v) == PIC_TT_STRING)
|
||||||
|
@ -30,6 +29,8 @@ pic_str *pic_strcat(pic_state *, pic_str *, pic_str *);
|
||||||
pic_str *pic_substr(pic_state *, pic_str *, size_t, size_t);
|
pic_str *pic_substr(pic_state *, pic_str *, size_t, size_t);
|
||||||
int pic_strcmp(pic_str *, pic_str *);
|
int pic_strcmp(pic_str *, pic_str *);
|
||||||
|
|
||||||
|
const char *pic_str_cstr(pic_str *);
|
||||||
|
|
||||||
pic_value pic_format(pic_state *, const char *, ...);
|
pic_value pic_format(pic_state *, const char *, ...);
|
||||||
pic_value pic_vformat(pic_state *, const char *, va_list);
|
pic_value pic_vformat(pic_state *, const char *, va_list);
|
||||||
pic_value pic_vfformat(pic_state *, xFILE *, const char *, va_list);
|
pic_value pic_vfformat(pic_state *, xFILE *, const char *, va_list);
|
||||||
|
|
|
@ -16,7 +16,7 @@ pic_errmsg(pic_state *pic)
|
||||||
{
|
{
|
||||||
assert(pic->err != NULL);
|
assert(pic->err != NULL);
|
||||||
|
|
||||||
return pic->err->msg->str;
|
return pic_str_cstr(pic->err->msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN static void
|
NORETURN static void
|
||||||
|
|
2
src/gc.c
2
src/gc.c
|
@ -595,7 +595,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIC_TT_STRING: {
|
case PIC_TT_STRING: {
|
||||||
pic_free(pic, (void*)((struct pic_string *)obj)->str);
|
XROPE_DECREF(((struct pic_string *)obj)->rope);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIC_TT_PORT: {
|
case PIC_TT_PORT: {
|
||||||
|
|
|
@ -619,11 +619,11 @@ pic_macro_include(pic_state *pic)
|
||||||
body = pic_list(pic, 1, pic_symbol_value(pic->sBEGIN));
|
body = pic_list(pic, 1, pic_symbol_value(pic->sBEGIN));
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
char *filename;
|
const char *filename;
|
||||||
if (! pic_str_p(argv[i])) {
|
if (! pic_str_p(argv[i])) {
|
||||||
pic_error(pic, "expected string");
|
pic_error(pic, "expected string");
|
||||||
}
|
}
|
||||||
filename = pic_str_ptr(argv[i])->str;
|
filename = pic_str_cstr(pic_str_ptr(argv[i]));
|
||||||
file = fopen(filename, "r");
|
file = fopen(filename, "r");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
pic_error(pic, "could not open file");
|
pic_error(pic, "could not open file");
|
||||||
|
|
|
@ -94,8 +94,7 @@ yy_str_new_cstr(struct parser_control *p, const char *cstr)
|
||||||
struct pic_string *str;
|
struct pic_string *str;
|
||||||
|
|
||||||
str = (struct pic_string *)yy_obj_alloc(p, sizeof(struct pic_string), PIC_TT_STRING);
|
str = (struct pic_string *)yy_obj_alloc(p, sizeof(struct pic_string), PIC_TT_STRING);
|
||||||
str->len = strlen(cstr);
|
str->rope = xr_new_volatile(cstr, strlen(cstr));
|
||||||
str->str = pic_strdup(p->pic, cstr);
|
|
||||||
|
|
||||||
return pic_obj_value(str);
|
return pic_obj_value(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,7 +414,7 @@ pic_port_read_line(pic_state *pic)
|
||||||
}
|
}
|
||||||
|
|
||||||
str = pic_get_output_string(pic, buf);
|
str = pic_get_output_string(pic, buf);
|
||||||
if (str->len == 0 && c == EOF) {
|
if (pic_strlen(str) == 0 && c == EOF) {
|
||||||
return pic_eof_object();
|
return pic_eof_object();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
110
src/string.c
110
src/string.c
|
@ -9,24 +9,25 @@
|
||||||
#include "picrin/pair.h"
|
#include "picrin/pair.h"
|
||||||
#include "picrin/port.h"
|
#include "picrin/port.h"
|
||||||
|
|
||||||
pic_str *
|
static pic_str *
|
||||||
pic_str_new(pic_state *pic, const char *cstr, size_t len)
|
str_new_rope(pic_state *pic, xrope *rope)
|
||||||
{
|
{
|
||||||
pic_str *str;
|
pic_str *str;
|
||||||
char *copy;
|
|
||||||
|
|
||||||
if (cstr) {
|
|
||||||
copy = pic_strdup(pic, cstr);
|
|
||||||
} else {
|
|
||||||
copy = (char *)pic_alloc(pic, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
str = (pic_str *)pic_obj_alloc(pic, sizeof(pic_str), PIC_TT_STRING);
|
str = (pic_str *)pic_obj_alloc(pic, sizeof(pic_str), PIC_TT_STRING);
|
||||||
str->len = len;
|
str->rope = rope; /* delegate ownership */
|
||||||
str->str = copy;
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pic_str *
|
||||||
|
pic_str_new(pic_state *pic, const char *imbed, size_t len)
|
||||||
|
{
|
||||||
|
if (imbed == NULL && len > 0) {
|
||||||
|
pic_errorf(pic, "zero length specified against NULL ptr");
|
||||||
|
}
|
||||||
|
return str_new_rope(pic, xr_new_volatile(imbed, len));
|
||||||
|
}
|
||||||
|
|
||||||
pic_str *
|
pic_str *
|
||||||
pic_str_new_cstr(pic_state *pic, const char *cstr)
|
pic_str_new_cstr(pic_state *pic, const char *cstr)
|
||||||
{
|
{
|
||||||
|
@ -38,73 +39,100 @@ pic_str_new_fill(pic_state *pic, size_t len, char fill)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
char *cstr;
|
char *cstr;
|
||||||
|
pic_str *str;
|
||||||
|
|
||||||
cstr = (char *)pic_alloc(pic, len + 1);
|
cstr = (char *)pic_alloc(pic, len + 1);
|
||||||
|
cstr[len] = '\0';
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
cstr[i] = fill;
|
cstr[i] = fill;
|
||||||
}
|
}
|
||||||
cstr[len] = '\0';
|
|
||||||
|
|
||||||
return pic_str_new(pic, cstr, len);
|
str = pic_str_new(pic, cstr, len);
|
||||||
|
|
||||||
|
pic_free(pic, cstr);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
pic_strlen(pic_str *str)
|
pic_strlen(pic_str *str)
|
||||||
{
|
{
|
||||||
return str->len;
|
return xr_len(str->rope);
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
pic_str_ref(pic_state *pic, pic_str *str, size_t n)
|
pic_str_ref(pic_state *pic, pic_str *str, size_t i)
|
||||||
{
|
{
|
||||||
UNUSED(pic);
|
char c;
|
||||||
|
|
||||||
return str->str[n];
|
c = xr_at(str->rope, i);
|
||||||
|
if (c == -1) {
|
||||||
|
pic_errorf(pic, "index out of range %d", i);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static xrope *
|
||||||
|
xr_put(xrope *rope, size_t i, char c)
|
||||||
|
{
|
||||||
|
xrope *x, *y;
|
||||||
|
char buf[1];
|
||||||
|
|
||||||
|
if (xr_len(rope) <= i) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = c;
|
||||||
|
|
||||||
|
x = xr_sub(rope, 0, i);
|
||||||
|
y = xr_new_volatile(buf, 1);
|
||||||
|
rope = xr_cat(x, y);
|
||||||
|
XROPE_DECREF(x);
|
||||||
|
XROPE_DECREF(y);
|
||||||
|
|
||||||
|
x = rope;
|
||||||
|
y = xr_sub(rope, i + 1, xr_len(rope));
|
||||||
|
rope = xr_cat(x, y);
|
||||||
|
XROPE_DECREF(x);
|
||||||
|
XROPE_DECREF(y);
|
||||||
|
|
||||||
|
return rope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_str_set(pic_state *pic, pic_str *str, size_t i, char c)
|
pic_str_set(pic_state *pic, pic_str *str, size_t i, char c)
|
||||||
{
|
{
|
||||||
UNUSED(pic);
|
xrope *x;
|
||||||
|
|
||||||
str->str[i] = c;
|
x = xr_put(str->rope, i, c);
|
||||||
|
if (x == NULL) {
|
||||||
|
pic_errorf(pic, "index out of range %d", i);
|
||||||
|
}
|
||||||
|
XROPE_DECREF(str->rope);
|
||||||
|
str->rope = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_str *
|
pic_str *
|
||||||
pic_strcat(pic_state *pic, pic_str *a, pic_str *b)
|
pic_strcat(pic_state *pic, pic_str *a, pic_str *b)
|
||||||
{
|
{
|
||||||
size_t len;
|
return str_new_rope(pic, xr_cat(a->rope, b->rope));
|
||||||
char *buf;
|
|
||||||
|
|
||||||
len = a->len + b->len;
|
|
||||||
buf = pic_alloc(pic, len + 1);
|
|
||||||
|
|
||||||
memcpy(buf, a->str, a->len);
|
|
||||||
memcpy(buf + a->len, b->str, b->len);
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
return pic_str_new(pic, buf, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_str *
|
pic_str *
|
||||||
pic_substr(pic_state *pic, pic_str *str, size_t s, size_t e)
|
pic_substr(pic_state *pic, pic_str *str, size_t s, size_t e)
|
||||||
{
|
{
|
||||||
size_t len;
|
return str_new_rope(pic, xr_sub(str->rope, s, e));
|
||||||
char *buf;
|
|
||||||
|
|
||||||
len = e - s;
|
|
||||||
buf = pic_alloc(pic, len + 1);
|
|
||||||
|
|
||||||
memcpy(buf, str->str + s, len);
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
return pic_str_new(pic, buf, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pic_strcmp(pic_str *str1, pic_str *str2)
|
pic_strcmp(pic_str *str1, pic_str *str2)
|
||||||
{
|
{
|
||||||
return strcmp(str1->str, str2->str);
|
return strcmp(xr_cstr(str1->rope), xr_cstr(str2->rope));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
pic_str_cstr(pic_str *str)
|
||||||
|
{
|
||||||
|
return xr_cstr(str->rope);
|
||||||
}
|
}
|
||||||
|
|
||||||
pic_value
|
pic_value
|
||||||
|
|
|
@ -93,7 +93,7 @@ pic_symbol_string_to_symbol(pic_state *pic)
|
||||||
pic_error(pic, "string->symbol: expected string");
|
pic_error(pic, "string->symbol: expected string");
|
||||||
}
|
}
|
||||||
|
|
||||||
return pic_symbol_value(pic_intern_cstr(pic, pic_str_ptr(v)->str));
|
return pic_symbol_value(pic_intern_cstr(pic, pic_str_cstr(pic_str_ptr(v))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
6
src/vm.c
6
src/vm.c
|
@ -188,15 +188,15 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
||||||
}
|
}
|
||||||
case 'z': {
|
case 'z': {
|
||||||
pic_value str;
|
pic_value str;
|
||||||
char **cstr;
|
const char **cstr;
|
||||||
|
|
||||||
cstr = va_arg(ap, char **);
|
cstr = va_arg(ap, const char **);
|
||||||
if (i < argc) {
|
if (i < argc) {
|
||||||
str = GET_OPERAND(pic,i);
|
str = GET_OPERAND(pic,i);
|
||||||
if (! pic_str_p(str)) {
|
if (! pic_str_p(str)) {
|
||||||
pic_error(pic, "pic_get_args: expected string");
|
pic_error(pic, "pic_get_args: expected string");
|
||||||
}
|
}
|
||||||
*cstr = pic_str_ptr(str)->str;
|
*cstr = pic_str_cstr(pic_str_ptr(str));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -155,11 +155,11 @@ static void
|
||||||
write_str(pic_state *pic, struct pic_string *str, xFILE *file)
|
write_str(pic_state *pic, struct pic_string *str, xFILE *file)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
const char *cstr = str->str;
|
const char *cstr = pic_str_cstr(str);
|
||||||
|
|
||||||
UNUSED(pic);
|
UNUSED(pic);
|
||||||
|
|
||||||
for (i = 0; i < str->len; ++i) {
|
for (i = 0; i < pic_strlen(str); ++i) {
|
||||||
if (cstr[i] == '"' || cstr[i] == '\\') {
|
if (cstr[i] == '"' || cstr[i] == '\\') {
|
||||||
xfputc('\\', file);
|
xfputc('\\', file);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue