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 "xfile/xfile.h"
 | 
			
		||||
#include "xrope/xrope.h"
 | 
			
		||||
 | 
			
		||||
#if __STDC_VERSION__ >= 201112L
 | 
			
		||||
# define NORETURN _Noreturn
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								src/gc.c
								
								
								
								
							
							
						
						
									
										2
									
								
								src/gc.c
								
								
								
								
							| 
						 | 
				
			
			@ -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: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										110
									
								
								src/string.c
								
								
								
								
							
							
						
						
									
										110
									
								
								src/string.c
								
								
								
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										6
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue