commit 4c04189263d4257c639049b2451c323836cb4050
parent 21755d9ef882a3d8a9e10a717eaa56d8a28b5e3e
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Tue, 24 Aug 2021 20:07:16 +0000
repair /ctl commands, add some extra generic functions around
Diffstat:
M | TODO | | | 5 | ----- |
M | array.c | | | 23 | ++++++++++++++++------- |
M | array.h | | | 2 | +- |
M | fs.c | | | 70 | ++++++++++++++++++++++++++++++---------------------------------------- |
M | richterm.c | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
M | richterm.h | | | 2 | ++ |
6 files changed, 104 insertions(+), 63 deletions(-)
diff --git a/TODO b/TODO
@@ -1,8 +1,3 @@
-# /ctl commands
-
-- object removal
-- screen clearing.
-
# images
draw them
diff --git a/array.c b/array.c
@@ -73,15 +73,24 @@ arraygrow(Array *ap, long n, void *v)
}
int
-arraydel(Array *ap, long n)
+arraydel(Array *ap, long offset, long count)
{
- char *v;
- if (_arraycheck(ap, n, "arraydel") != 0) return -1;
+ void *v, *ve;
+ long i;
+ if (_arraycheck(ap, offset + count, "arraydel") != 0) return -1;
+
+ if (ap->free != nil) {
+ for (i = offset; i < offset+ count; i++) {
+ v = arrayget(ap, i, nil);
+ ap->free(v);
+ }
+ }
+
+ v = arrayget(ap, offset, nil);
+ ve = arrayget(ap, offset + count, nil);
qlock(ap->l);
- v = ap->p + ap->size * n;
- if (ap->free != nil) ap->free(v);
- memcpy(v, v + ap->size, (ap->count - n) * ap->size);
- ap->count--;
+ memcpy(v, ve, (ap->count - offset - count) * ap->size);
+ ap->count -= count;
qunlock(ap->l);
return 0;
}
diff --git a/array.h b/array.h
@@ -10,7 +10,7 @@ struct Array {
};
Array * arraycreate(long size, long n, void (*free)(void *));
-int arraydel(Array *, long);
+int arraydel(Array *, long, long);
void arrayfree(Array *);
void * arraygrow(Array *, long, void *);
void * arrayget(Array *, long, void *);
diff --git a/fs.c b/fs.c
@@ -43,7 +43,8 @@ char *
ctlcmd(char *buf)
{
Object *obj;
- int n, i, j;
+ int n, i, j, k;
+ long ne;
char *args[256];
obj = nil;
n = tokenize(buf, args, 256);
@@ -55,22 +56,26 @@ ctlcmd(char *buf)
arrayget(rich.objects, j, &obj);
if (obj == olast) continue;
if (strcmp(obj->id, args[i]) == 0) {
- // objectfree(obj);
- arraydel(rich.objects, j);
+ objsettext(obj, nil, 0);
+ rmobjectftree(obj);
+ objectfree(obj);
+ free(obj);
+ arraydel(rich.objects, j, 1);
break;
}
}
}
} else if (strcmp(args[0], "clear") == 0) {
- int k;
- k = rich.objects->count;
- for (i = 0; i < k; i++) {
- arrayget(rich.objects, 0, &obj);
- if (obj != olast) {
- // objectfree(obj);
- arraydel(rich.objects, 0);
- }
+ for (i = 0; i < rich.objects->count; i++) {
+ arrayget(rich.objects, i, &obj);
+ if (obj != olast) rmobjectftree(obj);
+ objectfree(obj);
+ free(obj);
}
+ rich.objects->count = 0;
+ rich.text->count = 0;
+ olast = objectcreate();
+ arraygrow(rich.objects, 1, &olast);
} else {
qunlock(rich.l);
return "unknown command";
@@ -104,10 +109,8 @@ fs_open(Req *r)
mkobjectftree(newobj, fsctl->tree->root);
objinsertbeforelast(newobj);
- /*
- * Because our newobj is created empty, there's no need
- * to move text from olast around.
- */
+ /* Because our newobj is created empty, there's no need
+ to move text from olast around. */
}
respond(r, nil);
@@ -206,39 +209,26 @@ textwrite(Req *r, void *)
/* TODO: this is not exactly finished */
/* in particular TRUNK/APPEND handling is needed */
- char *p, *pe;
+ char *buf;
Faux *aux;
Object *obj;
- long n, m, dn;
-
- qlock(rich.objects->l);
+ long n, m, k;
aux = r->fid->file->aux;
obj = aux->obj;
- p = rich.text->p + obj->offset;
- pe = rich.text->p + rich.text->count;
- if (obj->next == nil) n = rich.text->count;
- else n = obj->next->offset - obj->offset;
- m = r->ifcall.count + r->ifcall.offset;
- dn = m - n;
- if (dn > 0) arraygrow(rich.text, dn, nil);
- else rich.text->count += dn;
+ n = r->ifcall.offset + r->ifcall.count;
+ m = objtextlen(obj);
+ k = (n > m) ? n : m;
+ buf = malloc(sizeof(char) * k);
- qlock(rich.text->l);
-
- memcpy(p + m, p + n, pe - p);
- memcpy(p + r->ifcall.offset, r->ifcall.data,
- r->ifcall.count);
-
- qunlock(rich.text->l);
-
- for (obj = obj->next; obj != nil; obj = obj->next) {
- obj->offset += dn;
- }
-
- qunlock(rich.objects->l);
+ qlock(rich.l);
+ memcpy(buf, arrayget(rich.text, obj->offset, nil), m);
+ memcpy(buf + r->ifcall.offset, r->ifcall.data, r->ifcall.count);
+ objsettext(obj, buf, k);
+ qunlock(rich.l);
+ free(buf);
}
void
diff --git a/richterm.c b/richterm.c
@@ -389,19 +389,31 @@ objectcreate(void)
void
objectfree(Object *obj)
{
- /* TODO: following should be in separate function rmobjectftree
+ arrayfree(obj->dlink);
+ arrayfree(obj->dimage);
+}
+
+void
+rmobjectftree(Object *obj)
+{
+ free(obj->ftext->aux);
+ free(obj->ffont->aux);
+ free(obj->flink->aux);
+ free(obj->fimage->aux);
+
+ obj->ftext->aux = nil;
+ obj->ffont->aux = nil;
+ obj->flink->aux = nil;
+ obj->fimage->aux = nil;
removefile(obj->ftext);
removefile(obj->ffont);
removefile(obj->flink);
removefile(obj->fimage);
- removefile(obj->dir);
- free(obj->id); */
+ removefile(obj->dir);
- /* TODO: why is this not working? */
- arrayfree(obj->dlink);
- arrayfree(obj->dimage);
+ free(obj->id);
}
Object *
@@ -409,8 +421,6 @@ mkobjectftree(Object *obj, File *root)
{
Faux *auxtext, *auxfont, *auxlink, *auximage;
- qlock(rich.l);
-
obj->id = smprint("%ulld", ++rich.idcount);
obj->dir = createfile(root, obj->id, "richterm", DMDIR|0555, nil);
@@ -431,8 +441,6 @@ mkobjectftree(Object *obj, File *root)
obj->flink = createfile(obj->dir, "link", "richterm", 0666, auxlink);
obj->fimage = createfile(obj->dir, "image", "richterm", 0666, auximage);
- qunlock(rich.l);
-
return obj;
}
@@ -767,3 +775,40 @@ objinsertbeforelast(Object *obj)
olast->prev = obj;
qunlock(rich.l);
}
+
+long
+objtextlen(Object *obj)
+{
+ long n;
+ n = (obj->next == nil) ? rich.text->count : obj->next->offset;
+ return n - obj->offset;
+}
+
+void
+objsettext(Object *obj, char *data, long count)
+{
+ long n, m, dn;
+ char *p, *pe;
+
+ p = arrayget(rich.text, obj->offset, nil);
+ pe = arrayend(rich.text);
+
+ n = objtextlen(obj);
+ m = count;
+ dn = m - n;
+
+ if (dn > 0) arraygrow(rich.text, dn, nil);
+ else rich.text->count += dn;
+
+ qlock(rich.text->l);
+ if (p != nil) memcpy(p + m, p + n, pe - p);
+ else p = pe;
+ memcpy(p, data, count);
+ qunlock(rich.text->l);
+
+ qlock(rich.objects->l);
+ for (obj = obj->next; obj != nil; obj = obj->next) {
+ obj->offset += dn;
+ }
+ qunlock(rich.objects->l);
+}
diff --git a/richterm.h b/richterm.h
@@ -36,6 +36,8 @@ Object * mkobjectftree(Object *, File *);
void objinsertbeforelast(Object *);
void rmobjectftree(Object *);
void objectfree(Object *);
+long objtextlen(Object *obj);
+void objsettext(Object *, char *, long);
extern Array *fonts;