init commit

This commit is contained in:
dzruyk
2022-04-23 01:35:06 +03:00
commit 6d1c299a16
18 changed files with 4294 additions and 0 deletions

32
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,32 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/list_test",
"args": ["--no-fork"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

14
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: gcc build",
"command": "make",
"problemMatcher": [
"$gcc"
],
"group": "build",
}
]
}

13
Makefile Normal file
View File

@@ -0,0 +1,13 @@
unittest_obj=munit/munit.o
CFLAGS=-Wall -ggdb
list_test: util.o list.o list_test.o $(unittest_obj)
$(CC) $^ -o $@
clean:
rm list_test $(unittest_obj) *.o
test: list_test
./list_test

48
README.txt Normal file
View File

@@ -0,0 +1,48 @@
Базовые структуры данных. Список
--------------------------------
* Склонировать репозиторий https://timp.pw/121/lab5_list.git
(если репозиторий уже склонирован -- пропустить этот шаг ^_^)
В этом задании необходимо дописать функции для работы с двусвязным списком.
Двусвязный список -- структура данных, которая имеет вид
Описание структуры данных в файле list.h
Вам необходимо реализовать некоторые функции в файле ./list.c
и пройти тесты (описанные в ./list_test.c).
Команда для сборки проекта -- make
Команда для запуска тестов -- make test
* Необходимо реализовать следующие функции(короткое описание функций можно
подсмотреть в list.h):
list_clear
list_push_front
list_len
Эти функции проверяет тест test_list_stage1
list_push_back
list_get
list_insert
list_pop_front
list_pop_back
list_remove
Эту функцию проверяет тест test_list_remove
list_reverse
Эту функцию проверяет тест test_list_reverse
(Опционально, но очень желательно)
Для работы вам могут понадобится следующие библиотечные функции:
* malloc(size_t size) -- функция, динамически выделяющая size байт и возвращающая
указатель на выделенный кусок
* realloc(void *ptr, size_t size) -- функция изменяющая размер выделенного куска памяти
на вход принимает указатель на предыдущий выделенный кусок.
возвращает укзаатель на заново выделенную память.
Все предыдущие данные в ptr остаются без изменений

136
list.c Normal file
View File

@@ -0,0 +1,136 @@
#include <assert.h>
#include <string.h>
#include "util.h"
#include "list.h"
void
list_init(list *l)
{
assert(l);
memset(l, 0, sizeof(*l));
}
static inline list_node *
list_node_orphan(list_node *li)
{
li->next = NULL;
li->prev = NULL;
return li;
}
//NOTE: Можем ли мы расчитывать на то, что node->next валидно после вызова list_free_cb???
void
list_clear(list *l, list_free_cb cb)
{
assert(l);
// <YOURCODE>
}
void
list_push_front(list *l, list_node *item)
{
assert(l && item);
// <YOURCODE>
}
void
list_push_back(list *l, list_node *item)
{
assert(l && item);
// <YOURCODE>
}
list_node *
list_first(list *l)
{
assert(l);
return l->head;
}
list_node *
list_last(list *l)
{
assert(l);
return l->tail;
}
size_t
list_len(list *l)
{
assert(l);
// <YOURCODE>
return 0;
}
list_node *
list_get(list *l, int idx)
{
assert(l);
// <YOURCODE>
return NULL;
}
void
list_insert(list *l, list_node *item, int idx)
{
assert(l && item);
// <YOURCODE>
}
list_node *
list_pop_front(list *l)
{
assert(l);
// <YOURCODE>
return NULL;
}
list_node *
list_pop_back(list *l)
{
assert(l);
// <YOURCODE>
return NULL;
}
int
list_index(list *l, list_node *n)
{
assert(l && n);
list_node *tmp;
int i = 0;
for (tmp = l->head; tmp != NULL; tmp = tmp->next) {
if (tmp == n)
return i;
i++;
}
return -1;
}
list_node *
list_remove(list *l, int idx)
{
assert(l);
// <YOURCODE>
return NULL;
}
void
list_reverse(list *l)
{
assert(l);
// <YOURCODE>
}
void
list_pass(list *l, list_pass_cb cb, void *opaq)
{
struct list_node *iter;
list_for_each(iter, l) {
cb(iter, opaq);
}
}

86
list.h Normal file
View File

@@ -0,0 +1,86 @@
#pragma once
#include <stdlib.h>
/* узел списка */
typedef struct list_node {
struct list_node *next; /* указатель на предыдущий элемент списка */
struct list_node *prev; /* указатель на следующий элемент списка */
} list_node;
/* структура, описывающая двусвязный список */
typedef struct {
list_node *head; /* указатель на голову списка */
list_node *tail; /* указатель на конец списка */
} list;
// Макро магия
#define list_for_each(iter, list) \
for (iter = list->head; iter != NULL; iter = iter->next)
typedef int (*list_pass_cb)(list_node *n, void *opaq);
typedef void (*list_free_cb)(list_node *n);
/* Инициализировать вектор (занулить указатели) */
void list_init(list *l);
/*
* Очистить список, удалив все элементы.
* *cb* -- опциональный параметр, с помощью которого передаётся функция, освобождающая объект
*/
void list_clear(list *l, list_free_cb cb);
list_node *list_first(list *l); /* Получить голову списка (или NULL, если список пустой) */
list_node *list_last(list *l); /* Получить конечный элемент списка (или NULL, если список пустой)*/
size_t list_len(list *l); /* Вернуть длину списка */
void list_push_front(list *l, list_node *node);
void list_push_back(list *l, list_node *node);
/*
* Get n'th element of list, return NULL if idx >= length(list)
*/
list_node *list_get(list *l, int idx);
/*
* Tries to insert node at idx position,
* calls xerror() (from util.h) if idx >= length(list)
* *Optional*: use negative idx to insert elements at the end of list
*/
void list_insert(list *l, list_node *node, int idx);
/*
* Удалить первый(последний) элемент списка.
* Если список пустой, ничего не делать и вернуть NULL
* NOTE: вы должны занулять указатели в list_node, который возвращаете
*/
list_node *list_pop_front(list *l);
list_node *list_pop_back(list *l);
/*
* Найти узел *n* в списке и вернуть
* порядковый номер узла в списке, или -1, если такого узла нет
*/
int list_index(list *l, list_node *n);
/*
* Удалить узел с порядковым номером idx
*/
list_node *list_remove(list *l, int idx);
/*
* Поменять порядок элементов в списке
* Т.е. Список [1, 2, 3, 4] должен стать [4, 3, 2, 1]
*/
void list_reverse(list *l);
void list_pass(list *l, list_pass_cb cb, void *opaq);
// Not implemented yet:
//
//typedef int (*list_cmp_cb)(list_node *a, list_node *b);
//void list_find(list *l, list_cmp_cb cb);
//void list_sort(list *l);

341
list_test.c Normal file
View File

@@ -0,0 +1,341 @@
#include <stdio.h>
#include "list.h"
#include "util.h"
#include "macro.h"
#include "munit/munit.h"
#define NAMELEN 128
typedef struct num_node {
list_node l;
int n;
} num_node;
static num_node *
new_num_node(int n)
{
num_node *res;
res = xmalloc(sizeof(*res));
res->n = n;
return res;
}
//#define NEW_ITEM(tp) xmalloc(sizeof(tp))
/*
list l;
list_init(&l);
list_clear(&l, NULL);
*/
int n_hardfrees = 0;
static void
hardmode_free(list_node *n)
{
n_hardfrees++;
memset(n, 0, sizeof(*n));
free(n);
}
void
list_num_print(list *l)
{
struct list_node *iter;
const char *hdrfmt = "%16.10s|%16.10s|%16.10s|%5.5s\n";
const char *itemfmt = "%16.10p|%16.10p|%16.10p|%5d\n";
printf("head = %p tail = %p\n", l->head, l->tail);
printf(hdrfmt, "ptr", "next", "prev", "n");
printf(" -------------------------------------------\n");
list_for_each(iter, l) {
num_node *ni;
ni = (num_node *)iter;
printf(itemfmt, ni, ni->l.next, ni->l.prev, ni->n);
}
}
static MunitResult
test_list_stage1(const MunitParameter params[], void * data)
{
//Tests for: list_init, list_clear, list_push_front, list_first, list_last
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
munit_logf(MUNIT_LOG_INFO, "Tests for %s", "list_init, list_clear, list_push_front, list_first, list_last");
munit_log(MUNIT_LOG_INFO, "Intializing num_node list...");
list_init(&l);
list_clear(&l, NULL);
munit_assert_null(l.head);
munit_assert_null(l.tail);
munit_log(MUNIT_LOG_INFO, "Checking list_push_front...");
// Insert first element, check list sanity
ni = new_num_node(num_arr[0]);
list_push_front(&l, (list_node *)ni);
munit_assert_null(ni->l.next);
munit_assert_null(ni->l.prev);
munit_assert_ptr(l.head, ==, ni);
munit_assert_ptr(l.tail, ==, ni);
// Insert second element, check list sanity
ni = new_num_node(num_arr[1]);
list_push_front(&l, (list_node *)ni);
munit_assert_not_null(ni->l.next);
munit_assert_null(ni->l.prev);
munit_assert_ptr(l.head, ==, ni);
munit_assert_ptr(l.tail, !=, ni);
for (i = 2; i < ARRSZ(num_arr); i++) {
munit_logf(MUNIT_LOG_DEBUG, "list_push_front i = %d", i);
ni = new_num_node(num_arr[i]);
list_push_front(&l, (list_node *)ni);
}
//list_num_print(&l);
munit_log(MUNIT_LOG_INFO, "Checking list contents after list_push_front calls");
// Manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, reverse_arr[i]);
}
ni = (num_node *) list_first(&l);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, reverse_arr[0]);
ni = (num_node *) list_last(&l);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[0]);
munit_assert_size(list_len(&l), ==, ARRSZ(num_arr));
list_clear(&l, (list_free_cb) free);
munit_assert_size(list_len(&l), ==, 0);
munit_log(MUNIT_LOG_INFO, "try to free every node and zero it memory");
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = xmalloc(sizeof(*ni));
ni->n = num_arr[i];
list_push_front(&l, (list_node *)ni);
}
size_t lsz = list_len(&l);
list_clear(&l, hardmode_free);
if (lsz != n_hardfrees) {
munit_log(MUNIT_LOG_WARNING, "not all objects are freed. Bug in list_clear??");
}
munit_assert_int(lsz, ==, n_hardfrees);
munit_assert_size(list_len(&l), ==, 0);
return MUNIT_OK;
}
static MunitResult
test_list_stage2(const MunitParameter params[], void * data)
{
//tests for list_push_back list_get list_insert list_pop_front list_pop_back
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int res_arr[] = {42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, 10};
num_node *n1, *n2;
num_node *ni;
int i;
int idx;
list l;
list_init(&l);
munit_log(MUNIT_LOG_INFO, "Checking list_push_back");
for (i = 2; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
munit_log(MUNIT_LOG_INFO, "Checking list_get");
for (i = 0; i < ARRSZ(num_arr) - 2; i++) {
ni = (num_node *) list_get(&l, i);
munit_assert_int(ni->n, ==, num_arr[i + 2]);
}
list_insert(&l, (list_node *) new_num_node(num_arr[0]), 0);
list_insert(&l, (list_node *) new_num_node(num_arr[1]), 1);
// manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, num_arr[i]);
}
list_insert(&l, (list_node *) new_num_node(42), 0);
list_insert(&l, (list_node *) new_num_node(43), 1);
list_insert(&l, (list_node *) new_num_node(44), list_len(&l) - 1);
// manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, res_arr[i]);
}
n2 = (num_node *) list_pop_front(&l);
munit_assert_not_null(n2);
munit_assert_int(n2->n, ==, 42);
n1 = (num_node *) list_pop_back(&l);
munit_assert_not_null(n1);
munit_assert_int(n1->n, ==, 10);
idx = list_index(&l, (list_node *) n2);
munit_assert_int(idx, ==, -1);
for (i = 0; i < 5; i++) {
munit_assert_int(
i, ==,
list_index(&l, list_get(&l, i))
);
}
list_clear(&l, (list_free_cb) free);
list_push_front(&l, (list_node *) n1);
list_push_front(&l, (list_node *) n2);
ni = (num_node *) list_pop_front(&l);
munit_assert_ptr(ni, ==, n2);
ni = (num_node *) list_pop_front(&l);
munit_assert_ptr(ni, ==, n1);
munit_assert_size(list_len(&l), ==, 0);
list_clear(&l, (list_free_cb) free);
munit_assert_null(list_pop_front(&l));
munit_assert_null(list_pop_back(&l));
return MUNIT_OK;
}
/*
static MunitResult
test_list_tmp(const MunitParameter params[], void * data)
{
//Tests for: list_remove list_reverse
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
list_init(&l);
list_clear(&l, (list_free_cb) free);
return MUNIT_OK;
}
*/
static MunitResult
test_list_remove(const MunitParameter params[], void * data)
{
//Tests for: list_remove list_reverse
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
num_node *ni;
int i;
list l;
list_init(&l);
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
ni = (num_node *) list_remove(&l, 122);
munit_assert_null(ni);
ni = (num_node *) list_remove(&l, 0);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[0]);
ni = (num_node *) list_remove(&l, list_len(&l) - 1);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[ARRSZ(num_arr) - 1]);
size_t sz = list_len(&l);
for (i = 0; i < sz; i++) {
ni = (num_node *) list_remove(&l, 0);
munit_assert_not_null(ni);
}
list_clear(&l, (list_free_cb) free);
return MUNIT_OK;
}
static MunitResult
test_list_reverse(const MunitParameter params[], void * data)
{
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
list_init(&l);
list_reverse(&l);
munit_assert_size(0, ==, list_len(&l));
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
list_reverse(&l);
munit_assert_size(list_len(&l), ==, ARRSZ(reverse_arr));
//manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, reverse_arr[i]);
}
return MUNIT_OK;
}
#define TEST_ITEM(func) {#func, func, NULL, NULL, MUNIT_TEST_OPTION_NONE }
static MunitTest test_suite_tests[] = {
TEST_ITEM(test_list_stage1),
TEST_ITEM(test_list_stage2),
TEST_ITEM(test_list_remove),
TEST_ITEM(test_list_reverse),
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
static const MunitSuite test_suite = {
(char *) "",
test_suite_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE
};
int
main(int argc, const char *argv[])
{
munit_suite_main(&test_suite, (void *) "vector_test", argc, (char * const*) argv);
return 0;
}

14
macro.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#define ARRSZ(arr) (sizeof(arr) / sizeof(*arr))
#define SWAP(a, b, type) do { \
type tmp; \
tmp = a; \
a = b; \
b = tmp; \
} while(0)
#define ARR_FOREACH(arr, item) \
for (item = arr; item != arr + ARRSZ(arr) * sizeof(*item); item++)

21
munit/COPYING Normal file
View File

@@ -0,0 +1,21 @@
µnit Testing Framework
Copyright (c) 2013-2016 Evan Nemerson <evan@nemerson.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

55
munit/Makefile Normal file
View File

@@ -0,0 +1,55 @@
# Using µnit is very simple; just include the header and add the C
# file to your sources. That said, here is a simple Makefile to build
# the example.
CSTD:=99
OPENMP:=n
ASAN:=n
UBSAN:=n
EXTENSION:=
TEST_ENV:=
CFLAGS:=
AGGRESSIVE_WARNINGS=n
ifeq ($(CC),pgcc)
CFLAGS+=-c$(CSTD)
else
CFLAGS+=-std=c$(CSTD)
endif
ifeq ($(OPENMP),y)
ifeq ($(CC),pgcc)
CFLAGS+=-mp
else
CFLAGS+=-fopenmp
endif
endif
ifneq ($(SANITIZER),)
CFLAGS+=-fsanitize=$(SANITIZER)
endif
ifneq ($(CC),pgcc)
ifeq ($(EXTRA_WARNINGS),y)
CFLAGS+=-Wall -Wextra -Werror
endif
ifeq ($(ASAN),y)
CFLAGS+=-fsanitize=address
endif
ifeq ($(UBSAN),y)
CFLAGS+=-fsanitize=undefined
endif
endif
example$(EXTENSION): munit.h munit.c example.c
$(CC) $(CFLAGS) -o $@ munit.c example.c
test:
$(TEST_ENV) ./example$(EXTENSION)
clean:
rm -f example$(EXTENSION)
all: example$(EXTENSION)

54
munit/README.md Normal file
View File

@@ -0,0 +1,54 @@
# µnit
µnit is a small but full-featured unit testing framework for C. It has
no dependencies (beyond libc), is permissively licensed (MIT), and is
easy to include into any project.
For more information, see
[the µnit web site](https://nemequ.github.io/munit).
[![Build status](https://travis-ci.org/nemequ/munit.svg?branch=master)](https://travis-ci.org/nemequ/munit)
[![Windows build status](https://ci.appveyor.com/api/projects/status/db515g5ifcwjohq7/branch/master?svg=true)](https://ci.appveyor.com/project/quixdb/munit/branch/master)
## Features
Features µnit currently includes include:
* Handy assertion macros which make for nice error messages.
* Reproducible cross-platform random number generation, including
support for supplying a seed via CLI.
* Timing of both wall-clock and CPU time.
* Parameterized tests.
* Nested test suites.
* Flexible CLI.
* Forking
([except on Windows](https://github.com/nemequ/munit/issues/2)).
* Hiding output of successful tests.
Features µnit does not currently include, but some day may include
(a.k.a., if you file a PR…), include:
* [TAP](http://testanything.org/) support; feel free to discuss in
[issue #1](https://github.com/nemequ/munit/issues/1)
### Include into your project with meson
In your `subprojects` folder put a `munit.wrap` file containing:
```
[wrap-git]
directory=munit
url=https://github.com/nemequ/munit/
revision=head
```
Then you can use a subproject fallback when you include munit as a
dependency to your project: `dependency('munit', fallback: ['munit', 'munit_dep'])`
## Documentation
See [the µnit web site](https://nemequ.github.io/munit).
Additionally, there is a heavily-commented
[example.c](https://github.com/nemequ/munit/blob/master/example.c) in
the repository.

351
munit/example.c Normal file
View File

@@ -0,0 +1,351 @@
/* Example file for using µnit.
*
* µnit is MIT-licensed, but for this file and this file alone:
*
* To the extent possible under law, the author(s) of this file have
* waived all copyright and related or neighboring rights to this
* work. See <https://creativecommons.org/publicdomain/zero/1.0/> for
* details.
*********************************************************************/
#include "munit.h"
/* This is just to disable an MSVC warning about conditional
* expressions being constant, which you shouldn't have to do for your
* code. It's only here because we want to be able to do silly things
* like assert that 0 != 1 for our demo. */
#if defined(_MSC_VER)
#pragma warning(disable: 4127)
#endif
/* Tests are functions that return void, and take a single void*
* parameter. We'll get to what that parameter is later. */
static MunitResult
test_compare(const MunitParameter params[], void* data) {
/* We'll use these later */
const unsigned char val_uchar = 'b';
const short val_short = 1729;
double pi = 3.141592654;
char* stewardesses = "stewardesses";
char* most_fun_word_to_type;
/* These are just to silence compiler warnings about the parameters
* being unused. */
(void) params;
(void) data;
/* Let's start with the basics. */
munit_assert(0 != 1);
/* There is also the more verbose, though slightly more descriptive
munit_assert_true/false: */
munit_assert_false(0);
/* You can also call munit_error and munit_errorf yourself. We
* won't do it is used to indicate a failure, but here is what it
* would look like: */
/* munit_error("FAIL"); */
/* munit_errorf("Goodbye, cruel %s", "world"); */
/* There are macros for comparing lots of types. */
munit_assert_char('a', ==, 'a');
/* Sure, you could just assert('a' == 'a'), but if you did that, a
* failed assertion would just say something like "assertion failed:
* val_uchar == 'b'". µnit will tell you the actual values, so a
* failure here would result in something like "assertion failed:
* val_uchar == 'b' ('X' == 'b')." */
munit_assert_uchar(val_uchar, ==, 'b');
/* Obviously we can handle values larger than 'char' and 'uchar'.
* There are versions for char, short, int, long, long long,
* int8/16/32/64_t, as well as the unsigned versions of them all. */
munit_assert_short(42, <, val_short);
/* There is also support for size_t.
*
* The longest word in English without repeating any letters is
* "uncopyrightables", which has uncopyrightable (and
* dermatoglyphics, which is the study of fingerprints) beat by a
* character */
munit_assert_size(strlen("uncopyrightables"), >, strlen("dermatoglyphics"));
/* Of course there is also support for doubles and floats. */
munit_assert_double(pi, ==, 3.141592654);
/* If you want to compare two doubles for equality, you might want
* to consider using munit_assert_double_equal. It compares two
* doubles for equality within a precison of 1.0 x 10^-(precision).
* Note that precision (the third argument to the macro) needs to be
* fully evaluated to an integer by the preprocessor so µnit doesn't
* have to depend pow, which is often in libm not libc. */
munit_assert_double_equal(3.141592654, 3.141592653589793, 9);
/* And if you want to check strings for equality (or inequality),
* there is munit_assert_string_equal/not_equal.
*
* "stewardesses" is the longest word you can type on a QWERTY
* keyboard with only one hand, which makes it loads of fun to type.
* If I'm going to have to type a string repeatedly, let's make it a
* good one! */
munit_assert_string_equal(stewardesses, "stewardesses");
/* A personal favorite macro which is fantastic if you're working
* with binary data, is the one which naïvely checks two blobs of
* memory for equality. If this fails it will tell you the offset
* of the first differing byte. */
munit_assert_memory_equal(7, stewardesses, "steward");
/* You can also make sure that two blobs differ *somewhere*: */
munit_assert_memory_not_equal(8, stewardesses, "steward");
/* There are equal/not_equal macros for pointers, too: */
most_fun_word_to_type = stewardesses;
munit_assert_ptr_equal(most_fun_word_to_type, stewardesses);
/* And null/not_null */
munit_assert_null(NULL);
munit_assert_not_null(most_fun_word_to_type);
/* Lets verify that the data parameter is what we expected. We'll
* see where this comes from in a bit.
*
* Note that the casting isn't usually required; if you give this
* function a real pointer (instead of a number like 0xdeadbeef) it
* would work as expected. */
munit_assert_ptr_equal(data, (void*)(uintptr_t)0xdeadbeef);
return MUNIT_OK;
}
static MunitResult
test_rand(const MunitParameter params[], void* user_data) {
int random_int;
double random_dbl;
munit_uint8_t data[5];
(void) params;
(void) user_data;
/* One thing missing from a lot of unit testing frameworks is a
* random number generator. You can't just use srand/rand because
* the implementation varies across different platforms, and it's
* important to be able to look at the seed used in a failing test
* to see if you can reproduce it. Some randomness is a fantastic
* thing to have in your tests, I don't know why more people don't
* do it...
*
* µnit's PRNG is re-seeded with the same value for each iteration
* of each test. The seed is retrieved from the MUNIT_SEED
* envirnment variable or, if none is provided, one will be
* (pseudo-)randomly generated. */
/* If you need an integer in a given range */
random_int = munit_rand_int_range(128, 4096);
munit_assert_int(random_int, >=, 128);
munit_assert_int(random_int, <=, 4096);
/* Or maybe you want a double, between 0 and 1: */
random_dbl = munit_rand_double();
munit_assert_double(random_dbl, >=, 0.0);
munit_assert_double(random_dbl, <=, 1.0);
/* Of course, you want to be able to reproduce bugs discovered
* during testing, so every time the tests are run they print the
* random seed used. When you want to reproduce a result, just put
* that random seed in the MUNIT_SEED environment variable; it even
* works on different platforms.
*
* If you want this to pass, use 0xdeadbeef as the random seed and
* uncomment the next line of code. Note that the PRNG is not
* re-seeded between iterations of the same test, so this will only
* work on the first iteration. */
/* munit_assert_uint32(munit_rand_uint32(), ==, 1306447409); */
/* You can also get blobs of random memory: */
munit_rand_memory(sizeof(data), data);
return MUNIT_OK;
}
/* This test case shows how to accept parameters. We'll see how to
* specify them soon.
*
* By default, every possible variation of a parameterized test is
* run, but you can specify parameters manually if you want to only
* run specific test(s), or you can pass the --single argument to the
* CLI to have the harness simply choose one variation at random
* instead of running them all. */
static MunitResult
test_parameters(const MunitParameter params[], void* user_data) {
const char* foo;
const char* bar;
(void) user_data;
/* The "foo" parameter is specified as one of the following values:
* "one", "two", or "three". */
foo = munit_parameters_get(params, "foo");
/* Similarly, "bar" is one of "four", "five", or "six". */
bar = munit_parameters_get(params, "bar");
/* "baz" is a bit more complicated. We don't actually specify a
* list of valid values, so by default NULL is passed. However, the
* CLI will accept any value. This is a good way to have a value
* that is usually selected randomly by the test, but can be
* overridden on the command line if desired. */
/* const char* baz = munit_parameters_get(params, "baz"); */
/* Notice that we're returning MUNIT_FAIL instead of writing an
* error message. Error messages are generally preferable, since
* they make it easier to diagnose the issue, but this is an
* option.
*
* Possible values are:
* - MUNIT_OK: Sucess
* - MUNIT_FAIL: Failure
* - MUNIT_SKIP: The test was skipped; usually this happens when a
* particular feature isn't in use. For example, if you're
* writing a test which uses a Wayland-only feature, but your
* application is running on X11.
* - MUNIT_ERROR: The test failed, but not because of anything you
* wanted to test. For example, maybe your test downloads a
* remote resource and tries to parse it, but the network was
* down.
*/
if (strcmp(foo, "one") != 0 &&
strcmp(foo, "two") != 0 &&
strcmp(foo, "three") != 0)
return MUNIT_FAIL;
if (strcmp(bar, "red") != 0 &&
strcmp(bar, "green") != 0 &&
strcmp(bar, "blue") != 0)
return MUNIT_FAIL;
return MUNIT_OK;
}
/* The setup function, if you provide one, for a test will be run
* before the test, and the return value will be passed as the sole
* parameter to the test function. */
static void*
test_compare_setup(const MunitParameter params[], void* user_data) {
(void) params;
munit_assert_string_equal(user_data, "µnit");
return (void*) (uintptr_t) 0xdeadbeef;
}
/* To clean up after a test, you can use a tear down function. The
* fixture argument is the value returned by the setup function
* above. */
static void
test_compare_tear_down(void* fixture) {
munit_assert_ptr_equal(fixture, (void*)(uintptr_t)0xdeadbeef);
}
static char* foo_params[] = {
(char*) "one", (char*) "two", (char*) "three", NULL
};
static char* bar_params[] = {
(char*) "red", (char*) "green", (char*) "blue", NULL
};
static MunitParameterEnum test_params[] = {
{ (char*) "foo", foo_params },
{ (char*) "bar", bar_params },
{ (char*) "baz", NULL },
{ NULL, NULL },
};
/* Creating a test suite is pretty simple. First, you'll need an
* array of tests: */
static MunitTest test_suite_tests[] = {
{
/* The name is just a unique human-readable way to identify the
* test. You can use it to run a specific test if you want, but
* usually it's mostly decorative. */
(char*) "/example/compare",
/* You probably won't be surprised to learn that the tests are
* functions. */
test_compare,
/* If you want, you can supply a function to set up a fixture. If
* you supply NULL, the user_data parameter from munit_suite_main
* will be used directly. If, however, you provide a callback
* here the user_data parameter will be passed to this callback,
* and the return value from this callback will be passed to the
* test function.
*
* For our example we don't really need a fixture, but lets
* provide one anyways. */
test_compare_setup,
/* If you passed a callback for the fixture setup function, you
* may want to pass a corresponding callback here to reverse the
* operation. */
test_compare_tear_down,
/* Finally, there is a bitmask for options you can pass here. You
* can provide either MUNIT_TEST_OPTION_NONE or 0 here to use the
* defaults. */
MUNIT_TEST_OPTION_NONE,
NULL
},
/* Usually this is written in a much more compact format; all these
* comments kind of ruin that, though. Here is how you'll usually
* see entries written: */
{ (char*) "/example/rand", test_rand, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
/* To tell the test runner when the array is over, just add a NULL
* entry at the end. */
{ (char*) "/example/parameters", test_parameters, NULL, NULL, MUNIT_TEST_OPTION_NONE, test_params },
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
/* If you wanted to have your test suite run other test suites you
* could declare an array of them. Of course each sub-suite can
* contain more suites, etc. */
/* static const MunitSuite other_suites[] = { */
/* { "/second", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE }, */
/* { NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE } */
/* }; */
/* Now we'll actually declare the test suite. You could do this in
* the main function, or on the heap, or whatever you want. */
static const MunitSuite test_suite = {
/* This string will be prepended to all test names in this suite;
* for example, "/example/rand" will become "/µnit/example/rand".
* Note that, while it doesn't really matter for the top-level
* suite, NULL signal the end of an array of tests; you should use
* an empty string ("") instead. */
(char*) "",
/* The first parameter is the array of test suites. */
test_suite_tests,
/* In addition to containing test cases, suites can contain other
* test suites. This isn't necessary in this example, but it can be
* a great help to projects with lots of tests by making it easier
* to spread the tests across many files. This is where you would
* put "other_suites" (which is commented out above). */
NULL,
/* An interesting feature of µnit is that it supports automatically
* running multiple iterations of the tests. This is usually only
* interesting if you make use of the PRNG to randomize your tests
* cases a bit, or if you are doing performance testing and want to
* average multiple runs. 0 is an alias for 1. */
1,
/* Just like MUNIT_TEST_OPTION_NONE, you can provide
* MUNIT_SUITE_OPTION_NONE or 0 to use the default settings. */
MUNIT_SUITE_OPTION_NONE
};
/* This is only necessary for EXIT_SUCCESS and EXIT_FAILURE, which you
* *should* be using but probably aren't (no, zero and non-zero don't
* always mean success and failure). I guess my point is that nothing
* about µnit requires it. */
#include <stdlib.h>
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
/* Finally, we'll actually run our test suite! That second argument
* is the user_data parameter which will be passed either to the
* test or (if provided) the fixture setup function. */
return munit_suite_main(&test_suite, (void*) "µnit", argc, argv);
}

37
munit/meson.build Normal file
View File

@@ -0,0 +1,37 @@
project('munit', 'c')
conf_data = configuration_data()
conf_data.set('version', '0.2.0')
add_project_arguments('-std=c99', language : 'c')
cc = meson.get_compiler('c')
root_include = include_directories('.')
munit = library('munit',
['munit.c'],
install: meson.is_subproject())
if meson.is_subproject()
munit_dep = declare_dependency(
include_directories : root_include,
link_with : munit)
else
# standalone install
install_headers('munit.h')
pkg = import('pkgconfig')
pkg.generate(name: 'munit',
description: 'µnit Testing Library for C',
version: conf_data.get('version'),
libraries: munit)
# compile the demo project
munit_example_src = files('example.c')
munit_example = executable('munit_example', munit_example_src,
include_directories: root_include,
link_with: munit)
test('munit example test', munit_example)
endif

2055
munit/munit.c Normal file

File diff suppressed because it is too large Load Diff

535
munit/munit.h Normal file
View File

@@ -0,0 +1,535 @@
/* µnit Testing Framework
* Copyright (c) 2013-2017 Evan Nemerson <evan@nemerson.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#if !defined(MUNIT_H)
#define MUNIT_H
#include <stdarg.h>
#include <stdlib.h>
#define MUNIT_VERSION(major, minor, revision) \
(((major) << 16) | ((minor) << 8) | (revision))
#define MUNIT_CURRENT_VERSION MUNIT_VERSION(0, 4, 1)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
# define munit_int8_t __int8
# define munit_uint8_t unsigned __int8
# define munit_int16_t __int16
# define munit_uint16_t unsigned __int16
# define munit_int32_t __int32
# define munit_uint32_t unsigned __int32
# define munit_int64_t __int64
# define munit_uint64_t unsigned __int64
#else
# include <stdint.h>
# define munit_int8_t int8_t
# define munit_uint8_t uint8_t
# define munit_int16_t int16_t
# define munit_uint16_t uint16_t
# define munit_int32_t int32_t
# define munit_uint32_t uint32_t
# define munit_int64_t int64_t
# define munit_uint64_t uint64_t
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1800)
# if !defined(PRIi8)
# define PRIi8 "i"
# endif
# if !defined(PRIi16)
# define PRIi16 "i"
# endif
# if !defined(PRIi32)
# define PRIi32 "i"
# endif
# if !defined(PRIi64)
# define PRIi64 "I64i"
# endif
# if !defined(PRId8)
# define PRId8 "d"
# endif
# if !defined(PRId16)
# define PRId16 "d"
# endif
# if !defined(PRId32)
# define PRId32 "d"
# endif
# if !defined(PRId64)
# define PRId64 "I64d"
# endif
# if !defined(PRIx8)
# define PRIx8 "x"
# endif
# if !defined(PRIx16)
# define PRIx16 "x"
# endif
# if !defined(PRIx32)
# define PRIx32 "x"
# endif
# if !defined(PRIx64)
# define PRIx64 "I64x"
# endif
# if !defined(PRIu8)
# define PRIu8 "u"
# endif
# if !defined(PRIu16)
# define PRIu16 "u"
# endif
# if !defined(PRIu32)
# define PRIu32 "u"
# endif
# if !defined(PRIu64)
# define PRIu64 "I64u"
# endif
#else
# include <inttypes.h>
#endif
#if !defined(munit_bool)
# if defined(bool)
# define munit_bool bool
# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define munit_bool _Bool
# else
# define munit_bool int
# endif
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__GNUC__)
# define MUNIT_LIKELY(expr) (__builtin_expect ((expr), 1))
# define MUNIT_UNLIKELY(expr) (__builtin_expect ((expr), 0))
# define MUNIT_UNUSED __attribute__((__unused__))
#else
# define MUNIT_LIKELY(expr) (expr)
# define MUNIT_UNLIKELY(expr) (expr)
# define MUNIT_UNUSED
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__PGI)
# define MUNIT_ARRAY_PARAM(name) name
#else
# define MUNIT_ARRAY_PARAM(name)
#endif
#if !defined(_WIN32)
# define MUNIT_SIZE_MODIFIER "z"
# define MUNIT_CHAR_MODIFIER "hh"
# define MUNIT_SHORT_MODIFIER "h"
#else
# if defined(_M_X64) || defined(__amd64__)
# define MUNIT_SIZE_MODIFIER "I64"
# else
# define MUNIT_SIZE_MODIFIER ""
# endif
# define MUNIT_CHAR_MODIFIER ""
# define MUNIT_SHORT_MODIFIER ""
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
# define MUNIT_NO_RETURN _Noreturn
#elif defined(__GNUC__)
# define MUNIT_NO_RETURN __attribute__((__noreturn__))
#elif defined(_MSC_VER)
# define MUNIT_NO_RETURN __declspec(noreturn)
#else
# define MUNIT_NO_RETURN
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
# define MUNIT_PUSH_DISABLE_MSVC_C4127_ __pragma(warning(push)) __pragma(warning(disable:4127))
# define MUNIT_POP_DISABLE_MSVC_C4127_ __pragma(warning(pop))
#else
# define MUNIT_PUSH_DISABLE_MSVC_C4127_
# define MUNIT_POP_DISABLE_MSVC_C4127_
#endif
typedef enum {
MUNIT_LOG_DEBUG,
MUNIT_LOG_INFO,
MUNIT_LOG_WARNING,
MUNIT_LOG_ERROR
} MunitLogLevel;
#if defined(__GNUC__) && !defined(__MINGW32__)
# define MUNIT_PRINTF(string_index, first_to_check) __attribute__((format (printf, string_index, first_to_check)))
#else
# define MUNIT_PRINTF(string_index, first_to_check)
#endif
MUNIT_PRINTF(4, 5)
void munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...);
#define munit_logf(level, format, ...) \
munit_logf_ex(level, __FILE__, __LINE__, format, __VA_ARGS__)
#define munit_log(level, msg) \
munit_logf(level, "%s", msg)
MUNIT_NO_RETURN
MUNIT_PRINTF(3, 4)
void munit_errorf_ex(const char* filename, int line, const char* format, ...);
#define munit_errorf(format, ...) \
munit_errorf_ex(__FILE__, __LINE__, format, __VA_ARGS__)
#define munit_error(msg) \
munit_errorf("%s", msg)
#define munit_assert(expr) \
do { \
if (!MUNIT_LIKELY(expr)) { \
munit_error("assertion failed: " #expr); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_true(expr) \
do { \
if (!MUNIT_LIKELY(expr)) { \
munit_error("assertion failed: " #expr " is not true"); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_false(expr) \
do { \
if (!MUNIT_LIKELY(!(expr))) { \
munit_error("assertion failed: " #expr " is not false"); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
do { \
T munit_tmp_a_ = (a); \
T munit_tmp_b_ = (b); \
if (!(munit_tmp_a_ op munit_tmp_b_)) { \
munit_errorf("assertion failed: %s %s %s (" prefix "%" fmt suffix " %s " prefix "%" fmt suffix ")", \
#a, #op, #b, munit_tmp_a_, #op, munit_tmp_b_); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_type(T, fmt, a, op, b) \
munit_assert_type_full("", "", T, fmt, a, op, b)
#define munit_assert_char(a, op, b) \
munit_assert_type_full("'\\x", "'", char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b)
#define munit_assert_uchar(a, op, b) \
munit_assert_type_full("'\\x", "'", unsigned char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b)
#define munit_assert_short(a, op, b) \
munit_assert_type(short, MUNIT_SHORT_MODIFIER "d", a, op, b)
#define munit_assert_ushort(a, op, b) \
munit_assert_type(unsigned short, MUNIT_SHORT_MODIFIER "u", a, op, b)
#define munit_assert_int(a, op, b) \
munit_assert_type(int, "d", a, op, b)
#define munit_assert_uint(a, op, b) \
munit_assert_type(unsigned int, "u", a, op, b)
#define munit_assert_long(a, op, b) \
munit_assert_type(long int, "ld", a, op, b)
#define munit_assert_ulong(a, op, b) \
munit_assert_type(unsigned long int, "lu", a, op, b)
#define munit_assert_llong(a, op, b) \
munit_assert_type(long long int, "lld", a, op, b)
#define munit_assert_ullong(a, op, b) \
munit_assert_type(unsigned long long int, "llu", a, op, b)
#define munit_assert_size(a, op, b) \
munit_assert_type(size_t, MUNIT_SIZE_MODIFIER "u", a, op, b)
#define munit_assert_float(a, op, b) \
munit_assert_type(float, "f", a, op, b)
#define munit_assert_double(a, op, b) \
munit_assert_type(double, "g", a, op, b)
#define munit_assert_ptr(a, op, b) \
munit_assert_type(const void*, "p", a, op, b)
#define munit_assert_int8(a, op, b) \
munit_assert_type(munit_int8_t, PRIi8, a, op, b)
#define munit_assert_uint8(a, op, b) \
munit_assert_type(munit_uint8_t, PRIu8, a, op, b)
#define munit_assert_int16(a, op, b) \
munit_assert_type(munit_int16_t, PRIi16, a, op, b)
#define munit_assert_uint16(a, op, b) \
munit_assert_type(munit_uint16_t, PRIu16, a, op, b)
#define munit_assert_int32(a, op, b) \
munit_assert_type(munit_int32_t, PRIi32, a, op, b)
#define munit_assert_uint32(a, op, b) \
munit_assert_type(munit_uint32_t, PRIu32, a, op, b)
#define munit_assert_int64(a, op, b) \
munit_assert_type(munit_int64_t, PRIi64, a, op, b)
#define munit_assert_uint64(a, op, b) \
munit_assert_type(munit_uint64_t, PRIu64, a, op, b)
#define munit_assert_double_equal(a, b, precision) \
do { \
const double munit_tmp_a_ = (a); \
const double munit_tmp_b_ = (b); \
const double munit_tmp_diff_ = ((munit_tmp_a_ - munit_tmp_b_) < 0) ? \
-(munit_tmp_a_ - munit_tmp_b_) : \
(munit_tmp_a_ - munit_tmp_b_); \
if (MUNIT_UNLIKELY(munit_tmp_diff_ > 1e-##precision)) { \
munit_errorf("assertion failed: %s == %s (%0." #precision "g == %0." #precision "g)", \
#a, #b, munit_tmp_a_, munit_tmp_b_); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#include <string.h>
#define munit_assert_string_equal(a, b) \
do { \
const char* munit_tmp_a_ = a; \
const char* munit_tmp_b_ = b; \
if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) != 0)) { \
munit_errorf("assertion failed: string %s == %s (\"%s\" == \"%s\")", \
#a, #b, munit_tmp_a_, munit_tmp_b_); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_string_not_equal(a, b) \
do { \
const char* munit_tmp_a_ = a; \
const char* munit_tmp_b_ = b; \
if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) == 0)) { \
munit_errorf("assertion failed: string %s != %s (\"%s\" == \"%s\")", \
#a, #b, munit_tmp_a_, munit_tmp_b_); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_memory_equal(size, a, b) \
do { \
const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \
const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \
const size_t munit_tmp_size_ = (size); \
if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) != 0) { \
size_t munit_tmp_pos_; \
for (munit_tmp_pos_ = 0 ; munit_tmp_pos_ < munit_tmp_size_ ; munit_tmp_pos_++) { \
if (munit_tmp_a_[munit_tmp_pos_] != munit_tmp_b_[munit_tmp_pos_]) { \
munit_errorf("assertion failed: memory %s == %s, at offset %" MUNIT_SIZE_MODIFIER "u", \
#a, #b, munit_tmp_pos_); \
break; \
} \
} \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_memory_not_equal(size, a, b) \
do { \
const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \
const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \
const size_t munit_tmp_size_ = (size); \
if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) == 0) { \
munit_errorf("assertion failed: memory %s != %s (%zu bytes)", \
#a, #b, munit_tmp_size_); \
} \
MUNIT_PUSH_DISABLE_MSVC_C4127_ \
} while (0) \
MUNIT_POP_DISABLE_MSVC_C4127_
#define munit_assert_ptr_equal(a, b) \
munit_assert_ptr(a, ==, b)
#define munit_assert_ptr_not_equal(a, b) \
munit_assert_ptr(a, !=, b)
#define munit_assert_null(ptr) \
munit_assert_ptr(ptr, ==, NULL)
#define munit_assert_not_null(ptr) \
munit_assert_ptr(ptr, !=, NULL)
#define munit_assert_ptr_null(ptr) \
munit_assert_ptr(ptr, ==, NULL)
#define munit_assert_ptr_not_null(ptr) \
munit_assert_ptr(ptr, !=, NULL)
/*** Memory allocation ***/
void* munit_malloc_ex(const char* filename, int line, size_t size);
#define munit_malloc(size) \
munit_malloc_ex(__FILE__, __LINE__, (size))
#define munit_new(type) \
((type*) munit_malloc(sizeof(type)))
#define munit_calloc(nmemb, size) \
munit_malloc((nmemb) * (size))
#define munit_newa(type, nmemb) \
((type*) munit_calloc((nmemb), sizeof(type)))
/*** Random number generation ***/
void munit_rand_seed(munit_uint32_t seed);
munit_uint32_t munit_rand_uint32(void);
int munit_rand_int_range(int min, int max);
double munit_rand_double(void);
void munit_rand_memory(size_t size, munit_uint8_t buffer[MUNIT_ARRAY_PARAM(size)]);
/*** Tests and Suites ***/
typedef enum {
/* Test successful */
MUNIT_OK,
/* Test failed */
MUNIT_FAIL,
/* Test was skipped */
MUNIT_SKIP,
/* Test failed due to circumstances not intended to be tested
* (things like network errors, invalid parameter value, failure to
* allocate memory in the test harness, etc.). */
MUNIT_ERROR
} MunitResult;
typedef struct {
char* name;
char** values;
} MunitParameterEnum;
typedef struct {
char* name;
char* value;
} MunitParameter;
const char* munit_parameters_get(const MunitParameter params[], const char* key);
typedef enum {
MUNIT_TEST_OPTION_NONE = 0,
MUNIT_TEST_OPTION_SINGLE_ITERATION = 1 << 0,
MUNIT_TEST_OPTION_TODO = 1 << 1
} MunitTestOptions;
typedef MunitResult (* MunitTestFunc)(const MunitParameter params[], void* user_data_or_fixture);
typedef void* (* MunitTestSetup)(const MunitParameter params[], void* user_data);
typedef void (* MunitTestTearDown)(void* fixture);
typedef struct {
char* name;
MunitTestFunc test;
MunitTestSetup setup;
MunitTestTearDown tear_down;
MunitTestOptions options;
MunitParameterEnum* parameters;
} MunitTest;
typedef enum {
MUNIT_SUITE_OPTION_NONE = 0
} MunitSuiteOptions;
typedef struct MunitSuite_ MunitSuite;
struct MunitSuite_ {
char* prefix;
MunitTest* tests;
MunitSuite* suites;
unsigned int iterations;
MunitSuiteOptions options;
};
int munit_suite_main(const MunitSuite* suite, void* user_data, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);
/* Note: I'm not very happy with this API; it's likely to change if I
* figure out something better. Suggestions welcome. */
typedef struct MunitArgument_ MunitArgument;
struct MunitArgument_ {
char* name;
munit_bool (* parse_argument)(const MunitSuite* suite, void* user_data, int* arg, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);
void (* write_help)(const MunitArgument* argument, void* user_data);
};
int munit_suite_main_custom(const MunitSuite* suite,
void* user_data,
int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)],
const MunitArgument arguments[]);
#if defined(MUNIT_ENABLE_ASSERT_ALIASES)
#define assert_true(expr) munit_assert_true(expr)
#define assert_false(expr) munit_assert_false(expr)
#define assert_char(a, op, b) munit_assert_char(a, op, b)
#define assert_uchar(a, op, b) munit_assert_uchar(a, op, b)
#define assert_short(a, op, b) munit_assert_short(a, op, b)
#define assert_ushort(a, op, b) munit_assert_ushort(a, op, b)
#define assert_int(a, op, b) munit_assert_int(a, op, b)
#define assert_uint(a, op, b) munit_assert_uint(a, op, b)
#define assert_long(a, op, b) munit_assert_long(a, op, b)
#define assert_ulong(a, op, b) munit_assert_ulong(a, op, b)
#define assert_llong(a, op, b) munit_assert_llong(a, op, b)
#define assert_ullong(a, op, b) munit_assert_ullong(a, op, b)
#define assert_size(a, op, b) munit_assert_size(a, op, b)
#define assert_float(a, op, b) munit_assert_float(a, op, b)
#define assert_double(a, op, b) munit_assert_double(a, op, b)
#define assert_ptr(a, op, b) munit_assert_ptr(a, op, b)
#define assert_int8(a, op, b) munit_assert_int8(a, op, b)
#define assert_uint8(a, op, b) munit_assert_uint8(a, op, b)
#define assert_int16(a, op, b) munit_assert_int16(a, op, b)
#define assert_uint16(a, op, b) munit_assert_uint16(a, op, b)
#define assert_int32(a, op, b) munit_assert_int32(a, op, b)
#define assert_uint32(a, op, b) munit_assert_uint32(a, op, b)
#define assert_int64(a, op, b) munit_assert_int64(a, op, b)
#define assert_uint64(a, op, b) munit_assert_uint64(a, op, b)
#define assert_double_equal(a, b, precision) munit_assert_double_equal(a, b, precision)
#define assert_string_equal(a, b) munit_assert_string_equal(a, b)
#define assert_string_not_equal(a, b) munit_assert_string_not_equal(a, b)
#define assert_memory_equal(size, a, b) munit_assert_memory_equal(size, a, b)
#define assert_memory_not_equal(size, a, b) munit_assert_memory_not_equal(size, a, b)
#define assert_ptr_equal(a, b) munit_assert_ptr_equal(a, b)
#define assert_ptr_not_equal(a, b) munit_assert_ptr_not_equal(a, b)
#define assert_ptr_null(ptr) munit_assert_null_equal(ptr)
#define assert_ptr_not_null(ptr) munit_assert_not_null(ptr)
#define assert_null(ptr) munit_assert_null(ptr)
#define assert_not_null(ptr) munit_assert_not_null(ptr)
#endif /* defined(MUNIT_ENABLE_ASSERT_ALIASES) */
#if defined(__cplusplus)
}
#endif
#endif /* !defined(MUNIT_H) */
#if defined(MUNIT_ENABLE_ASSERT_ALIASES)
# if defined(assert)
# undef assert
# endif
# define assert(expr) munit_assert(expr)
#endif

446
munit/tags Normal file
View File

@@ -0,0 +1,446 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
AGGRESSIVE_WARNINGS ./Makefile /^AGGRESSIVE_WARNINGS=n$/;" m
ASAN ./Makefile /^ASAN:=n$/;" m
ATOMIC_UINT32_INIT ./munit.c 798;" d file:
ATOMIC_UINT32_INIT ./munit.c 802;" d file:
ATOMIC_UINT32_INIT ./munit.c 805;" d file:
ATOMIC_UINT32_INIT ./munit.c 808;" d file:
ATOMIC_UINT32_INIT ./munit.c 811;" d file:
ATOMIC_UINT32_T ./munit.c 797;" d file:
ATOMIC_UINT32_T ./munit.c 801;" d file:
ATOMIC_UINT32_T ./munit.c 804;" d file:
ATOMIC_UINT32_T ./munit.c 807;" d file:
ATOMIC_UINT32_T ./munit.c 810;" d file:
CFLAGS ./Makefile /^CFLAGS:=$/;" m
CSTD ./Makefile /^CSTD:=99$/;" m
EXTENSION ./Makefile /^EXTENSION:=$/;" m
HAVE_CLANG_ATOMICS ./munit.c 784;" d file:
HAVE_CLANG_ATOMICS ./munit.c 792;" d file:
HAVE_STDATOMIC ./munit.c 781;" d file:
HAVE_STDATOMIC ./munit.c 790;" d file:
MUNIT_ARRAY_PARAM ./munit.h 135;" d
MUNIT_ARRAY_PARAM ./munit.h 137;" d
MUNIT_CHAR_MODIFIER ./munit.h 142;" d
MUNIT_CHAR_MODIFIER ./munit.h 150;" d
MUNIT_CURRENT_VERSION ./munit.h 34;" d
MUNIT_ENABLE_TIMING ./munit.c 51;" d file:
MUNIT_ERROR ./munit.h /^ MUNIT_ERROR$/;" e enum:__anon4
MUNIT_FAIL ./munit.h /^ MUNIT_FAIL,$/;" e enum:__anon4
MUNIT_H ./munit.h 26;" d
MUNIT_LIKELY ./munit.h 125;" d
MUNIT_LIKELY ./munit.h 129;" d
MUNIT_LOG_DEBUG ./munit.h /^ MUNIT_LOG_DEBUG,$/;" e enum:__anon3
MUNIT_LOG_ERROR ./munit.h /^ MUNIT_LOG_ERROR$/;" e enum:__anon3
MUNIT_LOG_INFO ./munit.h /^ MUNIT_LOG_INFO,$/;" e enum:__anon3
MUNIT_LOG_WARNING ./munit.h /^ MUNIT_LOG_WARNING,$/;" e enum:__anon3
MUNIT_NL_LANGINFO ./munit.c 99;" d file:
MUNIT_NO_BUFFER ./munit.c 143;" d file:
MUNIT_NO_FORK ./munit.c 139;" d file:
MUNIT_NO_RETURN ./munit.h 155;" d
MUNIT_NO_RETURN ./munit.h 157;" d
MUNIT_NO_RETURN ./munit.h 159;" d
MUNIT_NO_RETURN ./munit.h 161;" d
MUNIT_OK ./munit.h /^ MUNIT_OK,$/;" e enum:__anon4
MUNIT_OUTPUT_FILE ./munit.c 31;" d file:
MUNIT_POP_DISABLE_MSVC_C4127_ ./munit.h 166;" d
MUNIT_POP_DISABLE_MSVC_C4127_ ./munit.h 169;" d
MUNIT_PRINTF ./munit.h 180;" d
MUNIT_PRINTF ./munit.h 182;" d
MUNIT_PRNG_INCREMENT ./munit.c 883;" d file:
MUNIT_PRNG_MULTIPLIER ./munit.c 882;" d file:
MUNIT_PUSH_DISABLE_MSVC_C4127_ ./munit.h 165;" d
MUNIT_PUSH_DISABLE_MSVC_C4127_ ./munit.h 168;" d
MUNIT_RESULT_STRING_ERROR ./munit.c 1236;" d file:
MUNIT_RESULT_STRING_ERROR ./munit.c 1242;" d file:
MUNIT_RESULT_STRING_FAIL ./munit.c 1235;" d file:
MUNIT_RESULT_STRING_FAIL ./munit.c 1241;" d file:
MUNIT_RESULT_STRING_OK ./munit.c 1233;" d file:
MUNIT_RESULT_STRING_OK ./munit.c 1239;" d file:
MUNIT_RESULT_STRING_SKIP ./munit.c 1234;" d file:
MUNIT_RESULT_STRING_SKIP ./munit.c 1240;" d file:
MUNIT_RESULT_STRING_TODO ./munit.c 1237;" d file:
MUNIT_RESULT_STRING_TODO ./munit.c 1243;" d file:
MUNIT_SHORT_MODIFIER ./munit.h 143;" d
MUNIT_SHORT_MODIFIER ./munit.h 151;" d
MUNIT_SIZE_MODIFIER ./munit.h 141;" d
MUNIT_SIZE_MODIFIER ./munit.h 146;" d
MUNIT_SIZE_MODIFIER ./munit.h 148;" d
MUNIT_SKIP ./munit.h /^ MUNIT_SKIP,$/;" e enum:__anon4
MUNIT_STRERROR_LEN ./munit.c 250;" d file:
MUNIT_STRINGIFY ./munit.c 120;" d file:
MUNIT_SUITE_OPTION_NONE ./munit.h /^ MUNIT_SUITE_OPTION_NONE = 0$/;" e enum:__anon9
MUNIT_TEST_NAME_LEN ./munit.c 45;" d file:
MUNIT_TEST_OPTION_NONE ./munit.h /^ MUNIT_TEST_OPTION_NONE = 0,$/;" e enum:__anon7
MUNIT_TEST_OPTION_SINGLE_ITERATION ./munit.h /^ MUNIT_TEST_OPTION_SINGLE_ITERATION = 1 << 0,$/;" e enum:__anon7
MUNIT_TEST_OPTION_TODO ./munit.h /^ MUNIT_TEST_OPTION_TODO = 1 << 1$/;" e enum:__anon7
MUNIT_TEST_TIME_FORMAT ./munit.c 39;" d file:
MUNIT_THREAD_LOCAL ./munit.c 124;" d file:
MUNIT_THREAD_LOCAL ./munit.c 126;" d file:
MUNIT_THREAD_LOCAL ./munit.c 128;" d file:
MUNIT_UNLIKELY ./munit.h 126;" d
MUNIT_UNLIKELY ./munit.h 130;" d
MUNIT_UNUSED ./munit.h 127;" d
MUNIT_UNUSED ./munit.h 131;" d
MUNIT_VERSION ./munit.h 31;" d
MUNIT_XSTRINGIFY ./munit.c 121;" d file:
MunitArgument ./munit.h /^typedef struct MunitArgument_ MunitArgument;$/;" t typeref:struct:MunitArgument_
MunitArgument_ ./munit.h /^struct MunitArgument_ {$/;" s
MunitArgument_::name ./munit.h /^ char* name;$/;" m struct:MunitArgument_ access:public
MunitArgument_::parse_argument ./munit.h /^ munit_bool (* parse_argument)(const MunitSuite* suite, void* user_data, int* arg, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);$/;" m struct:MunitArgument_ access:public
MunitArgument_::write_help ./munit.h /^ void (* write_help)(const MunitArgument* argument, void* user_data);$/;" m struct:MunitArgument_ access:public
MunitLogLevel ./munit.h /^} MunitLogLevel;$/;" t typeref:enum:__anon3
MunitParameter ./munit.h /^} MunitParameter;$/;" t typeref:struct:__anon6
MunitParameterEnum ./munit.h /^} MunitParameterEnum;$/;" t typeref:struct:__anon5
MunitReport ./munit.c /^} MunitReport;$/;" t typeref:struct:__anon1 file:
MunitResult ./munit.h /^} MunitResult;$/;" t typeref:enum:__anon4
MunitSuite ./munit.h /^typedef struct MunitSuite_ MunitSuite;$/;" t typeref:struct:MunitSuite_
MunitSuiteOptions ./munit.h /^} MunitSuiteOptions;$/;" t typeref:enum:__anon9
MunitSuite_ ./munit.h /^struct MunitSuite_ {$/;" s
MunitSuite_::iterations ./munit.h /^ unsigned int iterations;$/;" m struct:MunitSuite_ access:public
MunitSuite_::options ./munit.h /^ MunitSuiteOptions options;$/;" m struct:MunitSuite_ access:public
MunitSuite_::prefix ./munit.h /^ char* prefix;$/;" m struct:MunitSuite_ access:public
MunitSuite_::suites ./munit.h /^ MunitSuite* suites;$/;" m struct:MunitSuite_ access:public
MunitSuite_::tests ./munit.h /^ MunitTest* tests;$/;" m struct:MunitSuite_ access:public
MunitTest ./munit.h /^} MunitTest;$/;" t typeref:struct:__anon8
MunitTestFunc ./munit.h /^typedef MunitResult (* MunitTestFunc)(const MunitParameter params[], void* user_data_or_fixture);$/;" t
MunitTestOptions ./munit.h /^} MunitTestOptions;$/;" t typeref:enum:__anon7
MunitTestRunner ./munit.c /^} MunitTestRunner;$/;" t typeref:struct:__anon2 file:
MunitTestSetup ./munit.h /^typedef void* (* MunitTestSetup)(const MunitParameter params[], void* user_data);$/;" t
MunitTestTearDown ./munit.h /^typedef void (* MunitTestTearDown)(void* fixture);$/;" t
OPENMP ./Makefile /^OPENMP:=n$/;" m
PRId16 ./munit.h 74;" d
PRId32 ./munit.h 77;" d
PRId64 ./munit.h 80;" d
PRId8 ./munit.h 71;" d
PRIi16 ./munit.h 62;" d
PRIi32 ./munit.h 65;" d
PRIi64 ./munit.h 68;" d
PRIi8 ./munit.h 59;" d
PRIu16 ./munit.h 98;" d
PRIu32 ./munit.h 101;" d
PRIu64 ./munit.h 104;" d
PRIu8 ./munit.h 95;" d
PRIx16 ./munit.h 86;" d
PRIx32 ./munit.h 89;" d
PRIx64 ./munit.h 92;" d
PRIx8 ./munit.h 83;" d
PSNIP_CLOCK_CLOCK_GETTIME_CPU ./munit.c 424;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_CPU ./munit.c 427;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC ./munit.c 433;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC ./munit.c 436;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC ./munit.c 439;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_WALL ./munit.c 415;" d file:
PSNIP_CLOCK_CLOCK_GETTIME_WALL ./munit.c 418;" d file:
PSNIP_CLOCK_CPU_METHOD ./munit.c 397;" d file:
PSNIP_CLOCK_CPU_METHOD ./munit.c 423;" d file:
PSNIP_CLOCK_CPU_METHOD ./munit.c 426;" d file:
PSNIP_CLOCK_CPU_METHOD ./munit.c 455;" d file:
PSNIP_CLOCK_H ./munit.c 311;" d file:
PSNIP_CLOCK_HAVE_CLOCK_GETTIME ./munit.c 389;" d file:
PSNIP_CLOCK_HAVE_CLOCK_GETTIME ./munit.c 391;" d file:
PSNIP_CLOCK_METHOD_CLOCK ./munit.c 355;" d file:
PSNIP_CLOCK_METHOD_CLOCK_GETTIME ./munit.c 350;" d file:
PSNIP_CLOCK_METHOD_GETPROCESSTIMES ./munit.c 356;" d file:
PSNIP_CLOCK_METHOD_GETRUSAGE ./munit.c 357;" d file:
PSNIP_CLOCK_METHOD_GETSYSTEMTIMEPRECISEASFILETIME ./munit.c 358;" d file:
PSNIP_CLOCK_METHOD_GETTICKCOUNT64 ./munit.c 359;" d file:
PSNIP_CLOCK_METHOD_GETTIMEOFDAY ./munit.c 352;" d file:
PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME ./munit.c 354;" d file:
PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER ./munit.c 353;" d file:
PSNIP_CLOCK_METHOD_TIME ./munit.c 351;" d file:
PSNIP_CLOCK_MONOTONIC_METHOD ./munit.c 400;" d file:
PSNIP_CLOCK_MONOTONIC_METHOD ./munit.c 406;" d file:
PSNIP_CLOCK_MONOTONIC_METHOD ./munit.c 432;" d file:
PSNIP_CLOCK_MONOTONIC_METHOD ./munit.c 435;" d file:
PSNIP_CLOCK_MONOTONIC_METHOD ./munit.c 438;" d file:
PSNIP_CLOCK_NSEC_PER_SEC ./munit.c 514;" d file:
PSNIP_CLOCK_TYPE_CPU ./munit.c /^ PSNIP_CLOCK_TYPE_CPU = 2,$/;" e enum:PsnipClockType file:
PSNIP_CLOCK_TYPE_MONOTONIC ./munit.c /^ PSNIP_CLOCK_TYPE_MONOTONIC = 3$/;" e enum:PsnipClockType file:
PSNIP_CLOCK_TYPE_WALL ./munit.c /^ PSNIP_CLOCK_TYPE_WALL = 1,$/;" e enum:PsnipClockType file:
PSNIP_CLOCK_UNREACHABLE ./munit.c 364;" d file:
PSNIP_CLOCK_UNREACHABLE ./munit.c 366;" d file:
PSNIP_CLOCK_WALL_METHOD ./munit.c 414;" d file:
PSNIP_CLOCK_WALL_METHOD ./munit.c 417;" d file:
PSNIP_CLOCK_WALL_METHOD ./munit.c 446;" d file:
PSNIP_CLOCK_WALL_METHOD ./munit.c 451;" d file:
PSNIP_CLOCK__COMPILER_ATTRIBUTES ./munit.c 319;" d file:
PSNIP_CLOCK__COMPILER_ATTRIBUTES ./munit.c 321;" d file:
PSNIP_CLOCK__FUNCTION ./munit.c 324;" d file:
PsnipClockTimespec ./munit.c /^struct PsnipClockTimespec {$/;" s file:
PsnipClockTimespec::nanoseconds ./munit.c /^ psnip_uint64_t nanoseconds;$/;" m struct:PsnipClockTimespec file: access:public
PsnipClockTimespec::seconds ./munit.c /^ psnip_uint64_t seconds;$/;" m struct:PsnipClockTimespec file: access:public
PsnipClockType ./munit.c /^enum PsnipClockType {$/;" g file:
STDERR_FILENO ./munit.c 114;" d file:
TEST_ENV ./Makefile /^TEST_ENV:=$/;" m
UBSAN ./Makefile /^UBSAN:=n$/;" m
_CRT_NONSTDC_NO_DEPRECATE ./munit.c 80;" d file:
_POSIX_C_SOURCE ./munit.c 57;" d file:
_POSIX_C_SOURCE ./munit.c 60;" d file:
_XOPEN_SOURCE ./munit.c 66;" d file:
_XOPEN_SOURCE ./munit.c 71;" d file:
_XOPEN_SOURCE ./munit.c 73;" d file:
__anon1::cpu_clock ./munit.c /^ munit_uint64_t cpu_clock;$/;" m struct:__anon1 file: access:public
__anon1::errored ./munit.c /^ unsigned int errored;$/;" m struct:__anon1 file: access:public
__anon1::failed ./munit.c /^ unsigned int failed;$/;" m struct:__anon1 file: access:public
__anon1::skipped ./munit.c /^ unsigned int skipped;$/;" m struct:__anon1 file: access:public
__anon1::successful ./munit.c /^ unsigned int successful;$/;" m struct:__anon1 file: access:public
__anon1::wall_clock ./munit.c /^ munit_uint64_t wall_clock;$/;" m struct:__anon1 file: access:public
__anon2::colorize ./munit.c /^ munit_bool colorize;$/;" m struct:__anon2 file: access:public
__anon2::fatal_failures ./munit.c /^ munit_bool fatal_failures;$/;" m struct:__anon2 file: access:public
__anon2::fork ./munit.c /^ munit_bool fork;$/;" m struct:__anon2 file: access:public
__anon2::iterations ./munit.c /^ unsigned int iterations;$/;" m struct:__anon2 file: access:public
__anon2::parameters ./munit.c /^ MunitParameter* parameters;$/;" m struct:__anon2 file: access:public
__anon2::prefix ./munit.c /^ const char* prefix;$/;" m struct:__anon2 file: access:public
__anon2::report ./munit.c /^ MunitReport report;$/;" m struct:__anon2 file: access:public
__anon2::seed ./munit.c /^ munit_uint32_t seed;$/;" m struct:__anon2 file: access:public
__anon2::show_stderr ./munit.c /^ munit_bool show_stderr;$/;" m struct:__anon2 file: access:public
__anon2::single_parameter_mode ./munit.c /^ munit_bool single_parameter_mode;$/;" m struct:__anon2 file: access:public
__anon2::suite ./munit.c /^ const MunitSuite* suite;$/;" m struct:__anon2 file: access:public
__anon2::tests ./munit.c /^ const char** tests;$/;" m struct:__anon2 file: access:public
__anon2::user_data ./munit.c /^ void* user_data;$/;" m struct:__anon2 file: access:public
__anon5::name ./munit.h /^ char* name;$/;" m struct:__anon5 access:public
__anon5::values ./munit.h /^ char** values;$/;" m struct:__anon5 access:public
__anon6::name ./munit.h /^ char* name;$/;" m struct:__anon6 access:public
__anon6::value ./munit.h /^ char* value;$/;" m struct:__anon6 access:public
__anon8::name ./munit.h /^ char* name;$/;" m struct:__anon8 access:public
__anon8::options ./munit.h /^ MunitTestOptions options;$/;" m struct:__anon8 access:public
__anon8::parameters ./munit.h /^ MunitParameterEnum* parameters;$/;" m struct:__anon8 access:public
__anon8::setup ./munit.h /^ MunitTestSetup setup;$/;" m struct:__anon8 access:public
__anon8::tear_down ./munit.h /^ MunitTestTearDown tear_down;$/;" m struct:__anon8 access:public
__anon8::test ./munit.h /^ MunitTestFunc test;$/;" m struct:__anon8 access:public
assert ./munit.h 532;" d
assert ./munit.h 534;" d
assert_char ./munit.h 485;" d
assert_double ./munit.h 497;" d
assert_double_equal ./munit.h 509;" d
assert_false ./munit.h 484;" d
assert_float ./munit.h 496;" d
assert_int ./munit.h 489;" d
assert_int16 ./munit.h 502;" d
assert_int32 ./munit.h 504;" d
assert_int64 ./munit.h 506;" d
assert_int8 ./munit.h 500;" d
assert_llong ./munit.h 493;" d
assert_long ./munit.h 491;" d
assert_memory_equal ./munit.h 512;" d
assert_memory_not_equal ./munit.h 513;" d
assert_not_null ./munit.h 520;" d
assert_null ./munit.h 519;" d
assert_ptr ./munit.h 498;" d
assert_ptr_equal ./munit.h 514;" d
assert_ptr_not_equal ./munit.h 515;" d
assert_ptr_not_null ./munit.h 517;" d
assert_ptr_null ./munit.h 516;" d
assert_short ./munit.h 487;" d
assert_size ./munit.h 495;" d
assert_string_equal ./munit.h 510;" d
assert_string_not_equal ./munit.h 511;" d
assert_true ./munit.h 483;" d
assert_uchar ./munit.h 486;" d
assert_uint ./munit.h 490;" d
assert_uint16 ./munit.h 503;" d
assert_uint32 ./munit.h 505;" d
assert_uint64 ./munit.h 507;" d
assert_uint8 ./munit.h 501;" d
assert_ullong ./munit.h 494;" d
assert_ulong ./munit.h 492;" d
assert_ushort ./munit.h 488;" d
bar_params ./example.c /^static char* bar_params[] = {$/;" v file:
colorize ./munit.c /^ munit_bool colorize;$/;" m struct:__anon2 file: access:public
cpu_clock ./munit.c /^ munit_uint64_t cpu_clock;$/;" m struct:__anon1 file: access:public
errored ./munit.c /^ unsigned int errored;$/;" m struct:__anon1 file: access:public
failed ./munit.c /^ unsigned int failed;$/;" m struct:__anon1 file: access:public
fatal_failures ./munit.c /^ munit_bool fatal_failures;$/;" m struct:__anon2 file: access:public
foo_params ./example.c /^static char* foo_params[] = {$/;" v file:
fork ./munit.c /^ munit_bool fork;$/;" m struct:__anon2 file: access:public
iterations ./munit.c /^ unsigned int iterations;$/;" m struct:__anon2 file: access:public
iterations ./munit.h /^ unsigned int iterations;$/;" m struct:MunitSuite_ access:public
main ./example.c /^int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {$/;" f signature:(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
munit_arguments_find ./munit.c /^munit_arguments_find(const MunitArgument arguments[], const char* name) {$/;" f file: signature:(const MunitArgument arguments[], const char* name)
munit_assert ./munit.h 204;" d
munit_assert_char ./munit.h 246;" d
munit_assert_double ./munit.h 272;" d
munit_assert_double_equal ./munit.h 294;" d
munit_assert_false ./munit.h 222;" d
munit_assert_float ./munit.h 270;" d
munit_assert_int ./munit.h 254;" d
munit_assert_int16 ./munit.h 281;" d
munit_assert_int32 ./munit.h 285;" d
munit_assert_int64 ./munit.h 289;" d
munit_assert_int8 ./munit.h 277;" d
munit_assert_llong ./munit.h 262;" d
munit_assert_long ./munit.h 258;" d
munit_assert_memory_equal ./munit.h 334;" d
munit_assert_memory_not_equal ./munit.h 353;" d
munit_assert_not_null ./munit.h 372;" d
munit_assert_null ./munit.h 370;" d
munit_assert_ptr ./munit.h 274;" d
munit_assert_ptr_equal ./munit.h 366;" d
munit_assert_ptr_not_equal ./munit.h 368;" d
munit_assert_ptr_not_null ./munit.h 376;" d
munit_assert_ptr_null ./munit.h 374;" d
munit_assert_short ./munit.h 250;" d
munit_assert_size ./munit.h 267;" d
munit_assert_string_equal ./munit.h 310;" d
munit_assert_string_not_equal ./munit.h 322;" d
munit_assert_true ./munit.h 213;" d
munit_assert_type ./munit.h 243;" d
munit_assert_type_full ./munit.h 231;" d
munit_assert_uchar ./munit.h 248;" d
munit_assert_uint ./munit.h 256;" d
munit_assert_uint16 ./munit.h 283;" d
munit_assert_uint32 ./munit.h 287;" d
munit_assert_uint64 ./munit.h 291;" d
munit_assert_uint8 ./munit.h 279;" d
munit_assert_ullong ./munit.h 264;" d
munit_assert_ulong ./munit.h 260;" d
munit_assert_ushort ./munit.h 252;" d
munit_atomic_cas ./munit.c /^munit_atomic_cas(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired) {$/;" f file: signature:(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T* expected, ATOMIC_UINT32_T desired)
munit_atomic_cas ./munit.c 850;" d file:
munit_atomic_cas ./munit.c 854;" d file:
munit_atomic_cas ./munit.c 858;" d file:
munit_atomic_cas ./munit.c 862;" d file:
munit_atomic_cas ./munit.c 866;" d file:
munit_atomic_load ./munit.c /^munit_atomic_load(ATOMIC_UINT32_T* src) {$/;" f file: signature:(ATOMIC_UINT32_T* src)
munit_atomic_load ./munit.c 849;" d file:
munit_atomic_load ./munit.c 853;" d file:
munit_atomic_load ./munit.c 857;" d file:
munit_atomic_load ./munit.c 861;" d file:
munit_atomic_load ./munit.c 865;" d file:
munit_atomic_load ./munit.c 870;" d file:
munit_atomic_store ./munit.c /^munit_atomic_store(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T value) {$/;" f file: signature:(ATOMIC_UINT32_T* dest, ATOMIC_UINT32_T value)
munit_atomic_store ./munit.c 848;" d file:
munit_atomic_store ./munit.c 852;" d file:
munit_atomic_store ./munit.c 856;" d file:
munit_atomic_store ./munit.c 860;" d file:
munit_atomic_store ./munit.c 864;" d file:
munit_atomic_store ./munit.c 869;" d file:
munit_bool ./munit.h 112;" d
munit_bool ./munit.h 114;" d
munit_bool ./munit.h 116;" d
munit_calloc ./munit.h 389;" d
munit_clock_get_elapsed ./munit.c /^munit_clock_get_elapsed(struct PsnipClockTimespec* start, struct PsnipClockTimespec* end) {$/;" f file: signature:(struct PsnipClockTimespec* start, struct PsnipClockTimespec* end)
munit_error ./munit.h 201;" d
munit_error_jmp_buf ./munit.c /^static MUNIT_THREAD_LOCAL jmp_buf munit_error_jmp_buf;$/;" v file:
munit_error_jmp_buf_valid ./munit.c /^static MUNIT_THREAD_LOCAL munit_bool munit_error_jmp_buf_valid = 0;$/;" v file:
munit_errorf ./munit.h 198;" d
munit_errorf_ex ./munit.c /^munit_errorf_ex(const char* filename, int line, const char* format, ...) {$/;" f signature:(const char* filename, int line, const char* format, ...)
munit_int16_t ./munit.h 39;" d
munit_int16_t ./munit.h 49;" d
munit_int32_t ./munit.h 41;" d
munit_int32_t ./munit.h 51;" d
munit_int64_t ./munit.h 43;" d
munit_int64_t ./munit.h 53;" d
munit_int8_t ./munit.h 37;" d
munit_int8_t ./munit.h 47;" d
munit_log ./munit.h 191;" d
munit_log_errno ./munit.c /^munit_log_errno(MunitLogLevel level, FILE* fp, const char* msg) {$/;" f file: signature:(MunitLogLevel level, FILE* fp, const char* msg)
munit_log_internal ./munit.c /^munit_log_internal(MunitLogLevel level, FILE* fp, const char* message) {$/;" f file: signature:(MunitLogLevel level, FILE* fp, const char* message)
munit_log_level_fatal ./munit.c /^static MunitLogLevel munit_log_level_fatal = MUNIT_LOG_ERROR;$/;" v file:
munit_log_level_visible ./munit.c /^static MunitLogLevel munit_log_level_visible = MUNIT_LOG_INFO;$/;" v file:
munit_logf ./munit.h 188;" d
munit_logf_ex ./munit.c /^munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...) {$/;" f signature:(MunitLogLevel level, const char* filename, int line, const char* format, ...)
munit_logf_exv ./munit.c /^munit_logf_exv(MunitLogLevel level, FILE* fp, const char* filename, int line, const char* format, va_list ap) {$/;" f file: signature:(MunitLogLevel level, FILE* fp, const char* filename, int line, const char* format, va_list ap)
munit_logf_internal ./munit.c /^munit_logf_internal(MunitLogLevel level, FILE* fp, const char* format, ...) {$/;" f file: signature:(MunitLogLevel level, FILE* fp, const char* format, ...)
munit_malloc ./munit.h 383;" d
munit_malloc_ex ./munit.c /^munit_malloc_ex(const char* filename, int line, size_t size) {$/;" f signature:(const char* filename, int line, size_t size)
munit_maybe_concat ./munit.c /^munit_maybe_concat(size_t* len, char* prefix, char* suffix) {$/;" f file: signature:(size_t* len, char* prefix, char* suffix)
munit_maybe_free_concat ./munit.c /^munit_maybe_free_concat(char* s, const char* prefix, const char* suffix) {$/;" f file: signature:(char* s, const char* prefix, const char* suffix)
munit_new ./munit.h 386;" d
munit_newa ./munit.h 392;" d
munit_parameters_add ./munit.c /^munit_parameters_add(size_t* params_size, MunitParameter* params[MUNIT_ARRAY_PARAM(*params_size)], char* name, char* value) {$/;" f file: signature:(size_t* params_size, MunitParameter* params[MUNIT_ARRAY_PARAM(*params_size)], char* name, char* value)
munit_parameters_get ./munit.c /^munit_parameters_get(const MunitParameter params[], const char* key) {$/;" f signature:(const MunitParameter params[], const char* key)
munit_print_help ./munit.c /^munit_print_help(int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], void* user_data, const MunitArgument arguments[]) {$/;" f file: signature:(int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], void* user_data, const MunitArgument arguments[])
munit_print_time ./munit.c /^munit_print_time(FILE* fp, munit_uint64_t nanoseconds) {$/;" f file: signature:(FILE* fp, munit_uint64_t nanoseconds)
munit_rand_at_most ./munit.c /^munit_rand_at_most(munit_uint32_t salt, munit_uint32_t max) {$/;" f file: signature:(munit_uint32_t salt, munit_uint32_t max)
munit_rand_double ./munit.c /^munit_rand_double(void) {$/;" f signature:(void)
munit_rand_from_state ./munit.c /^munit_rand_from_state(munit_uint32_t state) {$/;" f file: signature:(munit_uint32_t state)
munit_rand_generate_seed ./munit.c /^munit_rand_generate_seed(void) {$/;" f file: signature:(void)
munit_rand_int_range ./munit.c /^munit_rand_int_range(int min, int max) {$/;" f signature:(int min, int max)
munit_rand_memory ./munit.c /^munit_rand_memory(size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) {$/;" f signature:(size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)])
munit_rand_next_state ./munit.c /^munit_rand_next_state(munit_uint32_t state) {$/;" f file: signature:(munit_uint32_t state)
munit_rand_seed ./munit.c /^munit_rand_seed(munit_uint32_t seed) {$/;" f signature:(munit_uint32_t seed)
munit_rand_state ./munit.c /^static ATOMIC_UINT32_T munit_rand_state = ATOMIC_UINT32_INIT(42);$/;" v file:
munit_rand_state_at_most ./munit.c /^munit_rand_state_at_most(munit_uint32_t* state, munit_uint32_t salt, munit_uint32_t max) {$/;" f file: signature:(munit_uint32_t* state, munit_uint32_t salt, munit_uint32_t max)
munit_rand_state_memory ./munit.c /^munit_rand_state_memory(munit_uint32_t* state, size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)]) {$/;" f file: signature:(munit_uint32_t* state, size_t size, munit_uint8_t data[MUNIT_ARRAY_PARAM(size)])
munit_rand_state_uint32 ./munit.c /^munit_rand_state_uint32(munit_uint32_t* state) {$/;" f file: signature:(munit_uint32_t* state)
munit_rand_uint32 ./munit.c /^munit_rand_uint32(void) {$/;" f signature:(void)
munit_replace_stderr ./munit.c /^munit_replace_stderr(FILE* stderr_buf) {$/;" f file: signature:(FILE* stderr_buf)
munit_restore_stderr ./munit.c /^munit_restore_stderr(int orig_stderr) {$/;" f file: signature:(int orig_stderr)
munit_splice ./munit.c /^munit_splice(int from, int to) {$/;" f file: signature:(int from, int to)
munit_str_hash ./munit.c /^munit_str_hash(const char* name) {$/;" f file: signature:(const char* name)
munit_stream_supports_ansi ./munit.c /^munit_stream_supports_ansi(FILE *stream) {$/;" f file: signature:(FILE *stream)
munit_suite_list_tests ./munit.c /^munit_suite_list_tests(const MunitSuite* suite, munit_bool show_params, const char* prefix) {$/;" f file: signature:(const MunitSuite* suite, munit_bool show_params, const char* prefix)
munit_suite_main ./munit.c /^munit_suite_main(const MunitSuite* suite, void* user_data,$/;" f signature:(const MunitSuite* suite, void* user_data, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)])
munit_suite_main_custom ./munit.c /^munit_suite_main_custom(const MunitSuite* suite, void* user_data,$/;" f signature:(const MunitSuite* suite, void* user_data, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)], const MunitArgument arguments[])
munit_test_runner_exec ./munit.c /^munit_test_runner_exec(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[], MunitReport* report) {$/;" f file: signature:(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[], MunitReport* report)
munit_test_runner_print_color ./munit.c /^munit_test_runner_print_color(const MunitTestRunner* runner, const char* string, char color) {$/;" f file: signature:(const MunitTestRunner* runner, const char* string, char color)
munit_test_runner_run ./munit.c /^munit_test_runner_run(MunitTestRunner* runner) {$/;" f file: signature:(MunitTestRunner* runner)
munit_test_runner_run_suite ./munit.c /^munit_test_runner_run_suite(MunitTestRunner* runner,$/;" f file: signature:(MunitTestRunner* runner, const MunitSuite* suite, const char* prefix)
munit_test_runner_run_test ./munit.c /^munit_test_runner_run_test(MunitTestRunner* runner,$/;" f file: signature:(MunitTestRunner* runner, const MunitTest* test, const char* prefix)
munit_test_runner_run_test_wild ./munit.c /^munit_test_runner_run_test_wild(MunitTestRunner* runner,$/;" f file: signature:(MunitTestRunner* runner, const MunitTest* test, const char* test_name, MunitParameter* params, MunitParameter* p)
munit_test_runner_run_test_with_params ./munit.c /^munit_test_runner_run_test_with_params(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[]) {$/;" f file: signature:(MunitTestRunner* runner, const MunitTest* test, const MunitParameter params[])
munit_uint16_t ./munit.h 40;" d
munit_uint16_t ./munit.h 50;" d
munit_uint32_t ./munit.h 42;" d
munit_uint32_t ./munit.h 52;" d
munit_uint64_t ./munit.h 44;" d
munit_uint64_t ./munit.h 54;" d
munit_uint8_t ./munit.h 38;" d
munit_uint8_t ./munit.h 48;" d
name ./munit.h /^ char* name;$/;" m struct:__anon8 access:public
name ./munit.h /^ char* name;$/;" m struct:__anon5 access:public
name ./munit.h /^ char* name;$/;" m struct:MunitArgument_ access:public
name ./munit.h /^ char* name;$/;" m struct:__anon6 access:public
nanoseconds ./munit.c /^ psnip_uint64_t nanoseconds;$/;" m struct:PsnipClockTimespec file: access:public
options ./munit.h /^ MunitSuiteOptions options;$/;" m struct:MunitSuite_ access:public
options ./munit.h /^ MunitTestOptions options;$/;" m struct:__anon8 access:public
parameters ./munit.c /^ MunitParameter* parameters;$/;" m struct:__anon2 file: access:public
parameters ./munit.h /^ MunitParameterEnum* parameters;$/;" m struct:__anon8 access:public
parse_argument ./munit.h /^ munit_bool (* parse_argument)(const MunitSuite* suite, void* user_data, int* arg, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);$/;" m struct:MunitArgument_ access:public
prefix ./munit.c /^ const char* prefix;$/;" m struct:__anon2 file: access:public
prefix ./munit.h /^ char* prefix;$/;" m struct:MunitSuite_ access:public
psnip_clock__clock_getres ./munit.c /^psnip_clock__clock_getres (clockid_t clk_id) {$/;" f signature:(clockid_t clk_id)
psnip_clock__clock_gettime ./munit.c /^psnip_clock__clock_gettime (clockid_t clk_id, struct PsnipClockTimespec* res) {$/;" f signature:(clockid_t clk_id, struct PsnipClockTimespec* res)
psnip_clock_cpu_get_precision ./munit.c /^psnip_clock_cpu_get_precision (void) {$/;" f signature:(void)
psnip_clock_cpu_get_time ./munit.c /^psnip_clock_cpu_get_time (struct PsnipClockTimespec* res) {$/;" f signature:(struct PsnipClockTimespec* res)
psnip_clock_get_precision ./munit.c /^psnip_clock_get_precision (enum PsnipClockType clock_type) {$/;" f signature:(enum PsnipClockType clock_type)
psnip_clock_get_time ./munit.c /^psnip_clock_get_time (enum PsnipClockType clock_type, struct PsnipClockTimespec* res) {$/;" f signature:(enum PsnipClockType clock_type, struct PsnipClockTimespec* res)
psnip_clock_monotonic_get_precision ./munit.c /^psnip_clock_monotonic_get_precision (void) {$/;" f signature:(void)
psnip_clock_monotonic_get_time ./munit.c /^psnip_clock_monotonic_get_time (struct PsnipClockTimespec* res) {$/;" f signature:(struct PsnipClockTimespec* res)
psnip_clock_wall_get_precision ./munit.c /^psnip_clock_wall_get_precision (void) {$/;" f signature:(void)
psnip_clock_wall_get_time ./munit.c /^psnip_clock_wall_get_time (struct PsnipClockTimespec* res) {$/;" f signature:(struct PsnipClockTimespec* res)
psnip_uint32_t ./munit.c 293;" d file:
psnip_uint64_t ./munit.c 292;" d file:
report ./munit.c /^ MunitReport report;$/;" m struct:__anon2 file: access:public
seconds ./munit.c /^ psnip_uint64_t seconds;$/;" m struct:PsnipClockTimespec file: access:public
seed ./munit.c /^ munit_uint32_t seed;$/;" m struct:__anon2 file: access:public
setup ./munit.h /^ MunitTestSetup setup;$/;" m struct:__anon8 access:public
show_stderr ./munit.c /^ munit_bool show_stderr;$/;" m struct:__anon2 file: access:public
single_parameter_mode ./munit.c /^ munit_bool single_parameter_mode;$/;" m struct:__anon2 file: access:public
skipped ./munit.c /^ unsigned int skipped;$/;" m struct:__anon1 file: access:public
successful ./munit.c /^ unsigned int successful;$/;" m struct:__anon1 file: access:public
suite ./munit.c /^ const MunitSuite* suite;$/;" m struct:__anon2 file: access:public
suites ./munit.h /^ MunitSuite* suites;$/;" m struct:MunitSuite_ access:public
tear_down ./munit.h /^ MunitTestTearDown tear_down;$/;" m struct:__anon8 access:public
test ./munit.h /^ MunitTestFunc test;$/;" m struct:__anon8 access:public
test_compare ./example.c /^test_compare(const MunitParameter params[], void* data) {$/;" f file: signature:(const MunitParameter params[], void* data)
test_compare_setup ./example.c /^test_compare_setup(const MunitParameter params[], void* user_data) {$/;" f file: signature:(const MunitParameter params[], void* user_data)
test_compare_tear_down ./example.c /^test_compare_tear_down(void* fixture) {$/;" f file: signature:(void* fixture)
test_parameters ./example.c /^test_parameters(const MunitParameter params[], void* user_data) {$/;" f file: signature:(const MunitParameter params[], void* user_data)
test_params ./example.c /^static MunitParameterEnum test_params[] = {$/;" v file:
test_rand ./example.c /^test_rand(const MunitParameter params[], void* user_data) {$/;" f file: signature:(const MunitParameter params[], void* user_data)
test_suite ./example.c /^static const MunitSuite test_suite = {$/;" v file:
test_suite_tests ./example.c /^static MunitTest test_suite_tests[] = {$/;" v file:
tests ./munit.c /^ const char** tests;$/;" m struct:__anon2 file: access:public
tests ./munit.h /^ MunitTest* tests;$/;" m struct:MunitSuite_ access:public
user_data ./munit.c /^ void* user_data;$/;" m struct:__anon2 file: access:public
value ./munit.h /^ char* value;$/;" m struct:__anon6 access:public
values ./munit.h /^ char** values;$/;" m struct:__anon5 access:public
wall_clock ./munit.c /^ munit_uint64_t wall_clock;$/;" m struct:__anon1 file: access:public
write_help ./munit.h /^ void (* write_help)(const MunitArgument* argument, void* user_data);$/;" m struct:MunitArgument_ access:public

47
util.c Normal file
View File

@@ -0,0 +1,47 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void *
xmalloc(size_t sz)
{
void *res;
res = malloc(sz);
if (sz != 0 && res == NULL) {
perror("malloc()");
exit(EXIT_FAILURE);
}
return res;
}
void*
xrealloc(void *ptr, size_t size)
{
void *res;
res = realloc(ptr, size);
if (size != 0 && res == NULL) {
perror("realloc()");
exit(EXIT_FAILURE);
}
return res;
}
void
xfree(void *ptr)
{
if (ptr)
free(ptr);
}
void
xerror(int rc, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
exit(rc);
}

9
util.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
void *xmalloc(size_t sz);
void* xrealloc(void *ptr, size_t size);
void xfree(void *ptr);
void xerror(int rc, char *fmt, ...);