mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
log: add option to add a callback to C logging subsystem
This commit is contained in:
parent
d01b76070d
commit
bb2ea53856
6 changed files with 55 additions and 417 deletions
|
@ -36,11 +36,15 @@ extern "C" {
|
|||
#include <villas/log_config.h>
|
||||
|
||||
/* The log level which is passed as first argument to print() */
|
||||
#define LOG_LVL_DEBUG CLR_GRY("Debug")
|
||||
#define LOG_LVL_INFO CLR_WHT("Info ")
|
||||
#define LOG_LVL_WARN CLR_YEL("Warn ")
|
||||
#define LOG_LVL_ERROR CLR_RED("Error")
|
||||
#define LOG_LVL_STATS CLR_MAG("Stats")
|
||||
enum log_level {
|
||||
LOG_LVL_DEBUG,
|
||||
LOG_LVL_INFO,
|
||||
LOG_LVL_WARN,
|
||||
LOG_LVL_ERROR,
|
||||
LOG_LVL_STATS,
|
||||
};
|
||||
|
||||
typedef void (*log_cb_t)(struct log *l, enum log_level lvl, const char *fmt, va_list va);
|
||||
|
||||
/** Debug facilities.
|
||||
*
|
||||
|
@ -84,6 +88,8 @@ enum log_facilities {
|
|||
struct log {
|
||||
enum state state;
|
||||
|
||||
const char *name;
|
||||
|
||||
struct timespec epoch; /**< A global clock used to prefix the log messages. */
|
||||
|
||||
struct winsize window; /**< Size of the terminal window. */
|
||||
|
@ -99,15 +105,18 @@ struct log {
|
|||
int syslog; /**< Whether or not to log to syslogd. */
|
||||
bool tty; /**< Is the log file a tty? */
|
||||
|
||||
log_cb_t callback;
|
||||
|
||||
FILE *file; /**< Send all log output to this file / stdout / stderr. */
|
||||
};
|
||||
|
||||
/** The global log instance. */
|
||||
struct log *global_log;
|
||||
struct log default_log;
|
||||
extern struct log *global_log;
|
||||
|
||||
/** Initialize log object */
|
||||
int log_init(struct log *l, int level, long faciltities);
|
||||
int log_init(struct log *l, const char *name, int level, long faciltities);
|
||||
|
||||
void log_set_callback(struct log *l, log_cb_t cb);
|
||||
|
||||
int log_open(struct log *l);
|
||||
|
||||
|
@ -135,7 +144,7 @@ int log_set_facility_expression(struct log *l, const char *expression);
|
|||
* @param lvl The log level
|
||||
* @param fmt The format string (printf alike)
|
||||
*/
|
||||
void log_print(struct log *l, const char *lvl, const char *fmt, ...)
|
||||
void log_print(struct log *l, enum log_level lvl, const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 3, 4)));
|
||||
|
||||
/** Logs variadic messages to stdout.
|
||||
|
@ -144,7 +153,7 @@ void log_print(struct log *l, const char *lvl, const char *fmt, ...)
|
|||
* @param fmt The format string (printf alike)
|
||||
* @param va The variadic argument list (see stdarg.h)
|
||||
*/
|
||||
void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list va);
|
||||
void log_vprint(struct log *l, enum log_level lvl, const char *fmt, va_list va);
|
||||
|
||||
/** Printf alike debug message with level. */
|
||||
void debug(long lvl, const char *fmt, ...)
|
||||
|
|
|
@ -43,23 +43,33 @@
|
|||
#endif
|
||||
|
||||
struct log *global_log;
|
||||
struct log default_log;
|
||||
|
||||
/* We register a default log instance */
|
||||
__attribute__((constructor))
|
||||
void register_default_log()
|
||||
{
|
||||
int ret;
|
||||
static struct log default_log;
|
||||
|
||||
ret = log_init(&default_log, V, LOG_ALL);
|
||||
ret = log_init(&default_log, "default", V, LOG_ALL);
|
||||
if (ret)
|
||||
error("Failed to initalize log");
|
||||
|
||||
ret = log_open(&default_log);
|
||||
if (ret)
|
||||
error("Failed to start log");
|
||||
|
||||
global_log = &default_log;
|
||||
}
|
||||
|
||||
static const char *level_strs[] = {
|
||||
CLR_GRY("Debug"), /* LOG_LVL_DEBUG */
|
||||
CLR_WHT("Info "), /* LOG_LVL_INFO */
|
||||
CLR_YEL("Warn "), /* LOG_LVL_WARN */
|
||||
CLR_RED("Error"), /* LOG_LVL_ERROR */
|
||||
CLR_MAG("Stats") /* LOG_LVL_STATS */
|
||||
};
|
||||
|
||||
/** List of debug facilities as strings */
|
||||
static const char *facilities_strs[] = {
|
||||
"pool", /* LOG_POOL */
|
||||
|
@ -106,18 +116,20 @@ static void log_resize(int signal, siginfo_t *sinfo, void *ctx)
|
|||
debug(LOG_LOG | 15, "New terminal size: %dx%x", global_log->window.ws_row, global_log->window.ws_col);
|
||||
}
|
||||
|
||||
int log_init(struct log *l, int level, long facilitites)
|
||||
int log_init(struct log *l, const char *name, int level, long facilitites)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Register this log instance globally */
|
||||
global_log = l;
|
||||
|
||||
l->name = name;
|
||||
l->level = level;
|
||||
l->syslog = 0;
|
||||
l->facilities = facilitites;
|
||||
l->file = stderr;
|
||||
l->path = NULL;
|
||||
l->callback = NULL;
|
||||
|
||||
l->epoch = time_now();
|
||||
l->prefix = getenv("VILLAS_LOG_PREFIX");
|
||||
|
@ -159,6 +171,11 @@ int log_init(struct log *l, int level, long facilitites)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void log_set_callback(struct log *l, log_cb_t cb)
|
||||
{
|
||||
l->callback = cb;
|
||||
}
|
||||
|
||||
int log_open(struct log *l)
|
||||
{
|
||||
if (l->path) {
|
||||
|
@ -263,7 +280,7 @@ found: if (negate)
|
|||
return l->facilities;
|
||||
}
|
||||
|
||||
void log_print(struct log *l, const char *lvl, const char *fmt, ...)
|
||||
void log_print(struct log *l, enum log_level lvl, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
@ -272,11 +289,16 @@ void log_print(struct log *l, const char *lvl, const char *fmt, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list ap)
|
||||
void log_vprint(struct log *l, enum log_level lvl, const char *fmt, va_list ap)
|
||||
{
|
||||
struct timespec ts = time_now();
|
||||
static __thread char buf[1024];
|
||||
|
||||
if (l->callback) {
|
||||
l->callback(l, lvl, fmt, ap);
|
||||
return;
|
||||
}
|
||||
|
||||
int off = 0;
|
||||
int len = sizeof(buf);
|
||||
|
||||
|
@ -285,7 +307,7 @@ void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list ap)
|
|||
off += snprintf(buf + off, len - off, "%s", l->prefix);
|
||||
|
||||
/* Timestamp & Severity */
|
||||
off += snprintf(buf + off, len - off, "%10.3f %-5s ", time_delta(&l->epoch, &ts), lvl);
|
||||
off += snprintf(buf + off, len - off, "%10.3f %-5s ", time_delta(&l->epoch, &ts), level_strs[lvl]);
|
||||
|
||||
/* Format String */
|
||||
off += vsnprintf(buf + off, len - off, fmt, ap);
|
||||
|
|
|
@ -84,14 +84,12 @@ void jerror(json_error_t *err, const char *fmt, ...)
|
|||
va_list ap;
|
||||
char *buf = NULL;
|
||||
|
||||
struct log *l = global_log ? global_log : &default_log;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log_print(l, LOG_LVL_ERROR, "%s:", buf);
|
||||
log_print(l, LOG_LVL_ERROR, " %s in %s:%d:%d", err->text, err->source, err->line, err->column);
|
||||
log_print(global_log, LOG_LVL_ERROR, "%s:", buf);
|
||||
log_print(global_log, LOG_LVL_ERROR, " %s in %s:%d:%d", err->text, err->source, err->line, err->column);
|
||||
|
||||
free(buf);
|
||||
|
||||
|
|
|
@ -62,10 +62,8 @@ static int table_resize(struct table *t, int width)
|
|||
|
||||
void table_header(struct table *t)
|
||||
{
|
||||
struct log *l = global_log ? global_log : &default_log;
|
||||
|
||||
if (t->width != l->width)
|
||||
table_resize(t, l->width);
|
||||
if (t->width != global_log->width)
|
||||
table_resize(t, global_log->width);
|
||||
|
||||
char *line0 = strf("\b");
|
||||
char *line1 = strf("\b\b" BOX_UD);
|
||||
|
@ -121,10 +119,8 @@ void table_header(struct table *t)
|
|||
|
||||
void table_row(struct table *t, ...)
|
||||
{
|
||||
struct log *l = global_log ? global_log : &default_log;
|
||||
|
||||
if (t->width != l->width) {
|
||||
table_resize(t, l->width);
|
||||
if (t->width != global_log->width) {
|
||||
table_resize(t, global_log->width);
|
||||
table_header(t);
|
||||
}
|
||||
|
||||
|
@ -156,10 +152,8 @@ void table_row(struct table *t, ...)
|
|||
|
||||
void table_footer(struct table *t)
|
||||
{
|
||||
struct log *l = global_log ? global_log : &default_log;
|
||||
|
||||
if (t->width != l->width)
|
||||
table_resize(t, l->width);
|
||||
if (t->width != global_log->width)
|
||||
table_resize(t, global_log->width);
|
||||
|
||||
char *line = strf("\b");
|
||||
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
/** Unit tests for advio
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLAScommon
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/logging.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
#include <villas/advio.h>
|
||||
|
||||
/** This URI points to a Sciebo share which contains some test files.
|
||||
* The Sciebo share is read/write accessible via WebDAV. */
|
||||
#define BASE_URI "https://1Nrd46fZX8HbggT:badpass@rwth-aachen.sciebo.de/public.php/webdav/node/tests"
|
||||
|
||||
Test(advio, islocal)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = aislocal("/var/log/villas/dta.dat");
|
||||
cr_assert_eq(ret, 1);
|
||||
|
||||
ret = aislocal("http://www.google.de");
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = aislocal("torrent://www.google.de");
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(advio, local)
|
||||
{
|
||||
AFILE *af;
|
||||
int ret;
|
||||
char *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
|
||||
/* We open this file and check the first line */
|
||||
af = afopen(__FILE__, "r");
|
||||
cr_assert(af, "Failed to open local file");
|
||||
|
||||
ret = getline(&buf, &buflen, af->file);
|
||||
cr_assert_gt(ret, 1);
|
||||
cr_assert_str_eq(buf, "/** Unit tests for advio\n");
|
||||
}
|
||||
|
||||
Test(advio, download)
|
||||
{
|
||||
AFILE *af;
|
||||
int ret;
|
||||
size_t len;
|
||||
char buffer[64];
|
||||
char expect[64] = "ook4iekohC2Teegoghu6ayoo1OThooregheebaet8Zod1angah0che7quai4ID7A";
|
||||
|
||||
af = afopen(BASE_URI "/download" , "r");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
len = afread(buffer, 1, sizeof(buffer), af);
|
||||
cr_assert_gt(len, 0, "len=%zu, feof=%u", len, afeof(af));
|
||||
|
||||
cr_assert_arr_eq(buffer, expect, sizeof(expect));
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert_eq(ret, 0, "Failed to close file");
|
||||
}
|
||||
|
||||
Test(advio, download_large)
|
||||
{
|
||||
AFILE *af;
|
||||
int ret;
|
||||
|
||||
af = afopen(BASE_URI "/download-large" , "r");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
char line[4096];
|
||||
|
||||
char *f;
|
||||
|
||||
f = afgets(line, 4096, af);
|
||||
cr_assert_not_null(f);
|
||||
|
||||
/* Check first line */
|
||||
cr_assert_str_eq(line, "# VILLASnode signal params: type=mixed, values=4, rate=1000.000000, limit=100000, amplitude=1.000000, freq=1.000000\n");
|
||||
|
||||
while(afgets(line, 4096, af));
|
||||
|
||||
/* Check last line */
|
||||
cr_assert_str_eq(line, "1497710478.862332239(99999) 0.752074 -0.006283 1.000000 0.996000\n");
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert_eq(ret, 0, "Failed to close file");
|
||||
}
|
||||
|
||||
Test(advio, resume)
|
||||
{
|
||||
int ret;
|
||||
char *retp;
|
||||
AFILE *af1, *af2;
|
||||
char *fn, dir[] = "/tmp/temp.XXXXXX";
|
||||
char line1[32];
|
||||
char *line2 = NULL;
|
||||
size_t linelen = 0;
|
||||
|
||||
retp = mkdtemp(dir);
|
||||
cr_assert_not_null(retp);
|
||||
|
||||
ret = asprintf(&fn, "%s/file", dir);
|
||||
cr_assert_gt(ret, 0);
|
||||
|
||||
af1 = afopen(fn, "w+");
|
||||
cr_assert_not_null(af1);
|
||||
|
||||
/* We flush once the empty file in order to upload an empty file. */
|
||||
aupload(af1, 0);
|
||||
|
||||
af2 = afopen(fn, "r");
|
||||
cr_assert_not_null(af2);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
snprintf(line1, sizeof(line1), "This is line %d\n", i);
|
||||
|
||||
afputs(line1, af1);
|
||||
aupload(af1, 1);
|
||||
|
||||
adownload(af2, 1);
|
||||
|
||||
ret = agetline(&line2, &linelen, af2);
|
||||
cr_assert_gt(ret, 0);
|
||||
|
||||
cr_assert_str_eq(line1, line2);
|
||||
}
|
||||
|
||||
ret = afclose(af1);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = afclose(af2);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = unlink(fn);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = rmdir(dir);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
free(line2);
|
||||
}
|
||||
|
||||
Test(advio, upload)
|
||||
{
|
||||
AFILE *af;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
char upload[64];
|
||||
char buffer[64];
|
||||
|
||||
/* Get some random data to upload */
|
||||
len = read_random(upload, sizeof(upload));
|
||||
cr_assert_eq(len, sizeof(upload));
|
||||
|
||||
/* Open file for writing */
|
||||
af = afopen(BASE_URI "/upload", "w+");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
len = afwrite(upload, 1, sizeof(upload), af);
|
||||
cr_assert_eq(len, sizeof(upload));
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert_eq(ret, 0, "Failed to close/upload file");
|
||||
|
||||
/* Open for reading and comparison */
|
||||
af = afopen(BASE_URI "/upload", "r");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
len = afread(buffer, 1, sizeof(upload), af);
|
||||
cr_assert_eq(len, sizeof(upload));
|
||||
|
||||
cr_assert_arr_eq(buffer, upload, len);
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert(ret == 0, "Failed to close file");
|
||||
}
|
||||
|
||||
Test(advio, append)
|
||||
{
|
||||
AFILE *af;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
char append1[64] = "xa5gieTohlei9iu1uVaePae6Iboh3eeheeme5iejue5sheshae4uzisha9Faesei";
|
||||
char append2[64] = "bitheeRae7igee2miepahJaefoGad1Ooxeif0Mooch4eojoumueYahn4ohc9poo2";
|
||||
char expect[128] = "xa5gieTohlei9iu1uVaePae6Iboh3eeheeme5iejue5sheshae4uzisha9FaeseibitheeRae7igee2miepahJaefoGad1Ooxeif0Mooch4eojoumueYahn4ohc9poo2";
|
||||
char buffer[128];
|
||||
|
||||
/* Open file for writing first chunk */
|
||||
af = afopen(BASE_URI "/append", "w+");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
/* The append file might already exist and be not empty from a previous run. */
|
||||
ret = ftruncate(afileno(af), 0);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
char c;
|
||||
fseek(af->file, 0, SEEK_SET);
|
||||
if (af->file) {
|
||||
while ((c = getc(af->file)) != EOF)
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
len = afwrite(append1, 1, sizeof(append1), af);
|
||||
cr_assert_eq(len, sizeof(append1));
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert_eq(ret, 0, "Failed to close/upload file");
|
||||
|
||||
/* Open file for writing second chunk */
|
||||
af = afopen(BASE_URI "/append", "a");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
len = afwrite(append2, 1, sizeof(append2), af);
|
||||
cr_assert_eq(len, sizeof(append2));
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert_eq(ret, 0, "Failed to close/upload file");
|
||||
|
||||
/* Open for reading and comparison */
|
||||
af = afopen(BASE_URI "/append", "r");
|
||||
cr_assert(af, "Failed to download file");
|
||||
|
||||
len = afread(buffer, 1, sizeof(buffer), af);
|
||||
cr_assert_eq(len, sizeof(buffer));
|
||||
|
||||
ret = afclose(af);
|
||||
cr_assert(ret == 0, "Failed to close file");
|
||||
|
||||
cr_assert_arr_eq(buffer, expect, sizeof(expect));
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
/** Unit tests for advio
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLAScommon
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include <villas/bitset.h>
|
||||
#include <villas/utils.h>
|
||||
|
||||
#define LEN 1027
|
||||
|
||||
Test(bitset, simple)
|
||||
{
|
||||
int ret;
|
||||
struct bitset bs;
|
||||
|
||||
int bits[] = { 23, 223, 25, 111, 252, 86, 222, 454, LEN-1 };
|
||||
|
||||
ret = bitset_init(&bs, LEN);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(bits); i++) {
|
||||
bitset_set(&bs, bits[i]);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(bits); i++) {
|
||||
ret = bitset_test(&bs, bits[i]);
|
||||
cr_assert_eq(ret, 1, "Failed at bit %d", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(bits); i++) {
|
||||
ret = bitset_clear(&bs, bits[i]);
|
||||
cr_assert_eq(ret, 0, "Failed at bit %d", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < LEN; i++) {
|
||||
ret = bitset_test(&bs, i);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
ret = bitset_destroy(&bs);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(bitset, outofbounds)
|
||||
{
|
||||
int ret;
|
||||
struct bitset bs;
|
||||
|
||||
ret = bitset_init(&bs, LEN);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_set(&bs, LEN+1);
|
||||
cr_assert_eq(ret, -1);
|
||||
|
||||
ret = bitset_test(&bs, LEN+1);
|
||||
cr_assert_eq(ret, -1);
|
||||
|
||||
ret = bitset_destroy(&bs);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(bitset, cmp)
|
||||
{
|
||||
int ret;
|
||||
struct bitset bs1, bs2;
|
||||
|
||||
ret = bitset_init(&bs1, LEN);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_init(&bs2, LEN);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_set(&bs1, 525);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_set(&bs2, 525);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_cmp(&bs1, &bs2);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_clear(&bs2, 525);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_cmp(&bs1, &bs2);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
ret = bitset_destroy(&bs1);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
ret = bitset_destroy(&bs2);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(bitset, all)
|
||||
{
|
||||
int ret;
|
||||
struct bitset bs;
|
||||
|
||||
ret = bitset_init(&bs, LEN);
|
||||
cr_assert_eq(ret, 0);
|
||||
|
||||
for (int i = 0; i < LEN; i++) {
|
||||
bitset_test(&bs, i);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
ret = bitset_destroy(&bs);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
Loading…
Add table
Reference in a new issue