commit 4e2cfe55274595f5c971b5e409a316a2091867d0
parent d3fcbd4ed5bc7b59ae782e213ed184fcb3d8d90f
Author: ssnf <ssnf@ssnf.xyz>
Date: Sun, 2 Mar 2025 14:31:02 +0000
add utf8
Diffstat:
M | config.def.h | | | 7 | ++++--- |
M | sim.c | | | 454 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
2 files changed, 348 insertions(+), 113 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -1,8 +1,9 @@
-#define STATUS "%lu,%u 0x%02x %s%s -%lu- %u" \
+#define STATUS "%lu,%u 0x%02lx %s %s%s -%lu- %u" \
, f->dot.p1 \
, curpos() \
- , f->s.s[f->dot.p1] \
- , f->name.n ? f->name.s : "-unnamed-" \
+ , rune \
+ , urune \
+ , fname \
, (f->bd == f->b) ? "" : "*" \
, f - file \
, counter
diff --git a/sim.c b/sim.c
@@ -7,12 +7,14 @@
#define MINSIZE 16
#define MAXEMPTY 256
+#define UTFMAX 6
#define FILECOUNT 8
#define LENGTH(a) (sizeof(a)/sizeof(a[0]))
#define RED(a) CSI "31m" a CSI "0m"
#define GREEN(a) CSI "32m" a CSI "0m"
typedef long Posn;
+typedef ulong Rune;
enum {
Up = 1,
@@ -44,7 +46,7 @@ typedef struct {
} Address;
typedef struct {
- char* s;
+ Rune *s;
ulong n; /*number of filled characters*/
ulong size;
} String;
@@ -86,12 +88,17 @@ typedef struct {
void die(char*, ...);
void* emalloc(ulong);
void* erealloc(void*, ulong);
+static Rune* Strchr(Rune *s, Rune r);
+static String Strn(Rune *r, ulong n);
+static Rune* Strnstr(Rune *s1, Rune *s2, ulong n);
+static String Utf(char* s);
static void blind_reader(Frame* fr, Posn p0);
static void blind_writer(ushort line, ushort offset, ushort top, ushort bot);
static void buf_add(
String* is, String* ds, uint c, uint arg, uint count
);
static void buf_free(Buffer* p);
+static int c2r(Rune *r, uchar c, uchar *seq);
static void change(int arg);
static uint charsiz(char c, ulong wx);
static void count(int arg);
@@ -101,6 +108,7 @@ static void delete(int arg);
static void dot(int arg);
static void redo(int arg);
static void escape(int c);
+static Rune getr(void);
static void init(void);
static void input(String* s, uint line, char* prefix);
static void insert(int arg);
@@ -122,18 +130,22 @@ static void gmove(int arg);
static void msg(uint line, char* fmt, ...);
static void paste(int arg);
static void pline(int arg);
+static uchar r2u(char *s, Rune r);
static void resize(void);
static void search(int arg);
static int selection(int arg);
+static ulong str2u(char** buf, String s);
static void str_init(String* p);
static void str_close(String* p);
+static void str_dup(String* p, String q);
static void str_zero(String* p);
static void str_insure(String* p, ulong n);
-static void str_addc(String* p, int c);
-static void str_adds(String* p, char* s, ulong n);
-static void str_delc(String* p);
-static void str_insert(String* p, String* q, Posn p0);
+static void str_addr(String* p, Rune r);
+static void str_adds(String* p, String q);
+static void str_delr(String* p);
+static void str_insert(String* p, String q, Posn p0);
static void str_delete(String* p, Posn p0, Posn p1);
+static void u2str(String *s, char *u);
static void undo(int arg);
static void move(int);
static void quit(int);
@@ -144,14 +156,21 @@ static File* f, file[FILECOUNT];
static String istr, srch;
static Window w;
static uint counter;
+static char *ctrune[0x20] = {
+ "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
+ "bs" , "\\t", "\\n", "vt" , "ff" , "cr" , "so" , "si",
+ "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
+ "can", "em" , "sub", "esc", "fs" , "gs" , "rs" , "us"
+};
#include "config.h"
void
die(char* fmt, ...)
{
- uint i;
+ static char *s;
va_list ap;
+ uint i;
win_end();
va_start(ap, fmt);
@@ -162,11 +181,13 @@ die(char* fmt, ...)
else
fputc('\n', stderr);
for (i = 0; i < FILECOUNT; ++i) {
- if (!file[i].s.n)
+ f = file + i;
+ if (!f->s.n)
continue;
- str_adds(&file[i].name, ".swap", 5);
+ str_adds(&f->name, Utf(".swap"));
file_save(i);
- fprintf(stderr, "file saved to %s\n", file[i].name.s);
+ str2u(&s, f->name);
+ fprintf(stderr, "file saved to %s\n", s);
}
abort();
}
@@ -192,6 +213,50 @@ erealloc(void* p, ulong n)
return p;
}
+static Rune*
+Strchr(Rune *s, Rune r)
+{
+ for (;*s != '\0'; ++s)
+ if (*s == r)
+ return s;
+ return NULL;
+}
+
+static String
+Strn(Rune *r, ulong n)
+{
+ static String s;
+ ulong l;
+
+ l = (n + 1) * sizeof(*s.s);
+ s.s = erealloc(s.s, l);
+ s.n = n;
+ memcpy(s.s, r, l);
+ s.s[s.n] = '\0';
+ return s;
+}
+
+static Rune*
+Strnstr(Rune *s1, Rune *s2, ulong n)
+{
+ n *= sizeof(*s2);
+ do {
+ s1 = Strchr(s1, s2[0]);
+ if (s1 != NULL && !memcmp(s1, s2, n))
+ return s1;
+ } while (s1++ != NULL);
+ return NULL;
+}
+
+static String
+Utf(char* s)
+{
+ static String t;
+
+ u2str(&t, s);
+ return t;
+}
+
static void
blind_reader(Frame* fr, Posn p0)
{
@@ -221,7 +286,9 @@ blind_reader(Frame* fr, Posn p0)
static void
blind_writer(ushort line, ushort offset, ushort top, ushort bot)
{
- ushort i, o;
+ static char *s;
+ Posn i, o;
+ ulong n;
i = o = 0;
if (offset >= top)
@@ -231,9 +298,10 @@ blind_writer(ushort line, ushort offset, ushort top, ushort bot)
else if (fr->n)
o = fr->n - 1;
curmov(0, offset > line ? 0 : line - offset);
- fwrite(&f->s.s[fr->a[i].p0], fr->a[o].p1 - fr->a[i].p0
- , 1, stdout
- );
+ i = fr->a[i].p0;
+ o = fr->a[o].p1;
+ n = str2u(&s, Strn(f->s.s + i, o - i));
+ fwrite(s, n, 1, stdout);
}
static void
@@ -245,9 +313,9 @@ buf_add(String* is, String* ds, uint c, uint arg, uint count)
f->b->next->prev = f->b;
f->b = f->b->next;
if (is != NULL)
- str_insert(&f->b->is, is, 0);
+ str_insert(&f->b->is, *is, 0);
if (ds != NULL)
- str_insert(&f->b->ds, ds, 0);
+ str_insert(&f->b->ds, *ds, 0);
f->b->c = c;
f->b->arg = arg;
f->b->count = count;
@@ -265,14 +333,52 @@ buf_free(Buffer* p)
free(p);
}
+static int
+c2r(Rune *r, uchar c, uchar *seq)
+{
+ if (*seq != 0) {
+ if ((c & 0xc0) != 0x80) {
+ *seq = 0;
+ return -1;
+ }
+ *r = (*r << 6) | (c & 0x3f);
+ --*seq;
+ return 0;
+ }
+ if ((c & 0x80) == 0) {
+ *r = c & 0x7f;
+ *seq = 0;
+ } else if ((c & 0xe0) == 0xc0) {
+ *r = c & 0x1f;
+ *seq = 1;
+ } else if ((c & 0xf0) == 0xe0) {
+ *r = c & 0x0f;
+ *seq = 2;
+ } else if ((c & 0xf8) == 0xf0) {
+ *r = c & 0x07;
+ *seq = 3;
+ } else if ((c & 0xfc) == 0xf8) {
+ *r = c & 0x03;
+ *seq = 4;
+ } else if ((c & 0xfe) == 0xfc) {
+ *r = c & 0x01;
+ *seq = 5;
+ } else {
+ *r = c;
+ *seq = 0;
+ }
+ return 0;
+}
+
static void
change(int arg)
{
String s;
- uint count;
+ Address *a;
+ uint count;
if (!arg)
- arg = fgetc(stdin);
+ arg = getr();
switch (arg) {
case 'x': arg = Letter; break;
case 'c': arg = Line; break;
@@ -286,15 +392,16 @@ change(int arg)
if (arg == Word || arg == Letter || arg > 0x7f)
++f->dot.p1;
str_init(&s);
- if (f->dot.p0 != f->dot.p1) {
- str_adds(&s, f->s.s + f->dot.p0, f->dot.p1 - f->dot.p0);
- str_delete(&f->s, f->dot.p0, f->dot.p1);
+ a = &f->dot;
+ if (a->p0 != a->p1) {
+ str_adds(&s, Strn(f->s.s + a->p0, a->p1 - a->p0));
+ str_delete(&f->s, a->p0, a->p1);
+ a->p1 = a->p0;
}
- f->dot.p0 = f->dot.p1 = f->dot.p0;
fr_zero(fr);
insert(0);
if (s.n)
- str_insert(&f->b->ds, &s, 0);
+ str_insert(&f->b->ds, s, 0);
f->b->c = Change;
f->b->arg = arg;
f->b->count = count;
@@ -342,12 +449,13 @@ static void
delete(int arg)
{
String s;
- uint count;
+ Address *a;
+ uint count;
if (!f->s.n)
return;
if (!arg) {
- switch (arg = fgetc(stdin)) {
+ switch (arg = getr()) {
case 'x': arg = Letter; break;
case 'd': arg = Line; break;
case 'G': arg = Bottom; break;
@@ -362,15 +470,15 @@ delete(int arg)
if ((arg = selection(arg)) < 0)
return;
str_init(&s);
- str_zero(&istr);
- str_adds(&s, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0);
- str_adds(&istr, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0);
+ a = &f->dot;
+ str_adds(&s, Strn(f->s.s + a->p0, a->p1 + 1 - a->p0));
+ str_dup(&istr, s);
buf_add(NULL, &s, Delete, arg, count);
- str_delete(&f->s, f->dot.p0, f->dot.p1 + 1);
+ str_delete(&f->s, a->p0, a->p1 + 1);
str_close(&s);
- if (f->dot.p0 == f->s.n && f->dot.p0)
- --f->dot.p0;
- f->dot.p1 = f->dot.p0;
+ if (a->p0 == f->s.n && a->p0)
+ --a->p0;
+ a->p1 = a->p0;
fr_update();
}
@@ -378,9 +486,11 @@ static void
dot(int arg)
{
String ds;
+ Address *a;
if (f->b->prev == NULL)
return;
+ a = &f->dot;
arg = f->b->arg;
counter = f->b->count;
switch (f->b->c) {
@@ -389,7 +499,7 @@ dot(int arg)
move(EndLine);
else
move(arg);
- str_insert(&f->s, &f->b->is, f->dot.p0);
+ str_insert(&f->s, f->b->is, a->p0);
buf_add(&f->b->is, NULL, Insert, arg, counter);
break;
case Delete:
@@ -400,14 +510,14 @@ dot(int arg)
if (f->b->ds.n) {
selection(arg);
if (arg == Word || arg == Letter || arg > 0x7f)
- ++f->dot.p1;
- str_adds(
- &ds, f->s.s + f->dot.p0, f->dot.p1 - f->dot.p0
+ ++a->p1;
+ str_adds(&ds
+ , Strn(f->s.s + a->p0, a->p1 - a->p0)
);
- str_delete(&f->s, f->dot.p0, f->dot.p1);
+ str_delete(&f->s, a->p0, a->p1);
}
if (f->b->is.n)
- str_insert(&f->s, &f->b->is, f->dot.p0);
+ str_insert(&f->s, f->b->is, f->dot.p0);
buf_add(&f->b->is, &ds, Change, arg, f->b->count);
str_close(&ds);
f->dot.p1 = f->dot.p0;
@@ -430,7 +540,7 @@ redo(int arg)
if (f->b->ds.n)
str_delete(&f->s, f->b->p0, f->b->p0 + f->b->ds.n);
if (f->b->is.n)
- str_insert(&f->s, &f->b->is, f->b->p0);
+ str_insert(&f->s, f->b->is, f->b->p0);
f->dot.p0 = f->dot.p1 = f->b->p0;
fr_zero(fr);
fr_update();
@@ -450,25 +560,46 @@ escape(int c)
ungetc(c + 0x30, stdin);
}
+static Rune
+getr(void)
+{
+ Rune r;
+ uchar c, seq;
+
+ r = 0;
+ seq = 0;
+ do {
+ c = fgetc(stdin);
+ if (c2r(&r, c, &seq) == -1) {
+ seq = 0;
+ ungetc(c, stdin);
+ }
+ } while (seq != 0);
+ return r;
+}
+
static void
input(String* s, uint line, char* prefix)
{
- uchar c;
+ static char *t;
+ Rune r;
for (;;) {
- msg(line, "%s%s", prefix, s->s);
- switch (c = fgetc(stdin)) {
+ str2u(&t, *s);
+ msg(line, "%s%s", prefix, t);
+ switch (r = getr()) {
case Esc:
str_zero(s);
case '\n':
return;
case Del:
- str_delc(s);
+ str_delr(s);
break;
default:
- str_addc(s, c);
+ str_addr(s, r);
}
}
+ s->s[s->n] = '\0';
}
static int
@@ -493,9 +624,9 @@ insert(int arg)
String s, c;
if (f->s.s[f->s.n - 1] != '\n')
- str_addc(&f->s, '\n');
+ str_addr(&f->s, '\n');
str_init(&s), str_init(&c);
- str_addc(&c, '\0');
+ str_addr(&c, '\0');
switch (arg) {
case StartLine:
case EndLine:
@@ -504,36 +635,35 @@ insert(int arg)
break;
case Down:
move(EndLine);
- str_addc(&s, '\n');
- str_insert(&f->s, &s, f->dot.p0);
+ str_addr(&s, '\n');
+ str_insert(&f->s, s, f->dot.p0);
++f->dot.p1;
break;
}
for (;;) {
resize();
fr_update();
- switch (c.s[0] = fgetc(stdin)) {
+ switch (c.s[0] = getr()) {
case Esc:
goto endmode;
case Del:
if (f->dot.p1 != f->dot.p0) {
- str_delc(&s);
+ str_delr(&s);
str_delete(&f->s, f->dot.p1 - 1, f->dot.p1);
--f->dot.p1;
}
break;
default:
- str_addc(&s, c.s[0]);
- str_insert(&f->s, &c, f->dot.p1);
+ str_addr(&s, c.s[0]);
+ str_insert(&f->s, c, f->dot.p1);
}
f->dot.p1 = f->dot.p0 + s.n;
}
endmode:
- str_zero(&istr);
- str_insert(&istr, &s, 0);
+ str_dup(&istr, s);
for (counter ? --counter : 0; counter; --counter) {
- str_insert(&istr, &s, istr.n);
- str_insert(&f->s, &s, f->dot.p0);
+ str_insert(&istr, s, istr.n);
+ str_insert(&f->s, s, f->dot.p0);
}
buf_add(&istr, NULL, Insert, arg, counter);
str_close(&s), str_close(&c);
@@ -561,13 +691,16 @@ init(void)
static void
file_close(int arg)
{
+ static char *s;
+
if (arg != -1)
f = &file[arg];
if (f->bd != f->b) {
+ str2u(&s, f->name);
msg(w.wy / 2, RED("Save %s?") " [y/n]"
- , f->name.n ? f->name.s : "-unnamed-"
+ , f->name.n ? s : "-unnamed-"
);
- if (fgetc(stdin) == 'y')
+ if (getr() == 'y')
file_save(arg);
}
str_close(&f->s);
@@ -592,19 +725,25 @@ file_init(File* f)
static void
file_load(File* f)
{
- FILE* disk;
-
- if (!(disk = fopen(f->name.s, "r")))
+ FILE *disk;
+ ulong i, n;
+ char *s;
+
+ s = NULL;
+ str2u(&s, f->name);
+ disk = fopen(s, "r");
+ if (disk == NULL)
return;
- fseek(disk, 0, SEEK_END);
- if ((f->s.n = ftell(disk))) {
- str_insure(&f->s, f->s.n);
- rewind(disk);
- fread(f->s.s, f->s.n, 1, disk);
- }
- fclose(disk);
- f->dot.p0 = f->dot.p1 = 0;
- fr_zero(fr);
+ s = NULL;
+ n = 0;
+ do {
+ s = erealloc(s, n + 4096);
+ i = fread(s + n, 1, 4096, disk);
+ n += i;
+ } while (i != 0);
+ s[n] = '\0';
+ u2str(&f->s, s);
+ free(s);
}
static void
@@ -618,19 +757,23 @@ file_open(int arg)
static void
file_save(int arg)
{
- FILE* disk;
+ static char *s;
+ FILE *disk;
+ ulong n;
- if (arg == -1)
- arg = f - file;
- if (!file[arg].name.n) {
- input(&file[arg].name, w.wy / 2, "File name: ");
- if (!file[arg].name.n)
+ if (arg != -1)
+ f = &file[arg];
+ if (!f->name.n) {
+ input(&f->name, w.wy / 2, "File name: ");
+ if (!f->name.n)
return;
}
- disk = fopen(file[arg].name.s, "w");
- fwrite(file[arg].s.s, file[arg].s.n, 1, disk);
+ str2u(&s, f->name);
+ disk = fopen(s, "w");
+ n = str2u(&s, f->s);
+ fwrite(s, n, 1, disk);
fclose(disk);
- file[arg].bd = file[arg].b;
+ f->bd = f->b;
}
static void
@@ -724,7 +867,9 @@ fr_insure(Frame* fr, ushort n)
static void
fr_update(void)
{
- static char stat[128];
+ static char stat[128], u[UTFMAX + 1];
+ static char *fname, *urune;
+ Rune rune;
uint half;
half = w.wy / 2;
@@ -734,6 +879,16 @@ fr_update(void)
blind_writer(half, fr->cur, half, half + (w.wy % 2));
} else
printf(ED);
+ str2u(&fname, f->name.n ? f->name : Utf("-unnamed-"));
+ rune = f->s.s[f->dot.p1];
+ if (rune < 0x20)
+ urune = ctrune[rune];
+ else if (rune == 0x7f)
+ urune = "del";
+ else {
+ r2u(u, rune);
+ urune = u;
+ }
snprintf(stat, w.wx, STATUS); /*i dont care. TODO: care*/
msg(w.wy, "%s", stat);
curmov(curpos() + 1, half);
@@ -886,7 +1041,7 @@ msg(uint line, char* fmt, ...)
static void
paste(int arg)
{
- str_insert(&f->s, &istr, f->dot.p0);
+ str_insert(&f->s, istr, f->dot.p0);
buf_add(&istr, NULL, Insert, 0, 1);
}
@@ -919,6 +1074,44 @@ pline(int arg)
ungetc(i, stdin);
}
+static uchar
+r2u(char *s, Rune r)
+{
+ char* p;
+
+ p = s;
+ if (r < (1 << 7)) {
+ *p++ = r;
+ } else if (r < (1 << 11)) {
+ *p++ = 0xc0 | (r >> 6);
+ *p++ = 0x80 | (r & 0x3f);
+ } else if (r < (1 << 16)) {
+ *p++ = 0xe0 | (r >> 12);
+ *p++ = 0x80 | ((r >> 6) & 0x3f);
+ *p++ = 0x80 | (r & 0x3f);
+ } else if (r < (1 << 21)) {
+ *p++ = 0xf0 | (r >> 18);
+ *p++ = 0x80 | ((r >> 12) & 0x3f);
+ *p++ = 0x80 | ((r >> 6) & 0x3f);
+ *p++ = 0x80 | (r & 0x3f);
+ } else if (r < (1 << 26)) {
+ *p++ = 0xf8 | (r >> 24);
+ *p++ = 0x80 | ((r >> 18) & 0x3f);
+ *p++ = 0x80 | ((r >> 12) & 0x3f);
+ *p++ = 0x80 | ((r >> 6) & 0x3f);
+ *p++ = 0x80 | (r & 0x3f);
+ } else if (r < (1 << 31)) {
+ *p++ = 0xfe | (r >> 30);
+ *p++ = 0x80 | ((r >> 24) & 0x3f);
+ *p++ = 0x80 | ((r >> 18) & 0x3f);
+ *p++ = 0x80 | ((r >> 12) & 0x3f);
+ *p++ = 0x80 | ((r >> 6) & 0x3f);
+ *p++ = 0x80 | (r & 0x3f);
+ }
+ *p = '\0';
+ return p - s;
+}
+
static void
resize(void)
{
@@ -936,7 +1129,7 @@ static void
search(int arg)
{
Posn pos;
- char* p;
+ Rune *r;
f->s.s[f->s.n] = 0;
if (arg == '/' || arg == '?') {
@@ -948,8 +1141,8 @@ search(int arg)
}
if (arg == '/' || arg == 'n') {
move(Right);
- p = strstr(f->s.s + f->dot.p0, srch.s);
- if (p == NULL) {
+ r = Strnstr(f->s.s + f->dot.p0, srch.s, srch.n);
+ if (r == NULL) {
move(Left);
return;
}
@@ -962,16 +1155,18 @@ search(int arg)
&& f->s.s[f->dot.p1] != srch.s[0]
;
);
- if (!strncmp(f->s.s + f->dot.p1, srch.s, srch.n))
+ if (!memcmp(f->s.s + f->dot.p1
+ , srch.s , srch.n * sizeof(*srch.s)
+ ))
break;
if (!f->dot.p1) {
f->dot.p0 = f->dot.p1 = pos;
return;
}
}
- p = f->s.s + f->dot.p1;
+ r = f->s.s + f->dot.p1;
}
- f->dot.p0 = f->dot.p1 = p - f->s.s;
+ f->dot.p0 = f->dot.p1 = r - f->s.s;
if (srch.s[0] == '\n' && srch.s[1] != '\n')
move(Right);
fr_update();
@@ -1021,7 +1216,7 @@ selection(int arg)
move(EndWord);
break;
case Till:
- arg = fgetc(stdin);
+ arg = getr();
if (arg == Esc)
return 0;
till:
@@ -1044,6 +1239,19 @@ selection(int arg)
return arg;
}
+static ulong
+str2u(char** u, String s)
+{
+ ulong i, n;
+
+ n = 0;
+ *u = erealloc(*u, (s.n + 1) * UTFMAX);
+ for (i = 0; i < s.n; ++i)
+ n += r2u(*u + n, s.s[i]);
+ (*u)[n] = '\0';
+ return n;
+}
+
static void
str_init(String* p)
{
@@ -1060,6 +1268,13 @@ str_close(String* p)
}
static void
+str_dup(String* p, String q)
+{
+ str_zero(p);
+ str_adds(p, q);
+}
+
+static void
str_zero(String* p)
{
if (p->size > MAXEMPTY) {
@@ -1067,61 +1282,78 @@ str_zero(String* p)
p->size = MAXEMPTY;
}
p->n = 0;
- memset(p->s, 0, p->size);
+ memset(p->s, 0, p->size * sizeof(*p->s));
}
static void
str_insure(String* p, ulong n)
{
- if (p->size < n) {
+ if (p->size < n + 1) {
p->size = n + MAXEMPTY;
p->s = erealloc(p->s, p->size * sizeof(*p->s));
}
}
static void
-str_addc(String* p, int c)
+str_addr(String* p, Rune r)
{
- str_insure(p, p->n + 2);
- p->s[p->n++] = c;
+ str_insure(p, p->n + 1);
+ p->s[p->n++] = r;
p->s[p->n] = '\0';
}
static void
-str_adds(String* p, char* s, ulong n)
+str_adds(String *p, String q)
{
- str_insure(p, p->n + n + 1);
- memmove(p->s + p->n, s, n);
- p->n += n;
+ str_insure(p, p->n + q.n);
+ memcpy(p->s + p->n, q.s, q.n * sizeof(*q.s));
+ p->n += q.n;
p->s[p->n] = '\0';
}
static void
-str_delc(String* p)
+str_delr(String* p)
{
if (p->n)
- p->s[--p->n] = 0;
+ p->s[--p->n] = '\0';
}
static void
-str_insert(String* p, String* q, Posn p0)
+str_insert(String* p, String q, Posn p0)
{
- str_insure(p, p->n + q->n + 1);
- memmove(p->s + p0 + q->n, p->s + p0, p->n - p0);
- memmove(p->s + p0, q->s, q->n);
- p->n += q->n;
+ str_insure(p, p->n + q.n);
+ memmove(p->s + p0 + q.n, p->s + p0
+ , (p->n - p0) * sizeof(*p->s)
+ );
+ memmove(p->s + p0, q.s, q.n * sizeof(*q.s));
+ p->n += q.n;
p->s[p->n] = '\0';
}
static void
str_delete(String* p, Posn p0, Posn p1)
{
- memmove(p->s + p0, p->s + p1, p->n - p1);
+ memmove(p->s + p0, p->s + p1, (p->n - p1) * sizeof(*p->s));
p->n -= p1 - p0;
p->s[p->n] = '\0';
}
static void
+u2str(String *s, char *u)
+{
+ Rune r;
+ uchar seq;
+
+ str_zero(s);
+ for (seq = 0; *u != '\0'; ++u) {
+ if (c2r(&r, *u, &seq) == -1)
+ --u;
+ else if (seq == 0)
+ str_addr(s, r);
+ }
+}
+
+static void
undo(int arg)
{
if (f->b->prev == NULL)
@@ -1134,7 +1366,7 @@ undo(int arg)
if (f->b->is.n)
str_delete(&f->s, f->b->p0, f->b->p0 + f->b->is.n);
if (f->b->ds.n)
- str_insert(&f->s, &f->b->ds, f->b->p0);
+ str_insert(&f->s, f->b->ds, f->b->p0);
f->dot.p0 = f->dot.p1 = f->b->p0;
f->b = f->b->prev;
fr_zero(fr);
@@ -1144,10 +1376,12 @@ undo(int arg)
static void
yank(int arg)
{
+ Address a;
+
if (!f->s.n)
return;
if (!arg) {
- switch (arg = fgetc(stdin)) {
+ switch (arg = getr()) {
case 'y': arg = Line; break;
case 'G': arg = Bottom; break;
case 'g': arg = Top; break;
@@ -1159,8 +1393,8 @@ yank(int arg)
}
if ((arg = selection(arg)) < 0)
return;
- str_zero(&istr);
- str_adds(&istr, f->s.s + f->dot.p0, f->dot.p1 + 1 - f->dot.p0);
+ a = f->dot;
+ str_dup(&istr, Strn(f->s.s + a.p0, a.p1 + 1 - a.p0));
}
int
@@ -1171,13 +1405,13 @@ main(int argc, char* argv[])
init();
if (argv[1]) {
- str_adds(&f->name, argv[1], strlen(argv[1]));
+ str_adds(&f->name, Utf(argv[1]));
file_load(f);
}
for (;;) {
resize();
fr_update();
- c = fgetc(stdin);
+ c = getr();
for (i = 0; i < LENGTH(keys); ++i) {
if (keys[i].key == c) {
keys[i].func(keys[i].value);