aboutsummaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/error/errorf.c4
-rw-r--r--src/base/error/exits.c4
-rw-r--r--src/base/error/panicf.c8
-rw-r--r--src/base/error/verrorf.c6
-rw-r--r--src/base/error/vpanicf.c8
-rw-r--r--src/base/fmt/buffer.c2
-rw-r--r--src/base/fmt/do.c10
-rw-r--r--src/base/fmt/float.c14
-rw-r--r--src/base/fmt/open.c2
-rw-r--r--src/base/fmt/test.c2
-rw-r--r--src/base/fs/basename.c2
-rw-r--r--src/base/fs/close.c8
-rw-r--r--src/base/fs/dirname.c2
-rw-r--r--src/base/fs/exists.c4
-rw-r--r--src/base/fs/open.c14
-rw-r--r--src/base/fs/read.c25
-rw-r--r--src/base/fs/walk.c5
-rw-r--r--src/base/fs/walker.c7
-rw-r--r--src/base/gz/read.c2
-rw-r--r--src/base/io/flush.c2
-rw-r--r--src/base/io/getc.c2
-rw-r--r--src/base/io/read.c2
-rw-r--r--src/base/io/readuntil.c2
-rw-r--r--src/base/io/write.c2
-rw-r--r--src/base/mem/arena.c6
-rw-r--r--src/base/mem/interface.c4
-rw-r--r--src/base/mem/pool.c193
-rw-r--r--src/base/mem/pool.h66
-rw-r--r--src/base/mem/rfind.c14
-rw-r--r--src/base/rng/base.c2
-rw-r--r--src/base/sort/string.c2
-rw-r--r--src/base/string/append.c4
-rw-r--r--src/base/string/equals.c2
-rw-r--r--src/base/string/grow.c2
-rw-r--r--src/base/string/lower.c2
-rw-r--r--src/base/string/make.c10
-rw-r--r--src/base/string/raw/erfindc.c17
-rw-r--r--src/base/string/raw/nrfindc.c15
-rw-r--r--src/base/string/raw/rfindc.c15
-rw-r--r--src/base/string/read.c2
-rw-r--r--src/base/string/replace.c4
-rw-r--r--src/base/string/split.c2
-rw-r--r--src/base/string/upper.c4
-rw-r--r--src/base/test.c16
-rw-r--r--src/base/utf/find.c2
-rw-r--r--src/base/utf/findlast.c2
-rw-r--r--src/base/utf/rules.mk2
-rw-r--r--src/base/utf/vendor/common.c30
-rw-r--r--src/base/utf/vendor/common.h6
-rw-r--r--src/base/utf/vendor/mkrunetype.c18
-rw-r--r--src/base/utf/vendor/mkrunewidth.c21
51 files changed, 493 insertions, 109 deletions
diff --git a/src/base/error/errorf.c b/src/base/error/errorf.c
index 193dd9d..ed4c660 100644
--- a/src/base/error/errorf.c
+++ b/src/base/error/errorf.c
@@ -6,8 +6,8 @@ errorf(byte* fmt, ...)
va_list args;
va_start(args, fmt);
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, args);
+ fmt·fprint(sys·Stderr, "error: ");
+ fmt·fprint(sys·Stderr, fmt, args);
va_end(args);
}
diff --git a/src/base/error/exits.c b/src/base/error/exits.c
index 7fd83c5..3be9625 100644
--- a/src/base/error/exits.c
+++ b/src/base/error/exits.c
@@ -4,8 +4,8 @@ void
exits(char *s)
{
if(s == nil || *s == 0)
- exit(0);
+ rt·exit(0);
//fputs(s, stderr);
- exit(1);
+ rt·exit(1);
}
diff --git a/src/base/error/panicf.c b/src/base/error/panicf.c
index d698576..f1ed126 100644
--- a/src/base/error/panicf.c
+++ b/src/base/error/panicf.c
@@ -6,11 +6,11 @@ panicf(byte* fmt, ...)
va_list args;
va_start(args, fmt);
- printf("panic: ");
- vprintf(fmt, args);
- printf("\n");
+ fmt·fprint(sys·Stderr,"panic: ");
+ fmt·vfprint(sys·Stderr,fmt, args);
+ fmt·fprint(sys·Stderr,"\n");
va_end(args);
- exit(1);
+ rt·exit(1);
}
diff --git a/src/base/error/verrorf.c b/src/base/error/verrorf.c
index 15af064..7acd690 100644
--- a/src/base/error/verrorf.c
+++ b/src/base/error/verrorf.c
@@ -3,7 +3,7 @@
void
verrorf(byte* fmt, va_list args)
{
- printf("error: ");
- vprintf(fmt, args);
- printf("\n");
+ fmt·fprint(sys·Stderr,"error: ");
+ fmt·vfprint(sys·Stderr,fmt, args);
+ fmt·fprint(sys·Stderr,"\n");
}
diff --git a/src/base/error/vpanicf.c b/src/base/error/vpanicf.c
index bea97ac..84df334 100644
--- a/src/base/error/vpanicf.c
+++ b/src/base/error/vpanicf.c
@@ -3,9 +3,9 @@
void
vpanicf(byte* fmt, va_list args)
{
- printf("panic: ");
- vprintf(fmt, args);
- printf("\n");
+ fmt·fprint(sys·Stderr, "panic: ");
+ fmt·vfprint(sys·Stderr, fmt, args);
+ fmt·fprint(sys·Stderr, "\n");
- exit(1);
+ rt·exit(1);
}
diff --git a/src/base/fmt/buffer.c b/src/base/fmt/buffer.c
index e039577..3018ccc 100644
--- a/src/base/fmt/buffer.c
+++ b/src/base/fmt/buffer.c
@@ -33,7 +33,7 @@ fmt·make(mem·Allocator mem, void *heap, fmt·State *io)
{
int n;
- memset(io, 0, sizeof(*io));
+ mem·set(io, sizeof(*io), 0);
n = 32;
io->buffer.beg = io->buffer.cur = mem.alloc(heap, n, 1);
diff --git a/src/base/fmt/do.c b/src/base/fmt/do.c
index a990ab0..581ab1b 100644
--- a/src/base/fmt/do.c
+++ b/src/base/fmt/do.c
@@ -291,7 +291,7 @@ copystring(fmt·State *io, char *s)
return copy(io, s, i, j);
}
- return copy(io, s, strlen(s), utf8·len(s));
+ return copy(io, s, str·len(s), utf8·len(s));
}
static int
@@ -495,7 +495,7 @@ fmtint(fmt·State *io)
digits = 0;
excess = 0;
runes = utf8·len(thousands);
- bytes = strlen(thousands);
+ bytes = str·len(thousands);
#define PARSE(VALUE) \
while((VALUE)){ \
@@ -509,7 +509,7 @@ fmtint(fmt·State *io)
n += runes; \
excess += bytes - runes; \
p -= bytes; \
- memmove(p+1, thousands, bytes); \
+ mem·move(p+1, bytes, thousands); \
} \
*p-- = conv[i]; \
n++; \
@@ -537,7 +537,7 @@ fmtint(fmt·State *io)
n += runes;
excess += bytes - runes;
p -= bytes;
- memmove(p+1, thousands, bytes);
+ mem·move(p+1, bytes, thousands);
}
*p-- = '0';
}
@@ -565,7 +565,7 @@ fmtint(fmt·State *io)
n += runes;
excess += bytes - runes;
p -= bytes;
- memmove(p+1, thousands, bytes);
+ mem·move(p+1, bytes, thousands);
}
*p-- = '0';
}
diff --git a/src/base/fmt/float.c b/src/base/fmt/float.c
index 8a42dfc..ba2637e 100644
--- a/src/base/fmt/float.c
+++ b/src/base/fmt/float.c
@@ -154,7 +154,7 @@ sub1(char *a, int n)
* can't get here. the number a is always normalized
* so that it has a nonzero first digit.
*/
- abort();
+ rt·exit(1);
}
// -----------------------------------------------------------------------
@@ -322,7 +322,7 @@ divascii(char *a, int *na, int *dp, int *bp)
d = (int)(arrlen(tab1))-1;
t = tab1 + d;
b = t->bp;
- if(memcmp(a, t->cmp, t->siz) > 0)
+ if(mem·compare(a, t->siz, t->cmp) > 0)
d--;
*dp -= d;
*bp += b;
@@ -382,7 +382,7 @@ mulascii(char *a, int *na, int *dp, int *bp)
d = (int)(arrlen(tab2))-1;
t = tab2 + d;
b = t->bp;
- if(memcmp(a, t->cmp, t->siz) < 0)
+ if(mem·compare(a, t->siz, t->cmp) < 0)
d--;
p = a + *na;
*bp -= b;
@@ -398,8 +398,8 @@ cmp(char *a, char *b)
while((c1 = *b++) != '\0') {
c2 = *a++;
- if(isupper(c2))
- c2 = tolower(c2);
+ if(utf8·isupper(c2))
+ c2 = utf8·tolower(c2);
if(c1 != c2)
return 1;
}
@@ -824,7 +824,7 @@ fmtfloat(fmt·State *io)
end = special[0+ucase];
special:
io->flag = f & (fmt·Width|fmt·Left);
- return copy(io, end, strlen(end), strlen(end));
+ return copy(io, end, str·len(end), str·len(end));
}
if(isInf(val, 1)) {
end = special[2+ucase];
@@ -910,7 +910,7 @@ fmtfloat(fmt·State *io)
z2 = 0;
}
fmtexp(suf, e, ucase);
- nsuf = strlen(suf);
+ nsuf = str·len(suf);
break;
casef:
diff --git a/src/base/fmt/open.c b/src/base/fmt/open.c
index 2020a2a..58c5ccc 100644
--- a/src/base/fmt/open.c
+++ b/src/base/fmt/open.c
@@ -8,7 +8,7 @@ flush(fmt·State *io)
fd = (uintptr)io->file;
n = io->buffer.cur - io->buffer.beg;
- if(n && sys·write(fd, n, io->buffer.beg, &n))
+ if(n && sys·write(fd, io->buffer.beg, n, &n))
return -1;
io->buffer.cur = io->buffer.beg;
diff --git a/src/base/fmt/test.c b/src/base/fmt/test.c
index 3f7f070..0d46980 100644
--- a/src/base/fmt/test.c
+++ b/src/base/fmt/test.c
@@ -19,7 +19,7 @@ static void
saygoodbye(void *arg)
{
intptr n;
- sys·write(1, 9, "goodbye\n", &n);
+ sys·write(1, "goodbye\n", 9, &n);
}
int
diff --git a/src/base/fs/basename.c b/src/base/fs/basename.c
index 2f097da..d956ff1 100644
--- a/src/base/fs/basename.c
+++ b/src/base/fs/basename.c
@@ -5,6 +5,6 @@ fs·basename(char *path)
{
char *sep;
- sep = strrchr(path, '/');
+ sep = str·rfindc(path, '/');
return (sep == nil) ? path : sep+1;
}
diff --git a/src/base/fs/close.c b/src/base/fs/close.c
new file mode 100644
index 0000000..da753dd
--- /dev/null
+++ b/src/base/fs/close.c
@@ -0,0 +1,8 @@
+#include <u.h>
+#include <base.h>
+
+int
+fs·close(fs·Directory *dir)
+{
+ return sys·close(dir->fd);
+}
diff --git a/src/base/fs/dirname.c b/src/base/fs/dirname.c
index f312f63..18348e6 100644
--- a/src/base/fs/dirname.c
+++ b/src/base/fs/dirname.c
@@ -5,7 +5,7 @@ fs·dirname(char *path)
{
char *sep;
- if((sep = strrchr(path, '/')))
+ if((sep = str·rfindc(path, '/')))
*sep = 0;
return path;
diff --git a/src/base/fs/exists.c b/src/base/fs/exists.c
index 1841a41..f7077ea 100644
--- a/src/base/fs/exists.c
+++ b/src/base/fs/exists.c
@@ -1,7 +1,7 @@
#include "internal.h"
int
-fs·exists(byte *path, int flag)
+fs·exists(byte *path)
{
- return access(path, flag) == 0;
+ return !sys·access(path, sys·FileExists);
}
diff --git a/src/base/fs/open.c b/src/base/fs/open.c
new file mode 100644
index 0000000..698ac71
--- /dev/null
+++ b/src/base/fs/open.c
@@ -0,0 +1,14 @@
+#include <u.h>
+#include <base.h>
+
+int
+fs·open(char *path, fs·Directory *dir)
+{
+ int fd, err;
+ if((err=sys·open(path, sys·ORead|sys·ODirectory|sys·OCloseExec, 0, &fd)))
+ return err;
+
+ mem·set(dir, 0, sizeof(*dir));
+ dir->fd = fd;
+ return 0;
+}
diff --git a/src/base/fs/read.c b/src/base/fs/read.c
new file mode 100644
index 0000000..7e60823
--- /dev/null
+++ b/src/base/fs/read.c
@@ -0,0 +1,25 @@
+#include <u.h>
+#include <base.h>
+#include <sys.h>
+
+int
+fs·read(fs·Directory *dir, fs·DirEntry **ent)
+{
+ int err;
+ uintptr n;
+
+ fs·DirEntry *de;
+ if(dir->pos >= dir->end){
+ if((err=sys·direntry(dir->fd, arrlen(dir->buf), dir->buf, &n)))
+ return err;
+ dir->pos = 0;
+ dir->end = n;
+ }
+
+ de = (fs·DirEntry *)(dir->buf + dir->pos);
+ dir->pos += de->len;
+ dir->off = de->off;
+
+ *ent = de;
+ return 0;
+}
diff --git a/src/base/fs/walk.c b/src/base/fs/walk.c
index 612aca8..786a32a 100644
--- a/src/base/fs/walk.c
+++ b/src/base/fs/walk.c
@@ -37,7 +37,7 @@ fs·walk(fs·Walker *fs)
flags = 0;
if(fs->flags & fs·nolinks)
- flags |= AT_SYMLINK_NOFOLLOW;
+ flags |= sys·AtNoFollowLink;
/* get info for base relative to current fd */
if(fstatat(fs->fd, fs->base, &cwd, flags) < 0){
@@ -71,8 +71,7 @@ fs·walk(fs·Walker *fs)
/* open directory */
if(!fs->max || fs->lev + 1 < fs->max) {
- fd = openat(fs->fd, fs->base, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
- if(fd < 0)
+ if(sys·openat(fs->fd, fs->base, sys·ORead|sys·OCloseExec|sys·ODirectory, 0, &fd))
errorf("open %s:", fs->path);
if (!(dir=fdopendir(fd))) {
diff --git a/src/base/fs/walker.c b/src/base/fs/walker.c
index 0a0f61e..0a88f8e 100644
--- a/src/base/fs/walker.c
+++ b/src/base/fs/walker.c
@@ -12,15 +12,14 @@ fs·init(fs·Walker *fs, char *path)
fs->base = fs->end = fs->path;
if(!path || !path[0]){
- path = getcwd(fs->path, arrlen(fs->path));
- if (!path)
+ if(sys·cwd(fs->path, arrlen(fs->path)))
return 1;
- fs->end += strlen(path);
+ fs->end += str·len(path);
}else
fs->end = str·ncopy(fs->base, arrlen(fs->path), path);
if(fs->path[0] != '/')
- fs->fd = AT_FDCWD;
+ fs->fd = sys·FdCwd;
if(!fs->hist && !(fs->flags & fs·nolinks))
fs->hist = calloc(1, sizeof(*fs->hist));
diff --git a/src/base/gz/read.c b/src/base/gz/read.c
index 112fe4d..0a91f2f 100644
--- a/src/base/gz/read.c
+++ b/src/base/gz/read.c
@@ -12,5 +12,5 @@ gz·readln(gz·Stream *s, int n, byte *buf)
byte* b;
b = gzgets(s, buf, n);
- return strlen(b);
+ return str·len(b);
}
diff --git a/src/base/io/flush.c b/src/base/io/flush.c
index ff970b4..7aa0933 100644
--- a/src/base/io/flush.c
+++ b/src/base/io/flush.c
@@ -10,7 +10,7 @@ io·flush(io·Header *io)
if((ni = io->cap + io->olen))
return 0;
- sys·write(io->fd, ni, io->b, &no);
+ sys·write(io->fd, io->b, ni, &no);
if(no!=ni){
io->pos += ni;
diff --git a/src/base/io/getc.c b/src/base/io/getc.c
index 0f0d62e..758f98d 100644
--- a/src/base/io/getc.c
+++ b/src/base/io/getc.c
@@ -24,7 +24,7 @@ loop:
* pre-catenated from the previous read to allow for ungets
*/
mem·move(io->b-io·BufUngets, io·BufUngets, io->e-io·BufUngets);
- if(sys·read(io->fd, io->cap, io->b, &nr)){
+ if(sys·read(io->fd, io->b, io->cap, &nr)){
io->state = io·BufNil;
return io·BufEof;
}
diff --git a/src/base/io/read.c b/src/base/io/read.c
index a972c3e..b13fde7 100644
--- a/src/base/io/read.c
+++ b/src/base/io/read.c
@@ -20,7 +20,7 @@ io·read(io·Header *io, intptr len, void *buf)
break;
/* get more bytes */
- if(sys·read(io->fd, io->cap, io->b, &nr)){
+ if(sys·read(io->fd, io->b, io->cap, &nr)){
io->state = io·BufNil;
break;
}
diff --git a/src/base/io/readuntil.c b/src/base/io/readuntil.c
index 3fe3925..58e3d1e 100644
--- a/src/base/io/readuntil.c
+++ b/src/base/io/readuntil.c
@@ -33,7 +33,7 @@ io·readuntil(io·Header *io, int delim)
/* 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){
+ if(sys·read(io->fd, b, io->cap-i, &j) || j == 0){
mem·move(io->e-i, i, io->b);
io->nread = +i;
io->ilen = -i;
diff --git a/src/base/io/write.c b/src/base/io/write.c
index 554aa88..68f70c5 100644
--- a/src/base/io/write.c
+++ b/src/base/io/write.c
@@ -17,7 +17,7 @@ io·write(io·Header *io, intptr len, void *buf)
if(n == 0){
if(io->state != io·BufWtr)
return io·BufEof;
- switch(sys·write(io->fd, io->cap, io->b, &nw)){
+ switch(sys·write(io->fd, io->b, io->cap, &nw)){
case 0:
if(nw != io->cap) goto error;
io->pos += nw;
diff --git a/src/base/mem/arena.c b/src/base/mem/arena.c
index 7fe036a..cb1af74 100644
--- a/src/base/mem/arena.c
+++ b/src/base/mem/arena.c
@@ -26,13 +26,13 @@ struct mem·Arena
};
static void*
-·arenaalloc(void *heap, uint n, ulong size)
+·arenaalloc(void *heap, long n, uintptr size)
{
return mem·arenaalloc(heap, n, size);
}
static void*
-·arenarealloc(void *heap, void *old, uint n, ulong size)
+·arenarealloc(void *heap, void *old, long n, uintptr size)
{
/* does not free */
return mem·arenaalloc(heap, n, size);
@@ -99,7 +99,7 @@ mem·freearena(mem·Arena *a)
}
void*
-mem·arenaalloc(mem·Arena *a, uint n, ulong size)
+mem·arenaalloc(mem·Arena *a, long n, uintptr size)
{
if(!n) {
return nil;
diff --git a/src/base/mem/interface.c b/src/base/mem/interface.c
index 99cb774..aa76c85 100644
--- a/src/base/mem/interface.c
+++ b/src/base/mem/interface.c
@@ -11,12 +11,12 @@ static void *
}
static void *
-·calloc(void *_, uint n, ulong size) {
+·calloc(void *_, long n, ulong size) {
return calloc(n, size);
}
static void *
-·realloc(void *_, void *ptr, uint n, ulong size) {
+·realloc(void *_, void *ptr, long n, ulong size) {
return realloc(ptr, n*size);
}
diff --git a/src/base/mem/pool.c b/src/base/mem/pool.c
new file mode 100644
index 0000000..bf6f2b5
--- /dev/null
+++ b/src/base/mem/pool.c
@@ -0,0 +1,193 @@
+#include <u.h>
+#include <base.h>
+
+#include "pool.h"
+
+// -----------------------------------------------------------------------
+// globals/macros
+
+#define NOMAGIC 0xDEADFA11u
+#define DEADMAGIC 0xDEADDEADu
+#define TAILMAGIC0 0xBEu
+#define TAILMAGIC1 0xEFu
+#define FREEMAGIC 0xBA5EBA11u
+#define USEDMAGIC 0x0A110C09u
+#define UNUSEDMAGIC (0xCAB00D1Eu+1)
+#define COREMAGIC (0xC0A1E5CEu+1)
+#define CORETAILMAGIC (0xEC5E1A0Cu+1)
+#define ALIGNMAGIC 0xA1F1D1C1u
+
+#define POISON ((void*)0xCAFEBABEu)
+
+// -----------------------------------------------------------------------
+// hunk maintenance
+
+#define HUNKTAIL(h) ((Tail*)((uchar*)(h)+(h)->size-sizeof(Tail)))
+
+static uintptr
+gethunksize(mem·Pool *pool, uintptr size)
+{
+ size += sizeof(Head) + sizeof(Tail);
+ if(size < pool->minhunk)
+ size = pool->minhunk;
+ size = (size+pool->quantum) & ~(pool->quantum-1); // aligns to quantum
+ return size;
+}
+
+static Head *
+sethunksize(Head *h, uintptr size)
+{
+ Tail *t;
+
+ assert(h->magic != FREEMAGIC);
+
+ h->size = size;
+
+ t = HUNKTAIL(h);
+ t->size = size;
+ t->magic0 = TAILMAGIC0;
+ t->magic1 = TAILMAGIC1;
+
+ return h;
+}
+
+static void
+checkhunk(mem·Pool *p, Head *h)
+{
+ switch(h->magic){
+ default:
+ abort();
+ case FREEMAGIC:
+ case UNUSEDMAGIC:
+ case DEADMAGIC:
+ case COREMAGIC:
+ case CORETAILMAGIC:
+ case USEDMAGIC:
+ ;
+ }
+}
+
+// -----------------------------------------------------------------------
+// core maintenance
+
+#define COREHEAD(c) ((Head*)((uchar*)(c)+(c)->len -sizeof(Head)))
+
+static uintptr
+getcoresize(mem·Pool *pool, uintptr size)
+{
+ size += sizeof(Core) + sizeof(Tail);
+ if(size < pool->mincore)
+ size = pool->mincore;
+ size = (size+pool->quantum) & ~(pool->quantum-1);
+ return size;
+}
+
+static Core *
+setcoresize(Core *c, uintptr size)
+{
+ Head *h;
+
+ c->len = size;
+
+ h = COREHEAD(c);
+ h->size = 0;
+ h->magic = CORETAILMAGIC;
+
+ return c;
+}
+
+static void
+newcore(mem·Pool *pool, uintptr size)
+{
+ Core *c;
+
+ // XXX: check for size overflow
+
+ if(!(c = pool->mem.alloc(pool->heap, 1, size)))
+ return;
+
+ pool->cursize += size;
+
+ /* core header */
+ c->magic = COREMAGIC;
+ sethunksize((Head*)c, sizeof(Core));
+ setcoresize(c, size);
+ checkhunk(pool, (Head*)c);
+}
+
+// -----------------------------------------------------------------------
+// free list maintenance
+
+static Free *
+findgreater(Free *root, uintptr size)
+{
+ Free *last;
+
+ last = nil;
+ for(;;){
+ if(!root)
+ return last;
+ if(size == root->size)
+ return root;
+ if(size < root->size){
+ last = root;
+ root = root->left;
+ }else
+ root = root->right;
+ }
+}
+
+// -----------------------------------------------------------------------
+// exported functions
+
+/* constructors / destructors */
+mem·Pool*
+mem·makepool(mem·Allocator mem, void *heap, char *name, int flags, intptr maxsize, intptr mincore)
+{
+ mem·Pool *pool = mem.alloc(heap, 1, sizeof(*pool));
+ mem·set(pool, sizeof(*pool), 0);
+
+ pool->mem = mem;
+ pool->heap = heap;
+ pool->name = name;
+ pool->flags = flags;
+ pool->mincore = mincore;
+ pool->maxsize = maxsize;
+
+ return pool;
+}
+
+void
+mem·freepool(mem·Pool *pool)
+{
+ void *heap = pool->heap;
+ mem·Allocator mem = pool->mem;
+
+ mem.free(heap, pool);
+}
+
+/* base functions */
+
+void *
+mem·poolalloc(mem·Pool *pool, long n, uintptr eltsize)
+{
+ Free *node;
+ uintptr size, bksz;
+
+ if((size = n*eltsize) >= 0x80000000UL){
+ errorf("allocation overflow");
+ return nil;
+ }
+
+ bksz = gethunksize(pool, size);
+ node = findgreater(pool->free, bksz);
+ if(!node){
+ newcore(pool, getcoresize(pool, bksz));
+ if(!(node = findgreater(pool->free, bksz)))
+ return nil;
+ }
+
+
+
+ return nil;
+}
diff --git a/src/base/mem/pool.h b/src/base/mem/pool.h
new file mode 100644
index 0000000..d5e9952
--- /dev/null
+++ b/src/base/mem/pool.h
@@ -0,0 +1,66 @@
+#pragma once
+
+typedef struct Head Head;
+typedef struct Tail Tail;
+typedef struct Free Free;
+typedef struct Used Used;
+typedef struct Core Core;
+
+struct Head
+{
+ ulong magic;
+ ulong size;
+};
+
+struct Tail
+{
+ ulong magic0;
+ uchar datasize[2];
+ ulong magic1;
+ ulong size;
+};
+
+struct Free
+{
+ Head;
+ Free *left, *right;
+ Free *next, *prev;
+};
+
+struct Used
+{
+ Head;
+};
+
+struct Core
+{
+ Head;
+ Core *up, *down;
+ ulong len, pad;
+};
+
+struct mem·Pool
+{
+ char *name;
+ ulong maxsize;
+
+ void *heap;
+ mem·Allocator mem;
+
+ ulong cursize;
+ ulong curfree;
+ ulong curused;
+
+ ulong mincore; /* smallest size of new core */
+ ulong quantum; /* allocated hunks should be multiple of */
+ ulong minhunk; /* smallest newly allocated hunk */
+
+ Free *free;
+ Core *core;
+
+ int flags;
+ int nfree;
+ int lastcompact;
+
+ void* private;
+};
diff --git a/src/base/mem/rfind.c b/src/base/mem/rfind.c
new file mode 100644
index 0000000..ed45086
--- /dev/null
+++ b/src/base/mem/rfind.c
@@ -0,0 +1,14 @@
+#include "internal.h"
+
+void *
+mem·rfindc(void *addr, uintptr len, int c)
+{
+ char *s = addr;
+ c = (uchar)c;
+
+ while(len--){
+ if(s[len]==c)
+ return(s+len);
+ }
+ return nil;
+}
diff --git a/src/base/rng/base.c b/src/base/rng/base.c
index 9ec496e..3f6fd77 100644
--- a/src/base/rng/base.c
+++ b/src/base/rng/base.c
@@ -1,5 +1,7 @@
#include "internal.h"
+Rng rng·RNG = { 0 };
+
static uint64
splitmix64(struct Mix *state)
{
diff --git a/src/base/sort/string.c b/src/base/sort/string.c
index b511efa..e8fae66 100644
--- a/src/base/sort/string.c
+++ b/src/base/sort/string.c
@@ -4,7 +4,7 @@ void
sort·string(uintptr sz, byte* arr[])
{
byte *tmp;
-#define LESS(i, j) (strcmp(arr[i], arr[j]) < 0)
+#define LESS(i, j) (str·compare(arr[i], arr[j]) < 0)
#define SWAP(i, j) (tmp = arr[i], arr[i] = arr[j], arr[j] = tmp)
QSORT(sz, LESS, SWAP);
#undef SWAP
diff --git a/src/base/string/append.c b/src/base/string/append.c
index 60e1b48..7522f81 100644
--- a/src/base/string/append.c
+++ b/src/base/string/append.c
@@ -18,7 +18,7 @@ string·appendlen(string *s, vlong n, byte* b)
Hdr* h = (Hdr*)(*s - sizeof(Hdr));
- memcpy(*s + string·len(*s), b, n);
+ mem·copy(*s + string·len(*s), n, b);
h->len += n;
(*s)[h->len] = '\0';
@@ -30,7 +30,7 @@ string·appendlen(string *s, vlong n, byte* b)
int
string·append(string *s, byte* b)
{
- return string·appendlen(s, strlen(b), b);
+ return string·appendlen(s, str·len(b), b);
}
// appendbyte will append the given byte to our string.
diff --git a/src/base/string/equals.c b/src/base/string/equals.c
index 3637d67..ba7fd3b 100644
--- a/src/base/string/equals.c
+++ b/src/base/string/equals.c
@@ -10,5 +10,5 @@ string·equals(string s, string t)
if(sL != tL)
return false;
- return memcmp(s, t, sL) == 0;
+ return mem·compare(s, sL, t) == 0;
}
diff --git a/src/base/string/grow.c b/src/base/string/grow.c
index 6abe4cc..dd6b008 100644
--- a/src/base/string/grow.c
+++ b/src/base/string/grow.c
@@ -25,7 +25,7 @@ string·grow(string *s, vlong delta)
newh = (Hdr*)realloc(h, sizeof(*h) + newCap + 1);
if (newh == nil) return;
- memset(newh->buf + len, '\0', newCap - len);
+ mem·set(newh->buf + len, newCap - len, '\0');
newh->cap = newCap;
newh->len = len;
diff --git a/src/base/string/lower.c b/src/base/string/lower.c
index 00556d6..c094a5a 100644
--- a/src/base/string/lower.c
+++ b/src/base/string/lower.c
@@ -8,5 +8,5 @@ string·lower(string s)
b = s;
e = b + string·len(s);
while (b++ != e)
- *b = tolower(*b);
+ *b = utf8·tolower(*b);
}
diff --git a/src/base/string/make.c b/src/base/string/make.c
index d1e594a..50b8b98 100644
--- a/src/base/string/make.c
+++ b/src/base/string/make.c
@@ -9,7 +9,7 @@ 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) mem·set(h, sizeof(*h), 0);
if(h == nil) return nil; // Allocation failed.
@@ -19,8 +19,8 @@ string·makecap(byte *s, vlong len, vlong cap)
if(cap < h->len) goto cleanup;
if(s != nil && cap > 0){
- memcpy(h->buf, s, h->len);
- memset(h->buf + h->len, '\0', h->cap - h->len + 1);
+ mem·copy(h->buf, h->len, s);
+ mem·set(h->buf + h->len, h->cap - h->len + 1, '\0');
}
return h->buf;
@@ -36,7 +36,7 @@ cleanup:
string
string·makelen(byte *s, vlong len)
{
- vlong sl = (!s) ? 0 : strlen(s);
+ vlong sl = (!s) ? 0 : str·len(s);
if(sl < len) panicf("attempted to take a bigger substring than string length");
vlong cap = (len == 0) ? 1 : len;
@@ -48,6 +48,6 @@ string·makelen(byte *s, vlong len)
string
string·make(byte *s)
{
- vlong len = (!s) ? 0 : strlen(s);
+ vlong len = (!s) ? 0 : str·len(s);
return string·makelen(s, len);
}
diff --git a/src/base/string/raw/erfindc.c b/src/base/string/raw/erfindc.c
new file mode 100644
index 0000000..be04cde
--- /dev/null
+++ b/src/base/string/raw/erfindc.c
@@ -0,0 +1,17 @@
+#include <u.h>
+#include <base.h>
+
+char*
+str·erfindc(char *s, char *e, int c)
+{
+ int n;
+ if(e < s)
+ return nil;
+
+ n = e-s;
+ c = (uchar)c;
+ while(n--)
+ if(s[n]==c)
+ return s+n;
+ return nil;
+}
diff --git a/src/base/string/raw/nrfindc.c b/src/base/string/raw/nrfindc.c
new file mode 100644
index 0000000..66c0bee
--- /dev/null
+++ b/src/base/string/raw/nrfindc.c
@@ -0,0 +1,15 @@
+#include <u.h>
+#include <base.h>
+
+char*
+str·nrfindc(char *s, intptr n, int c)
+{
+ if(n < 0)
+ return nil;
+
+ c = (uchar)c;
+ while(n--)
+ if(s[n]==c)
+ return s+n;
+ return nil;
+}
diff --git a/src/base/string/raw/rfindc.c b/src/base/string/raw/rfindc.c
new file mode 100644
index 0000000..252be67
--- /dev/null
+++ b/src/base/string/raw/rfindc.c
@@ -0,0 +1,15 @@
+#include <u.h>
+#include <base.h>
+
+char*
+str·rfindc(char *s, int c)
+{
+ int n;
+
+ n = str·len(s);
+ c = (uchar)c;
+ while(n--)
+ if(s[n]==c)
+ return s+n;
+ return nil;
+}
diff --git a/src/base/string/read.c b/src/base/string/read.c
index f753e24..3bc4f74 100644
--- a/src/base/string/read.c
+++ b/src/base/string/read.c
@@ -6,7 +6,7 @@ string·read(string s, int size, int n, void *buf)
int len;
len = MIN(n * size, string·len(s));
- memcpy(buf, s, len);
+ mem·copy(buf, len, s);
return len;
}
diff --git a/src/base/string/replace.c b/src/base/string/replace.c
index 979c385..de3d397 100644
--- a/src/base/string/replace.c
+++ b/src/base/string/replace.c
@@ -6,8 +6,8 @@
void
string·replace(string s, byte* from, byte* to)
{
- vlong fromL = strlen(from);
- vlong toL = strlen(to);
+ vlong fromL = str·len(from);
+ vlong toL = str·len(to);
if (toL != fromL) { panicf("different sized replacement string not supported"); }
vlong l = string·len(s);
diff --git a/src/base/string/split.c b/src/base/string/split.c
index 6b0a9fd..56029e1 100644
--- a/src/base/string/split.c
+++ b/src/base/string/split.c
@@ -17,7 +17,7 @@ string·split(string s, byte* tok)
mem·buffit(fields, 5);
for(vlong i = 0; i < sL - tokL; i++){
- if((tokL == 1 && s[i] == tokL) || !memcmp(s + i, tok, tokL)){
+ if((tokL == 1 && s[i] == tokL) || !mem·compare(s + i, tokL, tok)){
mem·bufpush(fields, string·makelen(s + start, i - start));
if(fields[mem·buflen(fields) - 1] == nil) goto cleanup;
diff --git a/src/base/string/upper.c b/src/base/string/upper.c
index 2110974..1158a55 100644
--- a/src/base/string/upper.c
+++ b/src/base/string/upper.c
@@ -7,6 +7,6 @@ string·upper(string s)
byte *b, *e;
b = s;
e = b + string·len(s);
- while (b++ != e)
- *b = toupper(*b);
+ while (b++ != e)
+ *b = utf8·toupper(*b);
}
diff --git a/src/base/test.c b/src/base/test.c
index de53125..6baaf78 100644
--- a/src/base/test.c
+++ b/src/base/test.c
@@ -19,23 +19,21 @@ test·sort()
{
clock_t t;
int i, test[10000];
- for (i = 0; i < arrlen(test); i++) {
- test[i] = rand();
- }
+ for(i = 0; i < arrlen(test); i++)
+ test[i] = rng·randi(1000000);
t = clock();
sort·int(arrlen(test), test);
t = clock() - t;
- printf("inlined code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC);
+ fmt·print("inlined code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC);
- for (i = 0; i < arrlen(test); i++) {
- test[i] = rand();
- }
+ for (i = 0; i < arrlen(test); i++)
+ test[i] = rng·randi(1000000);
t = clock();
- qsort(test, arrlen(test), sizeof(int), (int (*)(const void *, const void *))less);
+ /* qsort(test, arrlen(test), sizeof(int), (int (*)(const void *, const void *))less); */
t = clock() - t;
- printf("std qsort code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC);
+ fmt·print("std qsort code took %f ms to execute\n", 1000.*t/CLOCKS_PER_SEC);
/*
for (i = 1; i < arrlen(test); i++) {
diff --git a/src/base/utf/find.c b/src/base/utf/find.c
index d75feb8..b9c0ed8 100644
--- a/src/base/utf/find.c
+++ b/src/base/utf/find.c
@@ -8,7 +8,7 @@ utf8·find(byte* s, rune c)
int n;
if(c < Tx)
- return strchr(s, c);
+ return str·findc(s, c);
for(;;){
c1 = *(ubyte*)s;
diff --git a/src/base/utf/findlast.c b/src/base/utf/findlast.c
index ab25ab2..ccdb461 100644
--- a/src/base/utf/findlast.c
+++ b/src/base/utf/findlast.c
@@ -8,7 +8,7 @@ utf8·findlast(byte* s, rune c)
byte *l;
if(c < Tx)
- return strrchr(s, c);
+ return str·rfindc(s, c);
l = nil;
for(;;){
diff --git a/src/base/utf/rules.mk b/src/base/utf/rules.mk
index 554ba6a..0ed2f8b 100644
--- a/src/base/utf/rules.mk
+++ b/src/base/utf/rules.mk
@@ -19,7 +19,6 @@ SRCS_$(d)+=\
NEED_OBJS=\
$(OBJ_DIR)/base/arg.o\
$(OBJ_DIR)/base/utf/decode.o\
- $(OBJ_DIR)/base/error/panicf.o\
$(OBJ_DIR)/base/io/readline.o\
$(OBJ_DIR)/base/io/readuntil.o\
$(OBJ_DIR)/base/io/open.o\
@@ -28,6 +27,7 @@ NEED_OBJS=\
$(OBJ_DIR)/base/io/init.o\
$(OBJ_DIR)/base/mem/move.o\
$(OBJ_DIR)/base/mem/findc.o\
+ $(OBJ_DIR)/base/io/readline.o\
$(d)/utf/vendor/common.o
$(d)/utf/vendor/common.o: $(d)/utf/vendor/common.c
diff --git a/src/base/utf/vendor/common.c b/src/base/utf/vendor/common.c
index c35d022..37ccca3 100644
--- a/src/base/utf/vendor/common.c
+++ b/src/base/utf/vendor/common.c
@@ -1,5 +1,19 @@
#include "common.h"
+int
+fatal(char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ fprintf(stderr,"panic: ");
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr,"\n");
+
+ va_end(args);
+ rt·exit(1);
+}
+
// -----------------------------------------------------------------------
// input functions
@@ -29,7 +43,7 @@ parse(io·Buffer *io, int nfield, char field[][FieldLen])
strcpy(field[n++], b);
if(n != nfield)
- panicf("expected %d number of fields, got %d: %s", nfield, n, b);
+ fatal("expected %d number of fields, got %d: %s", nfield, n, b);
return ParseOK;
}
@@ -47,7 +61,7 @@ codepoint(char *s)
else if(b >= 'A' && b <= 'F')
c += b - 'A' + 10;
else
- panicf("bad codepoint char '%c'", b);
+ fatal("bad codepoint char '%c'", b);
}
return c;
@@ -64,23 +78,23 @@ codepointrange(io·Buffer *utf8, char field[NumFields][FieldLen], int *start, i
c = codepoint(field[Fcode]);
if(c >= NumRunes)
- panicf("unexpected large codepoint %x", c);
+ fatal("unexpected large codepoint %x", c);
if(c <= e)
- panicf("bad code sequence: %x then %x", e, c);
+ fatal("bad code sequence: %x then %x", e, c);
e = c;
if(strstr(field[Fname], ", First>") != nil){
if(!parse(utf8, arrlen(other), other))
- panicf("range start at end of file");
+ fatal("range start at end of file");
if(strstr(other[Fname], ", Last>") == nil)
- panicf("range start not followed by range end");
+ fatal("range start not followed by range end");
e = codepoint(other[Fcode]);
if(e <= c)
- panicf("bad code sequence: %x then %x", c, e);
+ fatal("bad code sequence: %x then %x", c, e);
if(strcmp(field[Fcategory], other[Fcategory]) != 0)
- panicf("range with mismatched category");
+ fatal("range with mismatched category");
}
*start = c;
diff --git a/src/base/utf/vendor/common.h b/src/base/utf/vendor/common.h
index 95d7eaf..566fe68 100644
--- a/src/base/utf/vendor/common.h
+++ b/src/base/utf/vendor/common.h
@@ -3,6 +3,10 @@
#include <u.h>
#include <base.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
enum
{
// Fields inside UnicodeData.txt
@@ -44,3 +48,5 @@ void putsearch(void);
int putrange(char *ident, char *prop, int force);
int putpair(char *ident, char *prop);
int putsingle(char *ident, char *prop);
+
+int fatal(char *fmt, ...);
diff --git a/src/base/utf/vendor/mkrunetype.c b/src/base/utf/vendor/mkrunetype.c
index 3d75ce8..dd6e2c7 100644
--- a/src/base/utf/vendor/mkrunetype.c
+++ b/src/base/utf/vendor/mkrunetype.c
@@ -39,7 +39,7 @@ isrange(char *label, char *prop, int force)
{
char ident[128];
if(snprintf(ident, arrlen(ident), "is%s_range", label) == arrlen(ident))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
return putrange(ident, prop, force);
}
@@ -49,7 +49,7 @@ ispair(char *label, char *prop)
{
char ident[128];
if(snprintf(ident, arrlen(ident), "is%s_pair", label) == arrlen(ident))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
return putpair(ident, prop);
}
@@ -59,7 +59,7 @@ issingle(char *label, char *prop)
{
char ident[128];
if(snprintf(ident, arrlen(ident), "is%s_single", label) == arrlen(ident))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
return putsingle(ident, prop);
}
@@ -125,7 +125,7 @@ torange(char *label, int *index, int force)
d = DELTA(index[l], l);
if(d != (rune)d)
- panicf("bad map delta %d", d);
+ fatal("bad map delta %d", d);
for(r = l+1; r < NumRunes; r++){
if(DELTA(index[r], r) != d)
@@ -162,7 +162,7 @@ topair(char *label, int *index)
d = DELTA(index[l], l);
if(d != (rune)d)
- panicf("bad delta %d", d);
+ fatal("bad delta %d", d);
for(r = l+2; r < NumRunes; r += 2){
if(DELTA(index[r], r) != d)
@@ -198,7 +198,7 @@ tosingle(char *label, int *index)
d = DELTA(index[i], i);
if(d != (rune)d)
- panicf("bad map delta %d", d);
+ fatal("bad map delta %d", d);
if(!start){
printf("static rune to%s_single[] = {\n", label);
@@ -268,7 +268,7 @@ static void
usage(void)
{
fprintf(stderr, "usage: mkrunetype <UnicodeData.txt>\n");
- exit(1);
+ rt·exit(1);
}
int
@@ -285,7 +285,7 @@ main(int argc, char *argv[])
usage();
if((err=io·open(argv[0], sys·ORead, &utf8)))
- panicf("can't open %s: %d: %s\n", argv[0], err, strerror(err));
+ fatal("can't open %s: %d: %s\n", argv[0], err, strerror(err));
/* by default each character maps to itself */
for(i = 0; i < NumRunes; i++) {
@@ -350,7 +350,7 @@ main(int argc, char *argv[])
break;
default: badproperty:
- panicf("unrecognized category '%s'", prop);
+ fatal("unrecognized category '%s'", prop);
}
/* grab transformations */
if(*field[Fupper])
diff --git a/src/base/utf/vendor/mkrunewidth.c b/src/base/utf/vendor/mkrunewidth.c
index c911b66..7025744 100644
--- a/src/base/utf/vendor/mkrunewidth.c
+++ b/src/base/utf/vendor/mkrunewidth.c
@@ -38,7 +38,7 @@ parse_category(char *path)
char *prop, field[NumFields][FieldLen];
if(io·open(path, sys·ORead, &utf8))
- panicf("can't open %s\n", path);
+ fatal("can't open %s\n", path);
// NOTE: we don't check for comments here
ec = -1;
@@ -111,7 +111,7 @@ parse_eawidths(char *path)
char field[2][FieldLen];
if(io·open(path, sys·ORead, &utf8))
- panicf("can't open %s\n", path);
+ fatal("can't open %s\n", path);
while((at=parse(&utf8, arrlen(field), field)) != ParseEOF){
if(at == ParseSkip)
@@ -129,7 +129,7 @@ parse_eawidths(char *path)
case 'F': w = 2; break;
default:
- panicf("malformed east asian width class: %s\n", field[1]);
+ fatal("malformed east asian width class: %s\n", field[1]);
}
coderange(field[0], &l, &r);
@@ -153,7 +153,7 @@ parse_emoji(char *path)
char *s, field[2][FieldLen];
if(io·open(path, sys·ORead, &utf8))
- panicf("can't open %s\n", path);
+ fatal("can't open %s\n", path);
while((at=parse(&utf8, arrlen(field), field)) != ParseEOF){
if(at == ParseSkip)
@@ -198,17 +198,17 @@ maketable(char *label, char *table, int pairs, int onlyranges)
/* ranges */
if(snprintf(ident[Irange], arrlen(ident[Irange]), "%s_range", label) == arrlen(ident[Irange]))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
r = putrange(ident[Irange], table, onlyranges);
if(!onlyranges && pairs){
if(snprintf(ident[Ipair], arrlen(ident[Ipair]), "%s_pair", label) == arrlen(ident[Ipair]))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
p = putpair(ident[Ipair], table);
}
if(!onlyranges){
if(snprintf(ident[Isingle], arrlen(ident[Isingle]), "%s_single", label) == arrlen(ident[Isingle]))
- panicf("out of identifier space\n");
+ fatal("out of identifier space\n");
s = putsingle(ident[Isingle], table);
}
@@ -253,12 +253,11 @@ maketable(char *label, char *table, int pairs, int onlyranges)
// -----------------------------------------------------------------------
// main point of entry
-static
-void
+static void
usage(void)
{
fprintf(stderr, "usage: mkrunewidth <UnicodeData.txt> <EastAsianWidth.txt> <EmojiData.txt>\n");
- exit(1);
+ rt·exit(1);
}
#define SETW0(c) \
@@ -301,7 +300,7 @@ main(int argc, char *argv[])
/* simple checking */
for(c=0; c<NumRunes; c++){
if(table.width[0][c] + table.width[1][c] + table.width[2][c] > 1)
- panicf("improper table state");
+ fatal("improper table state");
}
putsearch();