91 lines
1.7 KiB
C
91 lines
1.7 KiB
C
#include "picrin.h"
|
|
|
|
void
|
|
pic_str_set(pic_state *pic, pic_str *str, size_t i, char c)
|
|
{
|
|
pic_str *x, *y, *z, *tmp;
|
|
|
|
if (pic_str_len(str) <= i) {
|
|
pic_errorf(pic, "index out of range %d", i);
|
|
}
|
|
|
|
x = pic_str_sub(pic, str, 0, i);
|
|
y = pic_make_str_fill(pic, 1, c);
|
|
z = pic_str_sub(pic, str, i + 1, pic_str_len(str));
|
|
|
|
tmp = pic_str_cat(pic, x, pic_str_cat(pic, y, z));
|
|
|
|
pic_rope_incref(pic, tmp->rope);
|
|
pic_rope_decref(pic, str->rope);
|
|
str->rope = tmp->rope;
|
|
}
|
|
|
|
static pic_value
|
|
pic_str_string_set(pic_state *pic)
|
|
{
|
|
pic_str *str;
|
|
char c;
|
|
int k;
|
|
|
|
pic_get_args(pic, "sic", &str, &k, &c);
|
|
|
|
pic_str_set(pic, str, k, c);
|
|
return pic_none_value();
|
|
}
|
|
|
|
static pic_value
|
|
pic_str_string_copy_ip(pic_state *pic)
|
|
{
|
|
pic_str *to, *from;
|
|
int n, at, start, end;
|
|
|
|
n = pic_get_args(pic, "sis|ii", &to, &at, &from, &start, &end);
|
|
|
|
switch (n) {
|
|
case 3:
|
|
start = 0;
|
|
case 4:
|
|
end = pic_str_len(from);
|
|
}
|
|
if (to == from) {
|
|
from = pic_str_sub(pic, from, 0, end);
|
|
}
|
|
|
|
while (start < end) {
|
|
pic_str_set(pic, to, at++, pic_str_ref(pic, from, start++));
|
|
}
|
|
return pic_none_value();
|
|
}
|
|
|
|
static pic_value
|
|
pic_str_string_fill_ip(pic_state *pic)
|
|
{
|
|
pic_str *str;
|
|
char c;
|
|
int n, start, end;
|
|
|
|
n = pic_get_args(pic, "sc|ii", &str, &c, &start, &end);
|
|
|
|
switch (n) {
|
|
case 2:
|
|
start = 0;
|
|
case 3:
|
|
end = pic_str_len(str);
|
|
}
|
|
|
|
while (start < end) {
|
|
pic_str_set(pic, str, start++, c);
|
|
}
|
|
return pic_none_value();
|
|
}
|
|
|
|
void
|
|
pic_init_mutable_string(pic_state *pic)
|
|
{
|
|
pic_deflibrary (pic, "(picrin string)") {
|
|
pic_defun(pic, "string-set!", pic_str_string_set);
|
|
pic_defun(pic, "string-copy!", pic_str_string_copy_ip);
|
|
pic_defun(pic, "string-fill!", pic_str_string_fill_ip);
|
|
}
|
|
}
|