commit 38847929a349c9fe0613c5053213f5b17e9d4d0b
parent 6c013fecdf5b447b4a09069674f60ebca9235f55
Author: ssnf <ssnf@ssnf.xyz>
Date: Fri, 1 Aug 2025 05:03:55 +0000
libstr: fix bugs and update documentation
Diffstat:
6 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/man/man3/str.3 b/man/man3/str.3
@@ -127,6 +127,11 @@ which must be initialized.
Any existing content in
.I p
is replaced.
+The behavior is undefined if
+.I p
+and
+.I s
+refer to the same string.
.PP
.I Straddc
appends character
@@ -152,6 +157,11 @@ at position
Characters after position
.I p
are shifted to make room.
+The behavior is undefined if
+.I s
+and
+.I t
+refer to the same string.
.PP
.I Strdelete
deletes characters from position
@@ -195,8 +205,9 @@ reads a line from
.I b
into string
.IR s .
-The newline character is included if present.
-It returns 1 on success, 0 on end of file, and -1 on error.
+The newline character is removed if present.
+It returns the number of characters read (excluding any newline),
+or 0 on end of file.
.PP
.I Strtok
tokenizes string
@@ -212,7 +223,7 @@ is set to point to the remaining string.
.I Strzero
empties string
.I s
-but retains its allocated space.
+and may shrink strings larger than the initial allocation size.
.PP
.I Strclose
frees the memory used by string
diff --git a/src/libstr/Stradds.c b/src/libstr/Stradds.c
@@ -22,6 +22,8 @@ Strinsure(String *p, ulong n)
{
ulong size;
+ if (!p->size)
+ sysfatal("Strinsure: read-only");
assert(p->s && p->size);
for (size = p->size; n >= size; size *= 2);
if (size != p->size) {
diff --git a/src/libstr/Strgetf.c b/src/libstr/Strgetf.c
@@ -5,6 +5,7 @@ Strgetf(String *p, int fd)
{
ulong n;
+ Strzero(p);
do {
n = read(fd, p->s + p->n, p->size - p->n);
p->n += n;
diff --git a/src/libstr/Strgets.c b/src/libstr/Strgets.c
@@ -7,12 +7,12 @@ Strgets(String *p, Biobuf *b)
ulong n;
Strzero(p);
- s = Brdline(b, '\n');
+ s = Brdstr(b, '\n', '\n');
+ if (!s)
+ return 0;
n = Blinelen(b);
- if (n && s[n - 1] == '\n')
- --n;
- if (n)
- Stradds(p, Strn(s, n));
+ Stradds(p, Strn(s, n));
+ free(s);
return n;
}
diff --git a/src/libstr/Strinit.c b/src/libstr/Strinit.c
@@ -11,6 +11,7 @@ void
Strclose(String *s)
{
free(s->s);
+ s->s = nil;
s->n = 0;
s->size = 0;
}
@@ -30,7 +31,7 @@ Strinit(String *p)
String
Str(char *s)
{
- return !s ? Strn(NULL, 0) : Strn(s, strlen(s));
+ return !s ? Strn(nil, 0) : Strn(s, strlen(s));
}
String
diff --git a/src/libstr/Strprint.c b/src/libstr/Strprint.c
@@ -4,12 +4,14 @@ int
Strprint(String *s, char *fmt, ...)
{
va_list ap;
+ char *t;
+ ulong n;
- if (s->s)
- free(s->s);
va_start(ap, fmt);
- s->s = vsmprint(fmt, ap);
+ t = vsmprint(fmt, ap);
va_end(ap);
- s->n = strlen(s->s);
- return s->n;
+ n = strlen(t);
+ Stradds(s, Strn(t, n));
+ free(t);
+ return n;
}