Skip to content

Commit

Permalink
Refactored tests and greatly improved test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
dimkr committed Nov 29, 2017
1 parent 189468b commit 98c8a86
Show file tree
Hide file tree
Showing 54 changed files with 2,618 additions and 874 deletions.
2 changes: 1 addition & 1 deletion examples/httpd.b6b
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
{$local hdrs {}}
{$map line [$list.range $lines 1 [$- [$list.len $lines] 1]] {
{$local parts [$str.split $line {: }]}
{$dict.set $hdrs [$rtrim [$list.index $parts 0]] [$ltrim [$str.join : [$list.range $parts 1 [$list.len $parts]]]]}
{$dict.set $hdrs [$rtrim [$list.index $parts 0]] [$ltrim [$str.join : [$list.range $parts 1 [$- [$list.len $parts] 1]]]]}
}}

{$dict.set $http.req_urls $1 [$list.index $info 1]}
Expand Down
1 change: 1 addition & 0 deletions include/b6b.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

# include <b6b/core.h>
# include <b6b/obj.h>
# include <b6b/hash.h>
# include <b6b/str.h>
# include <b6b/int.h>
# include <b6b/float.h>
Expand Down
46 changes: 46 additions & 0 deletions include/b6b/hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* This file is part of b6b.
*
* Copyright 2017 Dima Krasner
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <inttypes.h>

static inline uint32_t b6b_hash_init(void)
{
return 0;
}

static inline void b6b_hash_update(uint32_t *hash,
const unsigned char *buf,
const size_t len)
{
size_t i;

for (i = 0; i < len; ++i) {
*hash += buf[i] + (*hash << 10);
*hash ^= (*hash >> 6);
}
}

static inline void b6b_hash_finish(uint32_t *hash)
{
*hash += (*hash << 3);
*hash ^= (*hash >> 11);
*hash += (*hash << 15);
}

__attribute__((nonnull(1)))
uint32_t b6b_hash(const unsigned char *buf, const size_t len);
2 changes: 2 additions & 0 deletions include/b6b/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

typedef long long b6b_int;
#define B6B_INT_FMT "%lld"
#define B6B_INT_MAX LLONG_MAX

typedef double b6b_float;
#define B6B_FLOAT_FMT "%.12f"
Expand Down
3 changes: 0 additions & 3 deletions include/b6b/str.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ struct b6b_obj *b6b_str_fmt(const char *fmt, ...);

int b6b_as_str(struct b6b_obj *o);

__attribute__((nonnull(1)))
uint32_t b6b_str_hash(const char *s, const size_t len);

struct b6b_obj *b6b_str_decode(const char *s, size_t len);

static inline int b6b_isspace(const char c)
Expand Down
11 changes: 8 additions & 3 deletions src/b6b_ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,16 @@ static enum b6b_res b6b_ffi_proc_memcpy(struct b6b_interp *interp,
{
struct b6b_obj *addr, *len;
char *s;
const char *p;

if (!b6b_proc_get_args(interp, args, "oii", NULL, &addr, &len))
if (!b6b_proc_get_args(interp, args, "oii", NULL, &addr, &len) || !len->i)
return B6B_ERR;

s = b6b_strndup((char *)(intptr_t)addr->i, (size_t)len->i);
p = (char *)(intptr_t)addr->i;
if (!p)
return B6B_ERR;

s = b6b_strndup(p, (size_t)len->i);
if (b6b_unlikely(!s))
return B6B_ERR;

Expand Down Expand Up @@ -705,7 +710,7 @@ __b6b_ext(b6b_ffi);
"{$ffi.pack p [$1 address]}" \
"}}\n" \
"{$proc ffi.call {" \
"{$1 [$map x [$list.range $@ 2 [$list.len $@]] {{$x address}}]}" \
"{$1 [$map x [$list.range $@ 2 [$- [$list.len $@] 1]] {{$x address}}]}" \
"}}"

static int b6b_ffi_init(struct b6b_interp *interp)
Expand Down
32 changes: 32 additions & 0 deletions src/b6b_hash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* This file is part of b6b.
*
* Copyright 2017 Dima Krasner
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <inttypes.h>

#include <b6b.h>

uint32_t b6b_hash(const unsigned char *buf, const size_t len)
{
uint32_t h;

h = b6b_hash_init();
b6b_hash_update(&h, buf, len);
b6b_hash_finish(&h);

return h;
}
8 changes: 5 additions & 3 deletions src/b6b_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static enum b6b_res b6b_list_proc_extend(struct b6b_interp *interp,

if (b6b_proc_get_args(interp, args, "oll", NULL, &l, &l2) &&
b6b_list_extend(l, l2))
return B6B_OK;
return b6b_return(interp, b6b_ref(l));

return B6B_ERR;
}
Expand All @@ -452,7 +452,7 @@ static enum b6b_res b6b_list_proc_index(struct b6b_interp *interp,
struct b6b_litem *li;
b6b_int j;

if (b6b_proc_get_args(interp, args, "oli", NULL, &l, &i)) {
if (b6b_proc_get_args(interp, args, "oli", NULL, &l, &i) && (i->i >= 0)) {
li = b6b_list_first(l);
if (!li)
return B6B_ERR;
Expand Down Expand Up @@ -481,7 +481,8 @@ static enum b6b_res b6b_list_proc_range(struct b6b_interp *interp,

if (b6b_unlikely(start->i < 0) ||
b6b_unlikely(end->i < 0) ||
b6b_unlikely(start->i >= end->i))
b6b_unlikely(end->i == B6B_INT_MAX) ||
b6b_unlikely(start->i > end->i))
return B6B_ERR;

li = b6b_list_first(l);
Expand All @@ -498,6 +499,7 @@ static enum b6b_res b6b_list_proc_range(struct b6b_interp *interp,
if (b6b_unlikely(!r))
return B6B_ERR;

i = start->i;
do {
if (b6b_unlikely(!b6b_list_add(r, li->o))) {
b6b_destroy(r);
Expand Down
2 changes: 1 addition & 1 deletion src/b6b_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int b6b_obj_hash(struct b6b_obj *o)
if (!b6b_as_str(o))
return 0;

o->hash = b6b_str_hash(o->s, o->slen);
o->hash = b6b_hash((const unsigned char *)o->s, o->slen);
o->flags |= B6B_OBJ_HASHED;
}

Expand Down
39 changes: 8 additions & 31 deletions src/b6b_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,23 +267,6 @@ int b6b_as_str(struct b6b_obj *o)
return 1;
}

/* Jenkins's one-at-a-time hash */
uint32_t b6b_str_hash(const char *s, const size_t len)
{
size_t i;
uint32_t h = 0;

for (i = 0; i < len; ++i) {
h += s[i] + (h << 10);
h ^= (h >> 6);
}

h += (h << 3);
h ^= (h >> 11);
h += (h << 15);
return h;
}

struct b6b_obj *b6b_str_decode(const char *s, size_t len)
{
mbstate_t ps = {0};
Expand All @@ -297,23 +280,11 @@ struct b6b_obj *b6b_str_decode(const char *s, size_t len)
if (len) {
do {
out = mbrtowc(NULL, s, len, &ps);
if ((out == (size_t)-1) || (out == (size_t)-2)) {
if ((out == 0) || (out == (size_t)-1) || (out == (size_t)-2)) {
b6b_destroy(l);
return NULL;
}

if (!out) {
/* if no characters were converted and this isn't the end of the
* string, there is a \0 within the string and it cannot be
* decoded */
if (len) {
b6b_destroy(l);
return NULL;
}

break;
}

c = b6b_str_copy(s, out);
if (b6b_unlikely(!c)) {
b6b_destroy(l);
Expand All @@ -329,6 +300,7 @@ struct b6b_obj *b6b_str_decode(const char *s, size_t len)
b6b_unref(c);

len -= out;
/* if the entire string was converted, stop */
if (!len)
break;

Expand Down Expand Up @@ -367,6 +339,7 @@ static enum b6b_res b6b_str_proc_range(struct b6b_interp *interp,
struct b6b_obj *args)
{
struct b6b_obj *s, *start, *end;
size_t len;

if (!b6b_proc_get_args(interp, args, "osii", NULL, &s, &start, &end) ||
(start->i < 0) ||
Expand All @@ -376,9 +349,13 @@ static enum b6b_res b6b_str_proc_range(struct b6b_interp *interp,
(start->i > end->i))
return B6B_ERR;

len = (size_t)(end->i - start->i);
if (len == SIZE_MAX)
return B6B_ERR;

return b6b_return_str(interp,
&s->s[(ptrdiff_t)start->i],
end->i - start->i);
len + 1);
}

static enum b6b_res b6b_str_proc_join(struct b6b_interp *interp,
Expand Down
4 changes: 2 additions & 2 deletions src/b6b_zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void b6b_zlib_do_deflate(void *arg)
{
struct b6b_zlib_deflate_data *data = (struct b6b_zlib_deflate_data *)arg;

do {
while (data->rem) {
if (data->rem > B6B_DEFLATE_CHUNK_SZ)
data->strm.avail_in = B6B_DEFLATE_CHUNK_SZ;
else
Expand All @@ -49,7 +49,7 @@ static void b6b_zlib_do_deflate(void *arg)
return;

data->rem = (mz_uint)data->slen - data->strm.total_in;
} while (data->rem);
}

data->ok = 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ if cc.has_header('fenv.h')
endif

libb6b_srcs = [
'b6b_obj.c', 'b6b_str.c', 'b6b_int.c', 'b6b_float.c', 'b6b_list.c', 'b6b_dict.c',
'b6b_hash.c', 'b6b_obj.c', 'b6b_str.c', 'b6b_int.c', 'b6b_float.c', 'b6b_list.c', 'b6b_dict.c',
'b6b_frame.c', 'b6b_thread.c', 'b6b_interp.c',
'b6b_math.c', 'b6b_logic.c', 'b6b_loop.c', 'b6b_exc.c', 'b6b_proc.c',
'b6b_strm.c', 'b6b_fdops.c', 'b6b_stdio.c', 'b6b_file.c', 'b6b_socket.c', 'b6b_timer.c', 'b6b_signal.c', 'b6b_sh.c', 'b6b_poll.c', 'b6b_evloop.c',
Expand Down
64 changes: 64 additions & 0 deletions tests/b6b_test_choice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* This file is part of b6b.
*
* Copyright 2017 Dima Krasner
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include <b6b.h>

int main()
{
struct b6b_interp interp;
int occ[5] = {0, 0, 0, 0, 0};

assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE));
assert(b6b_call_copy(&interp, "{$choice}", 9) == B6B_ERR);
b6b_interp_destroy(&interp);

assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE));
assert(b6b_call_copy(&interp, "{$choice {}}", 12) == B6B_ERR);
b6b_interp_destroy(&interp);

assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE));
assert(b6b_call_copy(&interp, "{$choice a}", 11) == B6B_OK);
assert(b6b_as_str(interp.fg->_));
assert(interp.fg->_->slen == 1);
assert(strcmp(interp.fg->_->s, "a") == 0);
b6b_interp_destroy(&interp);

assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE));
assert(b6b_call_copy(&interp, "{$choice {a b}}", 15) == B6B_OK);
assert(b6b_as_str(interp.fg->_));
assert(interp.fg->_->slen == 1);
assert((strcmp(interp.fg->_->s, "a") == 0) ||
(strcmp(interp.fg->_->s, "b") == 0));
b6b_interp_destroy(&interp);

assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE));
do {
assert(b6b_call_copy(&interp, "{$choice {0 1 2 3 4}}", 21) == B6B_OK);
assert(b6b_as_int(interp.fg->_));
assert(interp.fg->_->i >= 0);
assert(interp.fg->_->i <= 4);
++occ[interp.fg->_->i];
} while (!occ[0] || !occ[1] || !occ[2] || !occ[3] || !occ[4]);
b6b_interp_destroy(&interp);

return EXIT_SUCCESS;
}

0 comments on commit 98c8a86

Please sign in to comment.