commit 5bf94bdb21bfe9dc2a4b7816b763ab57e654e229
parent 8b1bf4a393d24479e902f68fdfe35445042c9f06
Author: ssnf <ssnf@ssnf.xyz>
Date: Wed, 9 Jul 2025 07:48:45 +0000
port libstr
Diffstat:
12 files changed, 229 insertions(+), 0 deletions(-)
diff --git a/include/str.h b/include/str.h
@@ -0,0 +1,26 @@
+#define STRSIZ 2
+
+typedef unsigned long Posn;
+
+typedef struct {
+ char *s;
+ ulong n;
+ ulong size;
+} String;
+
+void Straddc(String*, int);
+void Stradds(String*, String);
+void Strclose(String*);
+void Strdelc(String*);
+void Strdelete(String*, Posn, Posn);
+void Strdup(String*, String);
+void Strgetf(String*, int);
+int Strgets(String*, Biobuf*);
+void Strinit(String*);
+void Strinsert(String*, String, Posn);
+void Strinsure(String*, ulong);
+int Strprint(String*, char*, ...);
+String Str(char*);
+String Strn(char*, ulong);
+void Strtok(String*, char*, char*, char**);
+void Strzero(String*);
diff --git a/src/libstr/Stradds.c b/src/libstr/Stradds.c
@@ -0,0 +1,33 @@
+#include "std.h"
+
+void
+Straddc(String *p, int c)
+{
+ Strinsure(p, p->n + 1);
+ p->s[p->n++] = c;
+ p->s[p->n] = '\0';
+}
+
+void
+Stradds(String *p, String s)
+{
+ Strinsure(p, p->n + s.n);
+ memmove(p->s + p->n, s.s, s.n);
+ p->n += s.n;
+ p->s[p->n] = '\0';
+}
+
+void
+Strinsure(String *p, ulong n)
+{
+ ulong size;
+
+ assert(p->s && p->size);
+ for (size = p->size; n >= size; size *= 2);
+ if (size != p->size) {
+ p->size = size;
+ p->s = realloc(p->s, p->size);
+ if (!p->s)
+ sysfatal("realloc(): %r");
+ }
+}
diff --git a/src/libstr/Strdelete.c b/src/libstr/Strdelete.c
@@ -0,0 +1,16 @@
+#include "std.h"
+
+void
+Strdelc(String *p)
+{
+ if (p->n)
+ p->s[--p->n] = '\0';
+}
+
+void
+Strdelete(String *p, Posn p0, Posn p1)
+{
+ memmove(p->s + p0, p->s + p1, p->n - p1);
+ p->n -= p1 - p0;
+ p->s[p->n] = '\0';
+}
diff --git a/src/libstr/Strgetf.c b/src/libstr/Strgetf.c
@@ -0,0 +1,14 @@
+#include "std.h"
+
+void
+Strgetf(String *p, int fd)
+{
+ ulong n;
+
+ do {
+ n = read(fd, p->s + p->n, p->size - p->n);
+ p->n += n;
+ Strinsure(p, p->n + 1);
+ } while (n);
+ p->s[p->n] = '\0';
+}
diff --git a/src/libstr/Strgets.c b/src/libstr/Strgets.c
@@ -0,0 +1,15 @@
+#include "std.h"
+
+int
+Strgets(String *p, Biobuf *b)
+{
+ char *s;
+
+ Strzero(p);
+ s = Brdline(b, '\n');
+ p->n = Blinelen(b);
+ if (p->n)
+ Stradds(p, Strn(s, p->n));
+ return p->n;
+}
+
diff --git a/src/libstr/Strinit.c b/src/libstr/Strinit.c
@@ -0,0 +1,45 @@
+#include "std.h"
+
+void
+Strdup(String *p, String s)
+{
+ Strzero(p);
+ Stradds(p, s);
+}
+
+void
+Strclose(String *s)
+{
+ free(s->s);
+ s->n = 0;
+ s->size = 0;
+}
+
+void
+Strinit(String *p)
+{
+ p->s = malloc(STRSIZ);
+ if (!p->s)
+ sysfatal("malloc: %r");
+ p->s[0] = '\0';
+ p->n = 0;
+ p->size = STRSIZ;
+}
+
+
+String
+Str(char *s)
+{
+ return !s ? Strn(NULL, 0) : Strn(s, strlen(s));
+}
+
+String
+Strn(char *s, ulong n)
+{
+ String S;
+
+ S.s = s;
+ S.n = n;
+ S.size = 0;
+ return S;
+}
diff --git a/src/libstr/Strinsert.c b/src/libstr/Strinsert.c
@@ -0,0 +1,11 @@
+#include "std.h"
+
+void
+Strinsert(String *p, String q, Posn p0)
+{
+ Strinsure(p, p->n + q.n);
+ memmove(p->s + p0 + q.n, p->s + p0, p->n - p0);
+ memmove(p->s + p0, q.s, q.n);
+ p->n += q.n;
+ p->s[p->n] = '\0';
+}
diff --git a/src/libstr/Strprint.c b/src/libstr/Strprint.c
@@ -0,0 +1,15 @@
+#include "std.h"
+
+int
+Strprint(String *s, char *fmt, ...)
+{
+ va_list ap;
+
+ if (s->s)
+ free(s->s);
+ va_start(ap, fmt);
+ s->s = vsmprint(fmt, ap);
+ va_end(ap);
+ s->n = strlen(s->s);
+ return s->n;
+}
diff --git a/src/libstr/Strtok.c b/src/libstr/Strtok.c
@@ -0,0 +1,18 @@
+#include "std.h"
+
+void
+Strtok(String *p, char *str, char *sep, char **last)
+{
+ char *q;
+
+ if (str != NULL)
+ *last = str;
+ if (*last == NULL)
+ sysfatal("libstr: wrong Strtok() usage.");
+ q = strpbrk(*last, sep);
+ if (q == NULL)
+ q = *last + strlen(*last);
+ Strzero(p);
+ Stradds(p, Strn(*last, q - *last));
+ *last = (*q == '\0') ? q : q + 1;
+}
diff --git a/src/libstr/Strzero.c b/src/libstr/Strzero.c
@@ -0,0 +1,14 @@
+#include "std.h"
+
+void
+Strzero(String *p)
+{
+ if (p->size > STRSIZ) {
+ p->size = STRSIZ;
+ p->s = realloc(p->s, p->size);
+ if (!p->s)
+ sysfatal("realloc(): %r");
+ }
+ p->n = 0;
+ memset(p->s, 0, p->size);
+}
diff --git a/src/libstr/mkfile b/src/libstr/mkfile
@@ -0,0 +1,18 @@
+<$PLAN9/src/mkhdr
+
+LIB=libstr.a
+
+OFILES=\
+ Stradds.$O\
+ Strdelete.$O\
+ Strgetf.$O\
+ Strgets.$O\
+ Strinit.$O\
+ Strinsert.$O\
+ Strprint.$O\
+ Strtok.$O\
+ Strzero.$O\
+
+HFILES= $PLAN9/include/str.h
+
+<$PLAN9/src/mksyslib
diff --git a/src/libstr/std.h b/src/libstr/std.h
@@ -0,0 +1,4 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <str.h>