xrope is now the internal representation of pic_str

This commit is contained in:
Yuichi Nishiwaki 2014-02-27 21:54:37 +09:00
parent 8e511bc410
commit 8586dc9057
11 changed files with 85 additions and 56 deletions

View File

@ -36,6 +36,7 @@ extern "C" {
#include "xhash/xhash.h"
#include "xfile/xfile.h"
#include "xrope/xrope.h"
#if __STDC_VERSION__ >= 201112L
# define NORETURN _Noreturn

View File

@ -11,8 +11,7 @@ extern "C" {
struct pic_string {
PIC_OBJECT_HEADER
char *str;
size_t len;
xrope *rope;
};
#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);
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_vformat(pic_state *, const char *, va_list);
pic_value pic_vfformat(pic_state *, xFILE *, const char *, va_list);

View File

@ -16,7 +16,7 @@ pic_errmsg(pic_state *pic)
{
assert(pic->err != NULL);
return pic->err->msg->str;
return pic_str_cstr(pic->err->msg);
}
NORETURN static void

View File

@ -595,7 +595,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
break;
}
case PIC_TT_STRING: {
pic_free(pic, (void*)((struct pic_string *)obj)->str);
XROPE_DECREF(((struct pic_string *)obj)->rope);
break;
}
case PIC_TT_PORT: {

View File

@ -619,11 +619,11 @@ pic_macro_include(pic_state *pic)
body = pic_list(pic, 1, pic_symbol_value(pic->sBEGIN));
for (i = 0; i < argc; ++i) {
char *filename;
const char *filename;
if (! pic_str_p(argv[i])) {
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");
if (file == NULL) {
pic_error(pic, "could not open file");

View File

@ -94,8 +94,7 @@ yy_str_new_cstr(struct parser_control *p, const char *cstr)
struct pic_string *str;
str = (struct pic_string *)yy_obj_alloc(p, sizeof(struct pic_string), PIC_TT_STRING);
str->len = strlen(cstr);
str->str = pic_strdup(p->pic, cstr);
str->rope = xr_new_volatile(cstr, strlen(cstr));
return pic_obj_value(str);
}

View File

@ -414,7 +414,7 @@ pic_port_read_line(pic_state *pic)
}
str = pic_get_output_string(pic, buf);
if (str->len == 0 && c == EOF) {
if (pic_strlen(str) == 0 && c == EOF) {
return pic_eof_object();
}
else {

View File

@ -9,24 +9,25 @@
#include "picrin/pair.h"
#include "picrin/port.h"
pic_str *
pic_str_new(pic_state *pic, const char *cstr, size_t len)
static pic_str *
str_new_rope(pic_state *pic, xrope *rope)
{
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->len = len;
str->str = copy;
str->rope = rope; /* delegate ownership */
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_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;
char *cstr;
pic_str *str;
cstr = (char *)pic_alloc(pic, len + 1);
cstr[len] = '\0';
for (i = 0; i < len; ++i) {
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
pic_strlen(pic_str *str)
{
return str->len;
return xr_len(str->rope);
}
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
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_strcat(pic_state *pic, pic_str *a, pic_str *b)
{
size_t len;
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);
return str_new_rope(pic, xr_cat(a->rope, b->rope));
}
pic_str *
pic_substr(pic_state *pic, pic_str *str, size_t s, size_t e)
{
size_t len;
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);
return str_new_rope(pic, xr_sub(str->rope, s, e));
}
int
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

View File

@ -93,7 +93,7 @@ pic_symbol_string_to_symbol(pic_state *pic)
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

View File

@ -188,15 +188,15 @@ pic_get_args(pic_state *pic, const char *format, ...)
}
case 'z': {
pic_value str;
char **cstr;
const char **cstr;
cstr = va_arg(ap, char **);
cstr = va_arg(ap, const char **);
if (i < argc) {
str = GET_OPERAND(pic,i);
if (! pic_str_p(str)) {
pic_error(pic, "pic_get_args: expected string");
}
*cstr = pic_str_ptr(str)->str;
*cstr = pic_str_cstr(pic_str_ptr(str));
i++;
}
break;

View File

@ -155,11 +155,11 @@ static void
write_str(pic_state *pic, struct pic_string *str, xFILE *file)
{
size_t i;
const char *cstr = str->str;
const char *cstr = pic_str_cstr(str);
UNUSED(pic);
for (i = 0; i < str->len; ++i) {
for (i = 0; i < pic_strlen(str); ++i) {
if (cstr[i] == '"' || cstr[i] == '\\') {
xfputc('\\', file);
}