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/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 + 19 files changed, 339 insertions(+) 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/base/string/raw') 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) -- cgit v1.2.1