From 521d01e8ad87e931af3e9a763cc84a6cf7fe5ee3 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sun, 5 Dec 2021 09:47:21 -0800 Subject: Feat: basic string and memory functions Continue filling out the basic standard lib functions. Included prototypes of the str* and mem* families. Plan to add e(str|mem) and n(str|mem) variants as well. --- src/base/fmt/nsprint.c | 4 ++-- src/base/fmt/sprint.c | 2 +- src/base/fmt/vnsprint.c | 2 +- src/base/fs/walk.c | 2 +- src/base/fs/walker.c | 2 +- src/base/io/getc.c | 4 ++-- src/base/io/read.c | 4 ++-- src/base/io/readuntil.c | 6 ++--- src/base/io/write.c | 2 +- src/base/mem/compare.c | 12 ++++++++++ src/base/mem/copy.c | 2 +- src/base/mem/move.c | 2 +- src/base/mem/rules.mk | 10 +-------- src/base/mem/set.c | 2 +- src/base/mem/set32.c | 15 +++++++++++++ src/base/mem/set64.c | 4 ++-- src/base/string/append.c | 16 ++++++------- src/base/string/appendf.c | 24 +++++++------------- src/base/string/atoi.c | 11 --------- src/base/string/clear.c | 2 +- src/base/string/copyn.c | 11 --------- src/base/string/equals.c | 10 +++++---- src/base/string/find.c | 10 +++++---- src/base/string/fit.c | 9 ++++---- src/base/string/free.c | 2 +- src/base/string/grow.c | 6 ++--- src/base/string/itoa.c | 23 ------------------- src/base/string/join.c | 8 +++---- src/base/string/len.c | 4 ++-- src/base/string/lower.c | 4 ++-- src/base/string/make.c | 20 ++++++++--------- src/base/string/makef.c | 19 +++++++--------- src/base/string/raw/append.c | 9 ++++++++ src/base/string/raw/atoi.c | 9 ++++++++ src/base/string/raw/compare.c | 18 +++++++++++++++ src/base/string/raw/copy.c | 9 ++++++++ src/base/string/raw/eappend.c | 9 ++++++++ src/base/string/raw/ecompare.c | 20 +++++++++++++++++ src/base/string/raw/ecopy.c | 12 ++++++++++ src/base/string/raw/efind.c | 48 +++++++++++++++++++++++++++++++++++++++ src/base/string/raw/efindc.c | 15 +++++++++++++ src/base/string/raw/find.c | 48 +++++++++++++++++++++++++++++++++++++++ src/base/string/raw/findc.c | 12 ++++++++++ src/base/string/raw/itoa.c | 21 +++++++++++++++++ src/base/string/raw/len.c | 10 +++++++++ src/base/string/raw/nappend.c | 9 ++++++++ src/base/string/raw/ncompare.c | 17 ++++++++++++++ src/base/string/raw/ncopy.c | 9 ++++++++ src/base/string/raw/nfind.c | 51 ++++++++++++++++++++++++++++++++++++++++++ src/base/string/raw/nfindc.c | 12 ++++++++++ src/base/string/raw/rules.mk | 1 + src/base/string/read.c | 4 ++-- src/base/string/replace.c | 4 ++-- src/base/string/rules.mk | 24 +++----------------- src/base/string/split.c | 26 ++++++++++----------- src/base/string/upper.c | 4 ++-- src/libbio/newick.c | 8 +++---- 57 files changed, 476 insertions(+), 187 deletions(-) create mode 100644 src/base/mem/compare.c create mode 100644 src/base/mem/set32.c delete mode 100644 src/base/string/atoi.c delete mode 100644 src/base/string/copyn.c delete mode 100644 src/base/string/itoa.c create mode 100644 src/base/string/raw/append.c create mode 100644 src/base/string/raw/atoi.c create mode 100644 src/base/string/raw/compare.c create mode 100644 src/base/string/raw/copy.c create mode 100644 src/base/string/raw/eappend.c create mode 100644 src/base/string/raw/ecompare.c create mode 100644 src/base/string/raw/ecopy.c create mode 100644 src/base/string/raw/efind.c create mode 100644 src/base/string/raw/efindc.c create mode 100644 src/base/string/raw/find.c create mode 100644 src/base/string/raw/findc.c create mode 100644 src/base/string/raw/itoa.c create mode 100644 src/base/string/raw/len.c create mode 100644 src/base/string/raw/nappend.c create mode 100644 src/base/string/raw/ncompare.c create mode 100644 src/base/string/raw/ncopy.c create mode 100644 src/base/string/raw/nfind.c create mode 100644 src/base/string/raw/nfindc.c create mode 100644 src/base/string/raw/rules.mk (limited to 'src') diff --git a/src/base/fmt/nsprint.c b/src/base/fmt/nsprint.c index 90489e0..598b0a5 100644 --- a/src/base/fmt/nsprint.c +++ b/src/base/fmt/nsprint.c @@ -1,13 +1,13 @@ #include "internal.h" int -fmt·nsprint(int len, char *buf, char *fmt, ...) +fmt·nsprint(char *buf, int len, char *fmt, ...) { int n; va_list args; va_start(args, fmt); - n = fmt·vnsprint(len, buf, fmt, args); + n = fmt·vnsprint(buf, len, fmt, args); va_end(args); return n; diff --git a/src/base/fmt/sprint.c b/src/base/fmt/sprint.c index f1be6dd..3d895df 100644 --- a/src/base/fmt/sprint.c +++ b/src/base/fmt/sprint.c @@ -12,7 +12,7 @@ fmt·sprint(char *buf, char *fmt, ...) len = -(uintptr)buf-1; va_start(args, fmt); - n = fmt·vnsprint(len, buf, fmt, args); + n = fmt·vnsprint(buf, len, fmt, args); va_end(args); return n; diff --git a/src/base/fmt/vnsprint.c b/src/base/fmt/vnsprint.c index 7ded908..7263c3b 100644 --- a/src/base/fmt/vnsprint.c +++ b/src/base/fmt/vnsprint.c @@ -1,7 +1,7 @@ #include "internal.h" int -fmt·vnsprint(int len, char *buf, char *fmt, va_list args) +fmt·vnsprint(char *buf, int len, char *fmt, va_list args) { fmt·State io; diff --git a/src/base/fs/walk.c b/src/base/fs/walk.c index 752791d..4b0d0aa 100644 --- a/src/base/fs/walk.c +++ b/src/base/fs/walk.c @@ -95,7 +95,7 @@ fs·walk(fs·Walker *fs) (d->d_name[1] == '.' && d->d_name[2] == 0)) /* .. */ continue; - fs->end = str·copyn(fs->base, d->d_name, arrend(fs->path) - fs->base); + fs->end = str·ncopy(fs->base, arrend(fs->path) - fs->base, d->d_name); fs->lev++; fs·walk(fs); diff --git a/src/base/fs/walker.c b/src/base/fs/walker.c index 4ef35cf..d988d13 100644 --- a/src/base/fs/walker.c +++ b/src/base/fs/walker.c @@ -17,7 +17,7 @@ fs·init(fs·Walker *fs, char *path) return 1; fs->end += strlen(path); }else - fs->end = str·copyn(fs->base, path, arrlen(fs->path)); + fs->end = str·ncopy(fs->base, arrlen(fs->path), path); if(fs->path[0] != '/') fs->fd = AT_FDCWD; diff --git a/src/base/io/getc.c b/src/base/io/getc.c index 68e1772..0f0d62e 100644 --- a/src/base/io/getc.c +++ b/src/base/io/getc.c @@ -23,7 +23,7 @@ loop: * get next buffer, try to keep io·BufUngets bytes * pre-catenated from the previous read to allow for ungets */ - mem·move(io->b-io·BufUngets, io->e-io·BufUngets, io·BufUngets); + mem·move(io->b-io·BufUngets, io·BufUngets, io->e-io·BufUngets); if(sys·read(io->fd, io->cap, io->b, &nr)){ io->state = io·BufNil; return io·BufEof; @@ -34,7 +34,7 @@ loop: } if(nr < io->cap){ - mem·move(io->e-i-io·BufUngets, io->b-io·BufUngets, i+io·BufUngets); + mem·move(io->e-i-io·BufUngets, i+io·BufUngets, io->b-io·BufUngets); io->g = io->e-i; } diff --git a/src/base/io/read.c b/src/base/io/read.c index d4f7bd9..a972c3e 100644 --- a/src/base/io/read.c +++ b/src/base/io/read.c @@ -35,13 +35,13 @@ io·read(io·Header *io, intptr len, void *buf) io->pos += nr; if(nr < io->cap){ io->g = io->e-nr; - mem·move(io->g, io->b, nr); + mem·move(io->g, nr, io->b); } ic -= nr; continue; } /* move our read bytes into the caller's buffer */ - mem·move(b, io->e+ic, n); + mem·move(b, n, io->e+ic); c -= n; ic += n; b += n; diff --git a/src/base/io/readuntil.c b/src/base/io/readuntil.c index d5c2ed6..3fe3925 100644 --- a/src/base/io/readuntil.c +++ b/src/base/io/readuntil.c @@ -27,14 +27,14 @@ io·readuntil(io·Header *io, int delim) } /* ok no luck, shift over the data and get more */ if(i < io->cap) - mem·move(io->b, b, i); + mem·move(io->b, i, b); io->g = io->b; /* write to the buffer while we search for delim */ b = (char *)io->b + i; while(i < io->cap){ if(sys·read(io->fd, io->cap-i, b, &j) || j == 0){ - mem·move(io->e-i, io->b, i); + mem·move(io->e-i, i, io->b); io->nread = +i; io->ilen = -i; io->g = io->e - i; @@ -47,7 +47,7 @@ io·readuntil(io·Header *io, int delim) /* finally have a hit. reset the world */ b = (char*)io->e - i; if(i < io->cap){ - mem·move(b, io->b, i); + mem·move(b, i, io->b); io->g = (uchar *)b; } j = (e - (char*)io->b) + 1; diff --git a/src/base/io/write.c b/src/base/io/write.c index 2f37200..554aa88 100644 --- a/src/base/io/write.c +++ b/src/base/io/write.c @@ -30,7 +30,7 @@ io·write(io·Header *io, intptr len, void *buf) return io·BufEof; } } - mem·move(io->e+o, b, n); + mem·move(io->e+o, n, b); o += n; c -= n; b += n; diff --git a/src/base/mem/compare.c b/src/base/mem/compare.c new file mode 100644 index 0000000..a2cdd1f --- /dev/null +++ b/src/base/mem/compare.c @@ -0,0 +1,12 @@ +#include + +int +mem·compare(void *qry, void *ref, uintptr size) +{ + intptr i; + char *q=qry, *r=ref; + for(i=0; i < size; i++) + if(q[i] != r[i]) + return q[i] - r[i]; + return 0; +} diff --git a/src/base/mem/copy.c b/src/base/mem/copy.c index 5ce4f90..001d5e5 100644 --- a/src/base/mem/copy.c +++ b/src/base/mem/copy.c @@ -1,7 +1,7 @@ #include "internal.h" int -mem·copy(void *dst, void *src, uintptr len) +mem·copy(void *dst, uintptr len, void *src) { char *d, *s; if((long)len < 0) diff --git a/src/base/mem/move.c b/src/base/mem/move.c index 5ad4074..7f6e906 100644 --- a/src/base/mem/move.c +++ b/src/base/mem/move.c @@ -1,7 +1,7 @@ #include "internal.h" int -mem·move(void *dst, void *src, uintptr len) +mem·move(void *dst, uintptr len, void *src) { char *d, *s; if((long)len < 0) diff --git a/src/base/mem/rules.mk b/src/base/mem/rules.mk index a4d9f10..9f07d34 100644 --- a/src/base/mem/rules.mk +++ b/src/base/mem/rules.mk @@ -1,9 +1 @@ -SRCS_$(d)+=\ - $(d)/mem/arena.c\ - $(d)/mem/buffer.c\ - $(d)/mem/interface.c\ - $(d)/mem/set.c\ - $(d)/mem/set64.c\ - $(d)/mem/findc.c\ - $(d)/mem/copy.c\ - $(d)/mem/move.c +SRCS_$(d)+=$(wildcard $(d)/mem/*.c) diff --git a/src/base/mem/set.c b/src/base/mem/set.c index 2e296be..cb19cae 100644 --- a/src/base/mem/set.c +++ b/src/base/mem/set.c @@ -1,7 +1,7 @@ #include "internal.h" int -mem·set(void *addr, int c, uintptr len) +mem·set(void *addr, uintptr len, int c) { char *a = addr; diff --git a/src/base/mem/set32.c b/src/base/mem/set32.c new file mode 100644 index 0000000..21ad64f --- /dev/null +++ b/src/base/mem/set32.c @@ -0,0 +1,15 @@ +#include "internal.h" + +int +mem·set32(void *dst, uintptr size, uint32 val) +{ + intptr i; + + for(i = 0; i < (size & (~3)); i += 4) + mem·copy((byte*)dst + i, 4, &val); + + for(; i < size; i++) + ((byte*)dst)[i] = ((byte*)&val)[i&3]; + + return 0; +} diff --git a/src/base/mem/set64.c b/src/base/mem/set64.c index 7000866..669c70c 100644 --- a/src/base/mem/set64.c +++ b/src/base/mem/set64.c @@ -1,12 +1,12 @@ #include "internal.h" int -mem·set64(void *dst, uint64 val, uintptr size) +mem·set64(void *dst, uintptr size, uint64 val) { intptr i; for(i = 0; i < (size & (~7)); i += 8) - memcpy((byte*)dst + i, &val, 8); + mem·copy((byte*)dst + i, 8, &val); for(; i < size; i++) ((byte*)dst)[i] = ((byte*)&val)[i&7]; diff --git a/src/base/string/append.c b/src/base/string/append.c index d4d0396..60e1b48 100644 --- a/src/base/string/append.c +++ b/src/base/string/append.c @@ -5,20 +5,20 @@ // string to our buffer. the result is reallocated if not enough room is present // in the buffer. int -str·appendlen(string *s, vlong n, const byte* b) +string·appendlen(string *s, vlong n, byte* b) { /* bl = strlen(b); if (n > bl) panicf("attempted to make a substring longer than string"); */ - str·grow(s, n); + string·grow(s, n); if(*s == nil) return 0; Hdr* h = (Hdr*)(*s - sizeof(Hdr)); - memcpy(*s + str·len(*s), b, n); + memcpy(*s + string·len(*s), b, n); h->len += n; (*s)[h->len] = '\0'; @@ -28,24 +28,24 @@ str·appendlen(string *s, vlong n, const byte* b) // append will append the given null terminated c string to the string data // structure. this variant will append the entire string. int -str·append(string *s, const byte* b) +string·append(string *s, byte* b) { - return str·appendlen(s, strlen(b), b); + return string·appendlen(s, strlen(b), b); } // appendbyte will append the given byte to our string. // NOTE: as the byte is on the stack, it is not null-terminated. // can not pass to the above functions. int -str·appendbyte(string *s, const byte b) +string·appendbyte(string *s, byte b) { - str·grow(s, 1); + string·grow(s, 1); if(*s == nil) return 0; Hdr* h = (Hdr*)(*s - sizeof(Hdr)); - *(*s + str·len(*s)) = b; + *(*s + string·len(*s)) = b; h->len++; (*s)[h->len] = '\0'; // NOTE: I don't think an explicit zero is required..? diff --git a/src/base/string/appendf.c b/src/base/string/appendf.c index 4b8d76c..dee2065 100644 --- a/src/base/string/appendf.c +++ b/src/base/string/appendf.c @@ -6,26 +6,18 @@ */ int -str·appendf(string *s, const byte* fmt, ...) +string·appendf(string *s, byte* fmt, ...) { + int r, n; va_list args; + va_start(args, fmt); - int remain = str·cap(*s) - str·len(*s); - int n = vsnprintf(*s + str·len(*s), remain + 1, fmt, args); + do{ + r = string·cap(*s) - string·len(*s); + n = fmt·vnsprint(*s + string·len(*s), r+1, fmt, args); + string·grow(s, 2*string·cap(*s)); + }while(n==r); va_end(args); - if(n > remain){ - // If the first write was incomplete, we overwite the data again. - str·grow(s, n); - va_list args; - va_start(args, fmt); - n = vsnprintf(*s + str·len(*s), n + 1, fmt, args); - assert(n - remain <= str·cap(*s)); - va_end(args); - } - - Hdr* h = (Hdr*)(*s - sizeof(Hdr)); - h->len += n; - return n; } diff --git a/src/base/string/atoi.c b/src/base/string/atoi.c deleted file mode 100644 index dba057a..0000000 --- a/src/base/string/atoi.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "internal.h" - -int -str·atoi(char *s) -{ - int n = 0; - while(*s) - n = 10*n + (*s++ - '0'); - - return n; -} diff --git a/src/base/string/clear.c b/src/base/string/clear.c index 986f809..fae6536 100644 --- a/src/base/string/clear.c +++ b/src/base/string/clear.c @@ -1,7 +1,7 @@ #include "internal.h" void -str·clear(string *s) +string·clear(string *s) { Hdr* h = (Hdr*)(*s - sizeof(Hdr)); h->len = 0; diff --git a/src/base/string/copyn.c b/src/base/string/copyn.c deleted file mode 100644 index 09c2879..0000000 --- a/src/base/string/copyn.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "internal.h" - -char * -str·copyn(char *dst, char *src, int n) -{ - while(*src && n-- > 0) - *dst++ = *src++; - - *dst = 0; - return dst; -} diff --git a/src/base/string/equals.c b/src/base/string/equals.c index a975cf5..3637d67 100644 --- a/src/base/string/equals.c +++ b/src/base/string/equals.c @@ -2,11 +2,13 @@ // Equals returns true if string s and t are equivalent. bool -str·equals(const string s, const string t) +string·equals(string s, string t) { - vlong sL = str·len(s); - vlong tL = str·len(t); - if (sL != tL) return false; + vlong sL = string·len(s); + vlong tL = string·len(t); + + if(sL != tL) + return false; return memcmp(s, t, sL) == 0; } diff --git a/src/base/string/find.c b/src/base/string/find.c index 20f990e..821094d 100644 --- a/src/base/string/find.c +++ b/src/base/string/find.c @@ -3,9 +3,11 @@ // find will find the first occurence of // substr in the string returns -1 if nothing was found. int -str·find(string s, const byte* substr) +string·find(string s, char* substr) { - byte* loc = strstr(s, substr); - if (loc == nil) return -1; - return (int)(loc - s); + char* loc = str·find(s, substr); + + if(loc == nil) + return -1; + return(int)(loc - s); } diff --git a/src/base/string/fit.c b/src/base/string/fit.c index 56ab041..23d4200 100644 --- a/src/base/string/fit.c +++ b/src/base/string/fit.c @@ -4,13 +4,14 @@ // buffer. if the capacity equals the length, then the function is a noop. the // byte array is unchanged. void -str·fit(string *s) +string·fit(string *s) { Hdr* h; - vlong cap = str·cap(*s); - vlong len = str·len(*s); + vlong cap = string·cap(*s); + vlong len = string·len(*s); - if (cap == len) return; + if(cap == len) + return; h = (Hdr*)(s - sizeof(Hdr)); h = realloc(h, sizeof(*h) + len + 1); diff --git a/src/base/string/free.c b/src/base/string/free.c index 7b5ee98..7e0301b 100644 --- a/src/base/string/free.c +++ b/src/base/string/free.c @@ -2,7 +2,7 @@ // free returns memory associated to the buffer. void -str·free(string s) +string·free(string s) { free(s - sizeof(Hdr)); } diff --git a/src/base/string/grow.c b/src/base/string/grow.c index 39a9d2f..6abe4cc 100644 --- a/src/base/string/grow.c +++ b/src/base/string/grow.c @@ -4,11 +4,11 @@ // if it already can, this is a no op. // if it can't, the string will be reallocated. void -str·grow(string *s, vlong delta) +string·grow(string *s, vlong delta) { Hdr *h, *newh; - vlong cap = str·cap(*s); - vlong len = str·len(*s); + vlong cap = string·cap(*s); + vlong len = string·len(*s); assert(cap >= len); // To prevent unsigned behavior if (cap - len >= delta) return; diff --git a/src/base/string/itoa.c b/src/base/string/itoa.c deleted file mode 100644 index a2910f4..0000000 --- a/src/base/string/itoa.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "internal.h" - -static char * -kernel(char *s, int x) -{ - if(x/10) - s = kernel(s, x/10); - *s++ = x%10 + '0'; - return s; -} - -char * -str·itoa(char *s, int x) -{ - if(x<0){ - *s++ = '-'; - x=-x; - } - s = kernel(s, x); - *s = '0'; - - return s; -} diff --git a/src/base/string/join.c b/src/base/string/join.c index fb97b6c..04d4739 100644 --- a/src/base/string/join.c +++ b/src/base/string/join.c @@ -1,15 +1,15 @@ #include "internal.h" string -str·join(vlong len, byte** fields, const byte* sep) +string·join(vlong len, byte** fields, byte* sep) { - string s = str·makecap("", 0, 10); + string s = string·makecap("", 0, 10); int j = 0; for (j = 0; j < len; j++) { - str·append(&s, fields[j]); + string·append(&s, fields[j]); if (j < len - 1) - str·appendlen(&s, 1, sep); + string·appendlen(&s, 1, sep); } return s; diff --git a/src/base/string/len.c b/src/base/string/len.c index 5e42919..cd0c360 100644 --- a/src/base/string/len.c +++ b/src/base/string/len.c @@ -2,7 +2,7 @@ // len returns the length of the string. int -str·len(const string s) +string·len(string s) { Hdr* h = (Hdr*)(s - sizeof(Hdr)); return h->len; @@ -10,7 +10,7 @@ str·len(const string s) // cap returns the capacity of the string buffer. int -str·cap(const string s) +string·cap(string s) { Hdr* h = (Hdr*)(s - sizeof(Hdr)); return h->cap; diff --git a/src/base/string/lower.c b/src/base/string/lower.c index c6935f8..00556d6 100644 --- a/src/base/string/lower.c +++ b/src/base/string/lower.c @@ -2,11 +2,11 @@ // lower will force all runes in the string to be lowercase void -str·lower(string s) +string·lower(string s) { byte *b, *e; b = s; - e = b + str·len(s); + e = b + string·len(s); while (b++ != e) *b = tolower(*b); } diff --git a/src/base/string/make.c b/src/base/string/make.c index eb71543..d1e594a 100644 --- a/src/base/string/make.c +++ b/src/base/string/make.c @@ -4,21 +4,21 @@ // len defines the length of the c substring that we will copy into our buffer. // the backing buffer will have capacity cap. string -str·makecap(const byte *s, vlong len, vlong cap) +string·makecap(byte *s, vlong len, vlong cap) { struct Hdr* h; h = malloc(sizeof(*h) + cap + 1); - if (s == nil) memset(h, 0, sizeof(*h)); + if(s == nil) memset(h, 0, sizeof(*h)); - if (h == nil) return nil; // Allocation failed. + if(h == nil) return nil; // Allocation failed. h->len = (s == nil) ? 0 : len; h->cap = cap; - if (cap < h->len) goto cleanup; + if(cap < h->len) goto cleanup; - if (s != nil && cap > 0) { + if(s != nil && cap > 0){ memcpy(h->buf, s, h->len); memset(h->buf + h->len, '\0', h->cap - h->len + 1); } @@ -34,20 +34,20 @@ cleanup: // new returns a new dynamic string object, initialized from the given c string. // the backing buffer capacity is equivalent to the string length. string -str·makelen(const byte *s, vlong len) +string·makelen(byte *s, vlong len) { vlong sl = (!s) ? 0 : strlen(s); - if (sl < len) panicf("attempted to take a bigger substring than string length"); + if(sl < len) panicf("attempted to take a bigger substring than string length"); vlong cap = (len == 0) ? 1 : len; - return str·makecap(s, len, cap); + return string·makecap(s, len, cap); } // new returns a new dynamic string object, initialized from the given c string. // the backing buffer capacity is equivalent to the string length. string -str·make(const byte *s) +string·make(byte *s) { vlong len = (!s) ? 0 : strlen(s); - return str·makelen(s, len); + return string·makelen(s, len); } diff --git a/src/base/string/makef.c b/src/base/string/makef.c index 8fb9c38..1e0d917 100644 --- a/src/base/string/makef.c +++ b/src/base/string/makef.c @@ -1,25 +1,22 @@ #include "internal.h" -// Newf returns a new dynamic string object +// makef returns a new dynamic string object string -str·makef(const byte *fmt, ...) +string·makef(byte *fmt, ...) { vlong n; string s; va_list args; + char bytes[256]; - va_start(args, fmt); - n = vsnprintf(nil, 0, fmt, args); - va_end(args); - - s = str·makecap(nil, 0, n); + s = string·makecap(nil, 0, arrlen(bytes)); va_start(args, fmt); - vsnprintf(s, n + 1, fmt, args); + do{ + n = fmt·vnsprint(bytes, arrlen(bytes), fmt, args); + string·append(&s, bytes); + }while(n==arrlen(bytes)); va_end(args); - Hdr* h = (Hdr*)(s - sizeof(Hdr)); - h->len = n; - return s; } diff --git a/src/base/string/raw/append.c b/src/base/string/raw/append.c new file mode 100644 index 0000000..3a4c37e --- /dev/null +++ b/src/base/string/raw/append.c @@ -0,0 +1,9 @@ +#include +#include + +char * +str·append(char *dst, char *src) +{ + str·copy(dst+str·len(dst), src); + return dst; +} diff --git a/src/base/string/raw/atoi.c b/src/base/string/raw/atoi.c new file mode 100644 index 0000000..8084e3e --- /dev/null +++ b/src/base/string/raw/atoi.c @@ -0,0 +1,9 @@ +int +str·atoi(char *s) +{ + int n = 0; + while(*s) + n = 10*n + (*s++ - '0'); + + return n; +} diff --git a/src/base/string/raw/compare.c b/src/base/string/raw/compare.c new file mode 100644 index 0000000..05e6c66 --- /dev/null +++ b/src/base/string/raw/compare.c @@ -0,0 +1,18 @@ +#include +#include + +int +str·compare(char *l, char *r) +{ + int cl, cr; + + for(;;){ + cl=*l++, cr=*r++; + if(cl != cr) + return cl-cr; + if(!cl) + return 0; + } + /* unreachable */ + return 0; +} diff --git a/src/base/string/raw/copy.c b/src/base/string/raw/copy.c new file mode 100644 index 0000000..10562bd --- /dev/null +++ b/src/base/string/raw/copy.c @@ -0,0 +1,9 @@ +char * +str·copy(char *dst, char *src) +{ + while(*src) + *dst++ = *src++; + + *dst = 0; + return dst; +} diff --git a/src/base/string/raw/eappend.c b/src/base/string/raw/eappend.c new file mode 100644 index 0000000..bf9086f --- /dev/null +++ b/src/base/string/raw/eappend.c @@ -0,0 +1,9 @@ +#include +#include + +char * +str·eappend(char *dst, char *end, char *src) +{ + str·ecopy(dst+str·len(dst), end, src); + return dst; +} diff --git a/src/base/string/raw/ecompare.c b/src/base/string/raw/ecompare.c new file mode 100644 index 0000000..f0e20e8 --- /dev/null +++ b/src/base/string/raw/ecompare.c @@ -0,0 +1,20 @@ +#include +#include + +int +str·ecompare(char *l, char *e, char *r) +{ + int cl, cr; + + if(l > e) /* l is nil */ + return *r ? -1 : 0; + + while(l != e){ + cl=*l++, cr=*r++; + if(cl != cr) + return cl-cr; + if(!cl) + return 0; + } + return *r ? -1 : 0; +} diff --git a/src/base/string/raw/ecopy.c b/src/base/string/raw/ecopy.c new file mode 100644 index 0000000..cd812e2 --- /dev/null +++ b/src/base/string/raw/ecopy.c @@ -0,0 +1,12 @@ +char * +str·ecopy(char *dst, char *end, char *src) +{ + if(dst > end) + return dst; + + while(*src && dst != end) + *dst++ = *src++; + + *dst = 0; + return dst; +} diff --git a/src/base/string/raw/efind.c b/src/base/string/raw/efind.c new file mode 100644 index 0000000..e097b42 --- /dev/null +++ b/src/base/string/raw/efind.c @@ -0,0 +1,48 @@ +#include +#include +#include + +char * +str·efind(char *h, char *e, char *n) +{ + char *s, *ih, *in; + intptr i, sum, sz; + + if(!n || !n[0]) + return h; + + if(!h || !h[0] || h > e) + return nil; + + /* two way string matching */ + + /* align first characters */ + if(!(s = str·findc(h, n[0]))) + return nil; + + ih = s+1; + in = n+1; + i = 1, sum = 0; + while(*ih && *in && ih != e){ + sum += *ih; + sum -= *in; + i &= (*ih++ == *in++); + } + + if(*in) /* needle is larger than haystack! */ + return nil; + else if(i) /* found match */ + return s; + + /* no hit: loop for remainder of haystack + * if prefix sum ever falls to zero, we have equal hashes + * compare! */ + sz = in - n - 1; + for(; *ih && ih != e; ih++){ + sum -= *s++; /* sub the last character, advance the location on haystack */ + sum += *ih; /* add the next character */ + if(sum == 0 && mem·compare(s, sz, n)==0) + return s; + } + return nil; +} diff --git a/src/base/string/raw/efindc.c b/src/base/string/raw/efindc.c new file mode 100644 index 0000000..c20ce5a --- /dev/null +++ b/src/base/string/raw/efindc.c @@ -0,0 +1,15 @@ +#include + +char * +str·efindc(char *s, char *e, int c) +{ + if(s > e) + return nil; + + while(*s && s != e){ + if(*s == c) + return s; + s++; + } + return nil; +} diff --git a/src/base/string/raw/find.c b/src/base/string/raw/find.c new file mode 100644 index 0000000..3faf040 --- /dev/null +++ b/src/base/string/raw/find.c @@ -0,0 +1,48 @@ +#include +#include +#include + +char * +str·find(char *h, char *n) +{ + char *s, *ih, *in; + intptr i, sum, len; + + if(!n || !n[0]) + return h; + + if(!h || !h[0]) + return nil; + + /* two way string matching */ + + /* align first characters */ + if(!(s = str·findc(h, n[0]))) + return nil; + + ih = s+1; + in = n+1; + i = 1, sum = 0; + while(*ih && *in){ + sum += *ih; + sum -= *in; + i &= (*ih++ == *in++); + } + + if(*in) /* needle is larger than haystack! */ + return nil; + else if(i) /* found match */ + return s; + + /* no hit: loop for remainder of haystack + * if prefix sum ever falls to zero, we have equal hashes + * compare! */ + len = in - n - 1; + for(; *ih; ih++){ + sum -= *s++; /* sub the last character, advance the location on haystack */ + sum += *ih; /* add the next character */ + if(sum == 0 && mem·compare(s, len, n)==0) + return s; + } + return nil; +} diff --git a/src/base/string/raw/findc.c b/src/base/string/raw/findc.c new file mode 100644 index 0000000..65099d8 --- /dev/null +++ b/src/base/string/raw/findc.c @@ -0,0 +1,12 @@ +#include + +char * +str·findc(char *s, int c) +{ + while(*s){ + if(*s == c) + return s; + s++; + } + return nil; +} diff --git a/src/base/string/raw/itoa.c b/src/base/string/raw/itoa.c new file mode 100644 index 0000000..38a6661 --- /dev/null +++ b/src/base/string/raw/itoa.c @@ -0,0 +1,21 @@ +static char * +kernel(char *s, int x) +{ + if(x/10) + s = kernel(s, x/10); + *s++ = x%10 + '0'; + return s; +} + +char * +str·itoa(char *s, int x) +{ + if(x<0){ + *s++ = '-'; + x=-x; + } + s = kernel(s, x); + *s = '0'; + + return s; +} diff --git a/src/base/string/raw/len.c b/src/base/string/raw/len.c new file mode 100644 index 0000000..8736e2e --- /dev/null +++ b/src/base/string/raw/len.c @@ -0,0 +1,10 @@ +#include + +intptr +str·len(char *s) +{ + int n = 0; + while(s[n]) + n++; + return n; +} diff --git a/src/base/string/raw/nappend.c b/src/base/string/raw/nappend.c new file mode 100644 index 0000000..dcd0e5e --- /dev/null +++ b/src/base/string/raw/nappend.c @@ -0,0 +1,9 @@ +#include +#include + +char * +str·nappend(char *dst, intptr len, char *src) +{ + str·ncopy(dst+str·len(dst), len, src); + return dst; +} diff --git a/src/base/string/raw/ncompare.c b/src/base/string/raw/ncompare.c new file mode 100644 index 0000000..34c6d6d --- /dev/null +++ b/src/base/string/raw/ncompare.c @@ -0,0 +1,17 @@ +#include +#include + +int +str·ncompare(char *l, intptr n, char *r) +{ + int cl, cr; + + while(n-- > 0){ + cl=*l++, cr=*r++; + if(cl != cr) + return cl-cr; + if(!cl) + return 0; + } + return *r ? -1 : 0; +} diff --git a/src/base/string/raw/ncopy.c b/src/base/string/raw/ncopy.c new file mode 100644 index 0000000..cf18a4b --- /dev/null +++ b/src/base/string/raw/ncopy.c @@ -0,0 +1,9 @@ +char * +str·ncopy(char *dst, int n, char *src) +{ + while(*src && n-- > 0) + *dst++ = *src++; + + *dst = 0; + return dst; +} diff --git a/src/base/string/raw/nfind.c b/src/base/string/raw/nfind.c new file mode 100644 index 0000000..181cc03 --- /dev/null +++ b/src/base/string/raw/nfind.c @@ -0,0 +1,51 @@ +#include +#include +#include + +char * +str·nfind(char *h, intptr len, char *n) +{ + char *s, *ih, *in; + intptr i, sum, sz; + + if(!n || !n[0]) + return h; + + if(!h || !h[0]) + return nil; + + /* two way string matching */ + + /* align first characters */ + if(!(s = str·findc(h, n[0]))) + return nil; + + len -= (s-h); + sz = len; + + ih = s+1; + in = n+1; + i = 1, sum = 0; + while(*ih && *in && len-- > 0){ + sum += *ih; + sum -= *in; + i &= (*ih++ == *in++); + } + + if(*in) /* needle is larger than haystack! */ + return nil; + else if(i) /* found match */ + return s; + + /* no hit: loop for remainder of haystack + * if prefix sum ever falls to zero, we have equal hashes + * compare! */ + sz = in - n - 1; + for(len=sz; *ih && len>0; ih++,len--){ + sum -= *s++; /* sub the last character, advance the location on haystack */ + sum += *ih; /* add the next character */ + if(sum == 0 && mem·compare(s, sz, n)==0) + return s; + } + return nil; +} diff --git a/src/base/string/raw/nfindc.c b/src/base/string/raw/nfindc.c new file mode 100644 index 0000000..832c39d --- /dev/null +++ b/src/base/string/raw/nfindc.c @@ -0,0 +1,12 @@ +#include + +char * +str·nfindc(char *s, intptr n, int c) +{ + while(*s && n-- > 0){ + if(*s == c) + return s; + s++; + } + return nil; +} diff --git a/src/base/string/raw/rules.mk b/src/base/string/raw/rules.mk new file mode 100644 index 0000000..b0c7d46 --- /dev/null +++ b/src/base/string/raw/rules.mk @@ -0,0 +1 @@ +SRCS_$(d)+=$(wildcard $(d)/string/raw/*.c) diff --git a/src/base/string/read.c b/src/base/string/read.c index df2028f..f753e24 100644 --- a/src/base/string/read.c +++ b/src/base/string/read.c @@ -1,11 +1,11 @@ #include "internal.h" int -str·read(string s, int size, int n, void *buf) +string·read(string s, int size, int n, void *buf) { int len; - len = MIN(n * size, str·len(s)); + len = MIN(n * size, string·len(s)); memcpy(buf, s, len); return len; diff --git a/src/base/string/replace.c b/src/base/string/replace.c index 127daed..979c385 100644 --- a/src/base/string/replace.c +++ b/src/base/string/replace.c @@ -4,13 +4,13 @@ // edits are done in place and modify the string. // NOTE: as of now strings from and to must be the same size. void -str·replace(string s, const byte* from, const byte* to) +string·replace(string s, byte* from, byte* to) { vlong fromL = strlen(from); vlong toL = strlen(to); if (toL != fromL) { panicf("different sized replacement string not supported"); } - vlong l = str·len(s); + vlong l = string·len(s); vlong i = l; vlong j = l; diff --git a/src/base/string/rules.mk b/src/base/string/rules.mk index 5fa6c5e..c2759f9 100644 --- a/src/base/string/rules.mk +++ b/src/base/string/rules.mk @@ -1,21 +1,3 @@ -SRCS_$(d)+=\ - $(d)/string/atoi.c\ - $(d)/string/itoa.c\ - $(d)/string/append.c\ - $(d)/string/appendf.c\ - $(d)/string/clear.c\ - $(d)/string/copyn.c\ - $(d)/string/equals.c\ - $(d)/string/find.c\ - $(d)/string/fit.c\ - $(d)/string/free.c\ - $(d)/string/grow.c\ - $(d)/string/join.c\ - $(d)/string/len.c\ - $(d)/string/lower.c\ - $(d)/string/make.c\ - $(d)/string/makef.c\ - $(d)/string/read.c\ - $(d)/string/replace.c\ - $(d)/string/split.c\ - $(d)/string/upper.c\ +include $(d)/string/raw/rules.mk + +SRCS_$(d)+=$(wildcard $(d)/string/*.c) diff --git a/src/base/string/split.c b/src/base/string/split.c index 2aa68b4..9d5d440 100644 --- a/src/base/string/split.c +++ b/src/base/string/split.c @@ -4,36 +4,36 @@ // returns a stretchy buffer of strings that result from the partition. // it is the caller's responsibility to clean the memory. string* -str·split(string s, const byte* tok) +string·split(string s, byte* tok) { string* fields = nil; vlong start = 0; - vlong sL = str·len(s); - vlong tokL = strlen(tok); - if (sL == 0 || tokL == 0) return nil; + vlong sL = string·len(s); + vlong tokL = str·len(tok); + if(sL == 0 || tokL == 0) + return nil; buffit(fields, 5); - for (vlong i = 0; i < sL - tokL; i++) { - if ((tokL == 1 && s[i] == tokL) || !memcmp(s + i, tok, tokL)) { - bufpush(fields, str·makelen(s + start, i - start)); - if (fields[buflen(fields) - 1] == nil) goto cleanup; + for(vlong i = 0; i < sL - tokL; i++){ + if((tokL == 1 && s[i] == tokL) || !memcmp(s + i, tok, tokL)){ + bufpush(fields, string·makelen(s + start, i - start)); + if(fields[buflen(fields) - 1] == nil) goto cleanup; start = i + tokL; i += tokL - 1; } } - bufpush(fields, str·makelen(s + start, sL - start)); + bufpush(fields, string·makelen(s + start, sL - start)); return fields; cleanup: - for (vlong i = 0; i < buflen(fields); i++) { - str·free(fields[i]); - } + for(vlong i = 0; i < buflen(fields); i++) + string·free(fields[i]); + buffree(fields); return nil; } - diff --git a/src/base/string/upper.c b/src/base/string/upper.c index ab692c1..2110974 100644 --- a/src/base/string/upper.c +++ b/src/base/string/upper.c @@ -2,11 +2,11 @@ // Upper will force all runes in the string to be uppercase. void -str·upper(string s) +string·upper(string s) { byte *b, *e; b = s; - e = b + str·len(s); + e = b + string·len(s); while (b++ != e) *b = toupper(*b); } diff --git a/src/libbio/newick.c b/src/libbio/newick.c index bc768fd..a855cea 100644 --- a/src/libbio/newick.c +++ b/src/libbio/newick.c @@ -229,14 +229,14 @@ parse(struct Parser *p) errorf("incorrect format: comment found in disallowed region"); goto ERROR; } - node->comment = str·make(""); + node->comment = string·make(""); while (tok.kind != tok·rbrak) { tok = lex_nospace(p->file, p->io); if (tok.kind == tok·eof || tok.kind == tok·nil) { errorf("incorrect format: unmatched comment bracket '['"); goto ERROR; } - str·append(&node->comment, tokstr(tok)); + string·append(&node->comment, tokstr(tok)); } break; @@ -268,7 +268,7 @@ parse(struct Parser *p) errorf("parse error: attempting to set name of nil node"); goto ERROR; } - node->name = str·make(tok.lit.s); + node->name = string·make(tok.lit.s); } else { if (p->tok.kind != tok·lparen && p->tok.kind != tok·comma) { errorf("format error: misplaced identifier for leaf found"); @@ -283,7 +283,7 @@ parse(struct Parser *p) node = p->mem.alloc(p->heap, 1, sizeof(*node)); memset(node, 0, sizeof(*node)); - node->name = str·make(tok.lit.s); + node->name = string·make(tok.lit.s); phylo·addchild(p->root, node); } -- cgit v1.2.1