mirror of https://github.com/flysand7/ciabatta.git
Better testing setup
This commit is contained in:
parent
9c643bd0a8
commit
6197b6747e
5
readme
5
readme
|
@ -42,14 +42,15 @@ Processor Architecture:
|
|||
- x86-64
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
USAGE
|
||||
USING THE LIBRARY
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Using ciabatta with msvc is not supported. The only compiler that the library
|
||||
have been compiled and tested with is clang.
|
||||
|
||||
Note that the library can only be used with clang
|
||||
1. Run bake.cmd to compile ciabatta
|
||||
1. Run ./build.cmd to compile ciabatta
|
||||
1.5. (Optionally) Run `./test crt_functions` to make sure there are no errors
|
||||
2. Grab the following files into your project's directory:
|
||||
- The ./include folder
|
||||
- The ./ciabatta.lib archive file
|
||||
|
|
3
test.bat
3
test.bat
|
@ -1,2 +1,3 @@
|
|||
|
||||
clang -g %1 -I inc utf8.obj -nostdlib -mfma -lciabatta.lib
|
||||
clang -g test\%1.c -I include utf8.obj -nostdlib -mfma -lciabatta.lib
|
||||
"./a.exe"
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
int main() {
|
||||
uint8_t *sp = _alloca(512);
|
||||
for(int i = 0; i != 550; ++i) {
|
||||
sp[i] = 0;
|
||||
}
|
||||
printf("%p\n", sp);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,440 @@
|
|||
|
||||
// Framework for testing of the CRT library. This file is supposed to be linked
|
||||
// to the ciabatta, so there is a possibility that the runtime that the testing
|
||||
// suite relies on is broken, which is why to decrease the chance of it crashing
|
||||
// because of that, I minimize that dependency. Therefore this testing suite
|
||||
// avoids the following:
|
||||
// - Heap allocations
|
||||
// - Calls to high-level functions like printf, preferring low-level fwrite instead
|
||||
// - Calling other CRT functions other than for the purpose of testing them
|
||||
|
||||
// Dependencies
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Tested
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static unsigned long random_seed = 0;
|
||||
|
||||
unsigned long random(void) {
|
||||
random_seed = random_seed * 2147001325 + 715136305;
|
||||
return 0x31415926 ^ ((random_seed >> 16) + (random_seed << 16));
|
||||
}
|
||||
|
||||
unsigned long random_between(int lo, int hi) {
|
||||
return (random() % (1+hi - lo)) + lo;
|
||||
}
|
||||
|
||||
static void printc(char c) {
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
static void prints(char *str) {
|
||||
while(*str != 0) {
|
||||
printc(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
static void printd(int number) {
|
||||
if(number < 0) {
|
||||
putchar('-');
|
||||
number = -number;
|
||||
}
|
||||
char buffer[20] = {0};
|
||||
char *str = buffer + sizeof buffer;
|
||||
do {
|
||||
*--str = number%10+'0';
|
||||
number /= 10;
|
||||
} while(number != 0);
|
||||
prints(str);
|
||||
}
|
||||
|
||||
static void term_color_green() {
|
||||
prints("\x1b[32m");
|
||||
}
|
||||
|
||||
static void term_color_red() {
|
||||
prints("\x1b[31m");
|
||||
}
|
||||
|
||||
static void term_color_yellow() {
|
||||
prints("\x1b[33m");
|
||||
}
|
||||
|
||||
static void term_color_reset() {
|
||||
prints("\x1b[0m");
|
||||
}
|
||||
|
||||
struct Test typedef Test;
|
||||
struct Test_Feature typedef Test_Feature;
|
||||
|
||||
struct Test_Feature {
|
||||
Test_Feature *next;
|
||||
char *name;
|
||||
int test_count;
|
||||
int success_count;
|
||||
Test *test_head;
|
||||
};
|
||||
|
||||
struct Test {
|
||||
Test *next;
|
||||
char *condition_str;
|
||||
char *error_msg;
|
||||
bool is_succeeded;
|
||||
};
|
||||
|
||||
static void print_test_results(Test_Feature *features_head) {
|
||||
int total_test_count = 0;
|
||||
int total_success_count = 0;
|
||||
for(Test_Feature *feature = features_head; feature != NULL; feature = feature->next) {
|
||||
total_test_count += feature->test_count;
|
||||
total_success_count += feature->success_count;
|
||||
term_color_green();
|
||||
prints("==> Feature ");
|
||||
term_color_reset();
|
||||
prints(feature->name);
|
||||
prints(": (");
|
||||
printd(feature->success_count);
|
||||
printc('/');
|
||||
printd(feature->test_count);
|
||||
prints(")\n");
|
||||
if(feature->success_count < feature->test_count) {
|
||||
int test_index = 0;
|
||||
for(Test *test = feature->test_head; test != NULL; test = test->next) {
|
||||
if(!test->is_succeeded) {
|
||||
term_color_red();
|
||||
prints(" Test #");
|
||||
printd(1+test_index);
|
||||
term_color_reset();
|
||||
// prints(" (");
|
||||
// prints(test->condition_str);
|
||||
prints(" failed: ");
|
||||
prints(test->error_msg);
|
||||
printc('\n');
|
||||
}
|
||||
test_index += 1;
|
||||
}
|
||||
}
|
||||
float success_percentage = (float) total_success_count / (float)total_test_count;
|
||||
if(success_percentage < 0.5) {
|
||||
term_color_red();
|
||||
}
|
||||
else if(success_percentage != 1.0) {
|
||||
term_color_yellow();
|
||||
}
|
||||
else {
|
||||
term_color_green();
|
||||
}
|
||||
}
|
||||
prints("TESTS COMPLETED: ");
|
||||
printd(total_success_count);
|
||||
printc('/');
|
||||
printd(total_test_count);
|
||||
term_color_reset();
|
||||
printc('\n');
|
||||
}
|
||||
|
||||
#define XSTR(expr) #expr
|
||||
#define STR(expr) XSTR(expr)
|
||||
|
||||
#define TESTS_INIT() \
|
||||
Test_Feature *current_feature = NULL
|
||||
|
||||
#define FEATURE_START__(NAME, NUMBER) \
|
||||
Test_Feature feature_ ## NUMBER; \
|
||||
(feature_ ## NUMBER).next = current_feature; \
|
||||
current_feature = &(feature_ ## NUMBER); \
|
||||
current_feature->name = NAME; \
|
||||
current_feature->test_head = NULL; \
|
||||
current_feature->success_count = 0; \
|
||||
current_feature->test_count = 0
|
||||
|
||||
#define FEATURE_START_(NAME, NUMBER) \
|
||||
FEATURE_START__(NAME, NUMBER)
|
||||
|
||||
#define FEATURE_START(NAME) \
|
||||
FEATURE_START_(NAME, __COUNTER__)
|
||||
|
||||
#define FEATURE_END()
|
||||
|
||||
#define TEST__(EXPR, ERROR_MSG, NUMBER) \
|
||||
Test test_ ## NUMBER; \
|
||||
(test_ ## NUMBER).next = current_feature->test_head; \
|
||||
current_feature->test_head = &test_ ## NUMBER; \
|
||||
current_feature->test_head->condition_str = STR(EXPR); \
|
||||
current_feature->test_head->error_msg = ERROR_MSG; \
|
||||
current_feature->test_head->is_succeeded = EXPR; \
|
||||
if(current_feature->test_head->is_succeeded) {\
|
||||
current_feature->success_count += 1; \
|
||||
}\
|
||||
current_feature->test_count += 1
|
||||
|
||||
#define TEST_(EXPR, ERROR_MSG, NUMBER) \
|
||||
TEST__(EXPR, ERROR_MSG, NUMBER)
|
||||
|
||||
#define TEST(EXPR, ERROR_MSG) \
|
||||
TEST_(EXPR, ERROR_MSG, __COUNTER__)
|
||||
|
||||
#define TESTS_PRINT_RESULT() \
|
||||
print_test_results(current_feature)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
TESTS_INIT();
|
||||
|
||||
FEATURE_START("limits.h");
|
||||
{
|
||||
// Check existing of macro definitions
|
||||
#ifdef BOOL_WIDTH
|
||||
TEST(BOOL_WIDTH == 8*sizeof(bool), "BOOL_WIDTH isn't correlated with sizeof(bool)");
|
||||
#else
|
||||
TEST(false, "The macro BOOL_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef CHAR_WIDTH
|
||||
TEST(CHAR_WIDTH == 8, "CHAR_WIDTH isn't 8");
|
||||
#else
|
||||
TEST(false, "The macro CHAR_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef CHAR_BIT
|
||||
TEST(CHAR_BIT == 8, "CHAR_BIT isn't 8");
|
||||
#else
|
||||
TEST(false, "The macro CHAR_BIT wasn't defined");
|
||||
#endif
|
||||
#ifdef CHAR_MIN
|
||||
TEST(CHAR_MIN == -128, "CHAR_MIN isn't -128");
|
||||
#else
|
||||
TEST(false, "The macro CHAR_MIN wasn't defined");
|
||||
#endif
|
||||
#ifdef CHAR_MAX
|
||||
TEST(CHAR_MAX == 127, "CHAR_MAX isn't 127");
|
||||
#else
|
||||
TEST(false, "The macro CHAR_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef MB_LEN_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro MB_LEN_MAX wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef SCHAR_WIDTH
|
||||
TEST(SCHAR_WIDTH == 8, "SCHAR_WIDTH isn't 8");
|
||||
#else
|
||||
TEST(false, "The macro SCHAR_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef SHRT_WIDTH
|
||||
TEST(SHRT_WIDTH == 16, "SHRT_WIDTH isn't 16");
|
||||
#else
|
||||
TEST(false, "The macro SHRT_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef INT_WIDTH
|
||||
TEST(INT_WIDTH == 32, "INT_WIDTH isn't 32");
|
||||
#else
|
||||
TEST(false, "The macro INT_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef LONG_WIDTH
|
||||
TEST(LONG_WIDTH == 32, "LONG_WIDTH isn't 32");
|
||||
#else
|
||||
TEST(false, "The macro LONG_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef LLONG_WIDTH
|
||||
TEST(LLONG_WIDTH == 64, "LLONG_WIDTH isn't 64");
|
||||
#else
|
||||
TEST(false, "The macro LLONG_WIDTH wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef SCHAR_MIN
|
||||
TEST(SCHAR_MIN == -128, "SCHAR_MIN isn't -128");
|
||||
#else
|
||||
TEST(false, "The macro SCHAR_MIN wasn't defined");
|
||||
#endif
|
||||
#ifdef SHRT_MIN
|
||||
TEST(SHRT_MIN == -0x8000, "SHRT_MIN isn't -0x8000");
|
||||
#else
|
||||
TEST(false, "The macro SHRT_MIN wasn't defined");
|
||||
#endif
|
||||
#ifdef INT_MIN
|
||||
TEST(INT_MIN == -0x80000000, "INT_MIN isn't -0x80000000");
|
||||
#else
|
||||
TEST(false, "The macro INT_MIN wasn't defined");
|
||||
#endif
|
||||
#ifdef LONG_MIN
|
||||
TEST(LONG_MIN == -0x80000000l, "LONG_MIN isn't -0x80000000");
|
||||
#else
|
||||
TEST(false, "The macro LONG_MIN wasn't defined");
|
||||
#endif
|
||||
#ifdef LLONG_MIN
|
||||
TEST(LLONG_MIN == -0x8000000000000000ll, "LLONG_MIN isn't -0x8000000000000000");
|
||||
#else
|
||||
TEST(false, "The macro LLONG_MIN wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef SCHAR_MAX
|
||||
TEST(SCHAR_MAX == 127, "SCHAR_MAX isn't 127");
|
||||
#else
|
||||
TEST(false, "The macro SCHAR_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef SHRT_MAX
|
||||
TEST(SHRT_MAX == 0x7fff, "SHRT_MAX isn't 0x7fff");
|
||||
#else
|
||||
TEST(false, "The macro SHRT_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef INT_MAX
|
||||
TEST(INT_MAX == 0x7fffffff, "INT_MAX isn't 0x7fffffff");
|
||||
#else
|
||||
TEST(false, "The macro INT_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef LONG_MAX
|
||||
TEST(LONG_MAX == 0x7fffffff, "LONG_MAX isn't 0x7fffffff");
|
||||
#else
|
||||
TEST(false, "The macro LONG_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef LLONG_MAX
|
||||
TEST(LLONG_MAX == 0x7fffffffffffffffll, "LLONG_MAX isn't 0x7fffffffffffffff");
|
||||
#else
|
||||
TEST(false, "The macro LLONG_MAX wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef UCHAR_WIDTH
|
||||
TEST(UCHAR_WIDTH == 8, "UCHAR_WIDTH isn't 8");
|
||||
#else
|
||||
TEST(false, "The macro UCHAR_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef USHRT_WIDTH
|
||||
TEST(USHRT_WIDTH == 16, "USHRT_WIDTH isn't 16");
|
||||
#else
|
||||
TEST(false, "The macro USHRT_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef UINT_WIDTH
|
||||
TEST(UINT_WIDTH == 32, "UINT_WIDTH isn't 32");
|
||||
#else
|
||||
TEST(false, "The macro UINT_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef ULONG_WIDTH
|
||||
TEST(ULONG_WIDTH == 32, "ULONG_WIDTH isn't 32");
|
||||
#else
|
||||
TEST(false, "The macro ULONG_WIDTH wasn't defined");
|
||||
#endif
|
||||
#ifdef ULLONG_WIDTH
|
||||
TEST(ULLONG_WIDTH == 64, "ULLONG_WIDTH isn't 64");
|
||||
#else
|
||||
TEST(false, "The macro ULLONG_WIDTH wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef UCHAR_MAX
|
||||
TEST(UCHAR_MAX == 255, "UCHAR_MAX isn't 255");
|
||||
#else
|
||||
TEST(false, "The macro UCHAR_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef USHRT_MAX
|
||||
TEST(USHRT_MAX == 0xffffu, "USHRT_MAX isn't 0xffff");
|
||||
#else
|
||||
TEST(false, "The macro USHRT_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef UINT_MAX
|
||||
TEST(UINT_MAX == 0xffffffffu, "UINT_MAX isn't 0xffffffff");
|
||||
#else
|
||||
TEST(false, "The macro UINT_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef ULONG_MAX
|
||||
TEST(ULONG_MAX == 0xffffffffu, "ULONG_MAX isn't 0xffffffff");
|
||||
#else
|
||||
TEST(false, "The macro ULONG_MAX wasn't defined");
|
||||
#endif
|
||||
#ifdef ULLONG_MAX
|
||||
TEST(ULLONG_MAX == 0xffffffffffffffffull, "ULLONG_MAX isn't 0xffffffffffffffffull");
|
||||
#else
|
||||
TEST(false, "The macro ULLONG_MAX wasn't defined");
|
||||
#endif
|
||||
|
||||
#ifdef PTRDIFF_WIDTH
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro PTRDIFF_WIDTH isn't defined");
|
||||
#endif
|
||||
#ifdef PTRDIFF_MIN
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro PTRDIFF_MIN isn't defined");
|
||||
#endif
|
||||
#ifdef PTRDIFF_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro PTRDIFF_MAX isn't defined");
|
||||
#endif
|
||||
#ifdef SIZE_WIDTH
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro SIZE_WIDTH isn't defined");
|
||||
#endif
|
||||
#ifdef SIZE_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro SIZE_MAX isn't defined");
|
||||
#endif
|
||||
#ifdef SIG_ATOMIC_WIDTH
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro SIG_ATOMIC_WIDTH isn't defined");
|
||||
#endif
|
||||
#ifdef SIG_ATOMIC_MIN
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro SIG_ATOMIC_MIN isn't defined");
|
||||
#endif
|
||||
#ifdef SIG_ATOMIC_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro SIG_ATOMIC_MAX isn't defined");
|
||||
#endif
|
||||
#ifdef WINT_WIDTH
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro WINT_WIDTH isn't defined");
|
||||
#endif
|
||||
#ifdef WINT_MIN
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro WINT_MIN isn't defined");
|
||||
#endif
|
||||
#ifdef WINT_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro WINT_MAX isn't defined");
|
||||
#endif
|
||||
#ifdef WCHAR_WIDTH
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "The macro WCHAR_WIDTH isn't defined");
|
||||
#endif
|
||||
#ifdef WCHAR_MIN
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "WCHAR_MIN isn't defined");
|
||||
#endif
|
||||
#ifdef WCHAR_MAX
|
||||
TEST(true, "");
|
||||
#else
|
||||
TEST(false, "WCHAR_MAX isn't defined");
|
||||
#endif
|
||||
}
|
||||
FEATURE_END();
|
||||
|
||||
FEATURE_START("ctype.h");
|
||||
// Test letters
|
||||
for(int i = 0; i != 10; ++i) {
|
||||
TEST(isalpha(random_between('a', 'z')) != 0, "isalpha(letter) returned false");
|
||||
TEST(isdigit(random_between('a', 'z')) == 0, "isdigit(letter) returned true");
|
||||
}
|
||||
// Test digits
|
||||
for(int i = 0; i != 10; ++i) {
|
||||
TEST(isalpha(random_between('0', '9')) == 0, "isalpha(digit) returned true");
|
||||
TEST(isdigit(random_between('0', '9')) != 0, "isdigit(digit) returned false");
|
||||
}
|
||||
FEATURE_END();
|
||||
|
||||
TESTS_PRINT_RESULT();
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
52
test/math.c
52
test/math.c
|
@ -1,52 +0,0 @@
|
|||
|
||||
#include <std.h>
|
||||
|
||||
double cool_doubles[] = {
|
||||
-NAN,
|
||||
-INFINITY,
|
||||
-DBL_MAX,
|
||||
-2.7,
|
||||
-2.5,
|
||||
-2.3,
|
||||
-1.0,
|
||||
-DBL_TRUE_MIN,
|
||||
-DBL_MIN,
|
||||
-0.0,
|
||||
+0.0,
|
||||
DBL_MIN,
|
||||
DBL_TRUE_MIN,
|
||||
1.0,
|
||||
2.3,
|
||||
2.5,
|
||||
2.7,
|
||||
DBL_MAX,
|
||||
INFINITY,
|
||||
NAN,
|
||||
};
|
||||
|
||||
size_t ncool_doubles = COUNTOF(cool_doubles);
|
||||
|
||||
#define for_each_cool_double(i,d,b) \
|
||||
for(int i = 0; i != ncool_doubles; ++i) { \
|
||||
double d = cool_doubles[i]; \
|
||||
b; \
|
||||
}
|
||||
|
||||
const char *show_classification(double x) {
|
||||
switch(fpclassify(x)) {
|
||||
case FP_INFINITE: return "Inf";
|
||||
case FP_NAN: return "NaN";
|
||||
case FP_NORMAL: return "normal";
|
||||
case FP_SUBNORMAL: return "subnormal";
|
||||
case FP_ZERO: return "zero";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
for(int i = 0; i != ncool_doubles; ++i) {
|
||||
double d = cool_doubles[i];
|
||||
printf("%a\n", d);
|
||||
}
|
||||
return 0;
|
||||
}
|
47
test/plot.py
47
test/plot.py
|
@ -1,47 +0,0 @@
|
|||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import subprocess;
|
||||
import math;
|
||||
import csv;
|
||||
|
||||
plt.style.use('_mpl-gallery')
|
||||
pi=math.pi
|
||||
|
||||
with open('bin/data.csv', newline='') as csvfile:
|
||||
reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
|
||||
rows = [row for row in reader];
|
||||
|
||||
# make data
|
||||
x = [float.fromhex(xi[:-1]) for xi in rows[0][:-1]]
|
||||
y = [float.fromhex(yi[:-1]) for yi in rows[1][:-1]]
|
||||
yex = [math.asin(x0) for x0 in x]
|
||||
|
||||
err = np.subtract(y, yex);
|
||||
maxerrv = max(err)
|
||||
minerrv = min(err)
|
||||
maxerr = [maxerrv for xi in rows[0][:-1]]
|
||||
minerr = [minerrv for xi in rows[0][:-1]]
|
||||
errscale = 10**-14
|
||||
|
||||
lo = x[0]
|
||||
hi = x[-1]
|
||||
|
||||
fig, a = plt.subplots(2, 1, constrained_layout=True)
|
||||
# a.step(x, y, linewidth=1)
|
||||
a[0].set_xlim(lo, hi);
|
||||
# a[0].set_ylim(-1.000001, 1.000001);
|
||||
a[0].set_xlabel('x');
|
||||
a[0].set_ylabel('f(x)');
|
||||
a[0].plot(x, y, x, yex)
|
||||
|
||||
a[1].set_xlim(lo, hi);
|
||||
a[1].ticklabel_format(useOffset=False)
|
||||
a[1].set_ylim(-errscale, errscale);
|
||||
a[1].set_xlabel('x');
|
||||
a[1].set_ylabel('absolute error');
|
||||
a[1].plot(x, err, x, maxerr, x, minerr);
|
||||
|
||||
plt.show()
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main() {
|
||||
printf("%i\n", INT_MAX);
|
||||
printf("%i\n", INT_MIN);
|
||||
printf("%x\n", UINT_MAX);
|
||||
printf("%x\n", 0);
|
||||
return 0;
|
||||
}
|
13
test/stuff.c
13
test/stuff.c
|
@ -1,13 +0,0 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
char arr[] = "Bruh\0\0\0";
|
||||
printf("Before memmove: %s\n", &arr[0]);
|
||||
memmove(arr+3, arr, 4);
|
||||
printf("After memmove: %s\n", &arr[0]);
|
||||
return 0;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#include <assert.h>
|
||||
|
||||
int factorial(int n) {
|
||||
assert(n >= 0);
|
||||
if(n == 0) return 1;
|
||||
return n*factorial(n-1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Factorial of %d is %d\n", 10, factorial(10));
|
||||
printf("Factorial of %d is %d\n", -1, factorial(-1));
|
||||
return 0;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// https://en.cppreference.com/w/c/algorithm/bsearch
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
struct data {
|
||||
int nr;
|
||||
char const *value;
|
||||
} dat[] = {
|
||||
{1, "Foo"}, {2, "Bar"}, {3, "Hello"}, {4, "World"}
|
||||
};
|
||||
|
||||
int data_cmp(void const *lhs, void const *rhs)
|
||||
{
|
||||
struct data const *const l = lhs;
|
||||
struct data const *const r = rhs;
|
||||
|
||||
if (l->nr < r->nr) return -1;
|
||||
else if (l->nr > r->nr) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
system("clang -v");
|
||||
|
||||
struct data key = { .nr = 3 };
|
||||
struct data const *res = bsearch(&key, dat, sizeof dat / sizeof dat[0], sizeof dat[0], data_cmp);
|
||||
if (res) {
|
||||
printf("No %d: %s\n", res->nr, res->value);
|
||||
} else {
|
||||
printf("No %d not found\n", key.nr);
|
||||
}
|
||||
|
||||
while (clock() <= 3*CLOCKS_PER_SEC) {
|
||||
printf("%llu seconds\n", clock() / CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
struct timespec start;
|
||||
timespec_get(&start, TIME_UTC);
|
||||
|
||||
struct timespec ts;
|
||||
do {
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
printf("%zu:%ld\n", ts.tv_sec, ts.tv_nsec);
|
||||
} while (ts.tv_sec < start.tv_sec+5);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
float start = (float)clock()/CLOCKS_PER_SEC;
|
||||
for(int i = 0; i != 1000000; ++i) {
|
||||
int c = rand() % 128;
|
||||
assert(ispunct(c) == iswpunct((wint_t)c));
|
||||
assert(isalpha(c) == iswalpha((wint_t)c));
|
||||
assert(isspace(c) == iswspace((wint_t)c));
|
||||
assert(isgraph(c) == iswgraph((wint_t)c));
|
||||
assert(iscntrl(c) == iswcntrl((wint_t)c));
|
||||
}
|
||||
float end = (float)clock()/CLOCKS_PER_SEC;
|
||||
float elaps = end-start;
|
||||
printf("Elapsed: %f\n", elaps);
|
||||
return 0;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
// #include <stdio.h>
|
||||
// #include <errno.h>
|
||||
// #include <stdlib.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// printf("[%d] = %s\n", i, argv[i]);
|
||||
}
|
||||
}
|
101
test/test_fenv.c
101
test/test_fenv.c
|
@ -1,101 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
|
||||
#include <emmintrin.h>
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
|
||||
static inline double rint (double const x) {
|
||||
return (double)_mm_cvtsd_si32(_mm_load_sd(&x));
|
||||
}
|
||||
|
||||
void show_fe_exceptions(void)
|
||||
{
|
||||
printf("current exceptions raised: ");
|
||||
if(fetestexcept(FE_DIVBYZERO)) printf(" FE_DIVBYZERO");
|
||||
if(fetestexcept(FE_INEXACT)) printf(" FE_INEXACT");
|
||||
if(fetestexcept(FE_INVALID)) printf(" FE_INVALID");
|
||||
if(fetestexcept(FE_OVERFLOW)) printf(" FE_OVERFLOW");
|
||||
if(fetestexcept(FE_UNDERFLOW)) printf(" FE_UNDERFLOW");
|
||||
if(fetestexcept(FE_ALL_EXCEPT)==0) printf(" none");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void show_fe_current_rounding_direction(void)
|
||||
{
|
||||
printf("current rounding direction: ");
|
||||
switch (fegetround()) {
|
||||
case FE_TONEAREST: printf ("FE_TONEAREST"); break;
|
||||
case FE_DOWNWARD: printf ("FE_DOWNWARD"); break;
|
||||
case FE_UPWARD: printf ("FE_UPWARD"); break;
|
||||
case FE_TOWARDZERO: printf ("FE_TOWARDZERO"); break;
|
||||
default: printf ("unknown");
|
||||
};
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
double x2 (double x) /* times two */
|
||||
{
|
||||
fenv_t curr_excepts;
|
||||
|
||||
/* Save and clear current f-p environment. */
|
||||
feholdexcept(&curr_excepts);
|
||||
|
||||
/* Raise inexact and overflow exceptions. */
|
||||
printf("In x2(): x = %f\n", x=x*2.0);
|
||||
show_fe_exceptions();
|
||||
feclearexcept(FE_INEXACT); /* hide inexact exception from caller */
|
||||
|
||||
/* Merge caller's exceptions (FE_INVALID) */
|
||||
/* with remaining x2's exceptions (FE_OVERFLOW). */
|
||||
feupdateenv(&curr_excepts);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// ROUNDING MODES
|
||||
printf("\nROUNDING MODES\n");
|
||||
/* Default rounding direction */
|
||||
show_fe_current_rounding_direction();
|
||||
printf("+11.5 -> %f\n", rint(+11.5)); /* midway between two integers */
|
||||
printf("+12.5 -> %f\n", rint(+12.5)); /* midway between two integers */
|
||||
|
||||
/* Save current rounding direction. */
|
||||
int curr_direction = fegetround();
|
||||
|
||||
/* Temporarily change current rounding direction. */
|
||||
fesetround(FE_DOWNWARD);
|
||||
show_fe_current_rounding_direction();
|
||||
printf("+11.5 -> %f\n", rint(+11.5));
|
||||
printf("+12.5 -> %f\n", rint(+12.5));
|
||||
|
||||
/* Restore default rounding direction. */
|
||||
fesetround(curr_direction);
|
||||
show_fe_current_rounding_direction();
|
||||
|
||||
// EXCEPTION TEST
|
||||
printf("\nEXCEPTIONS\n");
|
||||
|
||||
show_fe_exceptions();
|
||||
|
||||
/* Perform some computations which raise exceptions. */
|
||||
printf("1.0/0.0 = %f\n", 1.0/0.0); /* FE_DIVBYZERO */
|
||||
printf("1.0/10.0 = %f\n", 1.0/10.0); /* FE_INEXACT */
|
||||
printf("DBL_MAX*2.0 = %f\n", DBL_MAX*2.0); /* FE_INEXACT FE_OVERFLOW */
|
||||
show_fe_exceptions();
|
||||
|
||||
// FEHOLDEXCEPT
|
||||
printf("\nFEHOLDEXCEPT\n");
|
||||
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
feraiseexcept(FE_INVALID); /* some computation with invalid argument */
|
||||
show_fe_exceptions();
|
||||
printf("x2(DBL_MAX) = %f\n", x2(DBL_MAX));
|
||||
show_fe_exceptions();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void) {
|
||||
FILE *tmp = tmpfile();
|
||||
fputc('a', tmp);
|
||||
fclose(tmp);
|
||||
return 0;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main() {
|
||||
printf("%g\n", 0.0);
|
||||
printf("%g\n", 0.00000031415);
|
||||
printf("%g\n", 3.1415);
|
||||
printf("%g\n", 31.415);
|
||||
printf("%g\n", 314.15);
|
||||
return 0;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int compare_ints(const void *p, const void *q) {
|
||||
int x = *(const int *)p;
|
||||
int y = *(const int *)q;
|
||||
|
||||
/* Avoid return x - y, which can cause undefined behaviour
|
||||
because of signed integer overflow. */
|
||||
if (x < y)
|
||||
return -1; // Return -1 if you want ascending, 1 if you want descending order.
|
||||
else if (x > y)
|
||||
return 1; // Return 1 if you want ascending, -1 if you want descending order.
|
||||
|
||||
return 0;
|
||||
// All the logic is often alternatively written:
|
||||
return (x > y) - (x < y);
|
||||
}
|
||||
|
||||
/* Sort an array of n integers, pointed to by a. */
|
||||
void sort_ints(int *a, size_t n) {
|
||||
qsort(a, n, sizeof(*a), compare_ints);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int arr[] = {-1,10,155, 256-10,0,0,0};
|
||||
int count = sizeof arr / sizeof *arr;
|
||||
sort_ints(arr, count);
|
||||
for(int i = 0; i != count; ++i) {
|
||||
printf("%d\t", arr[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void) {
|
||||
double v0 = strtod("0X1.BC70A3D70A3D7P+6", NULL);
|
||||
|
||||
// parsing with error handling
|
||||
const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz";
|
||||
|
||||
char *end;
|
||||
for (double f = strtod(p, &end); p != end; f = strtod(p, &end)) {
|
||||
// printf("'%.*s' -> ", (int)(end-p), p);
|
||||
p = end;
|
||||
if (errno == ERANGE){
|
||||
// printf("range error, got ");
|
||||
errno = 0;
|
||||
}
|
||||
// printf("%f\n", f);
|
||||
}
|
||||
|
||||
// parsing without error handling
|
||||
double v1 = strtod(" -0.0000000123junk", NULL);
|
||||
double v2 = strtod("junk", NULL);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
int test() {
|
||||
static int a = 2;
|
||||
a += 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
void wack() {
|
||||
printf("BYE!!!\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
atexit(wack);
|
||||
|
||||
char* path_env = getenv("PATH");
|
||||
char *ctx, *path_token = strtok_r(path_env, ";", &ctx);
|
||||
while(path_token) {
|
||||
printf("%s\n", path_token);
|
||||
path_token = strtok_r(NULL, ";", &ctx);
|
||||
}
|
||||
|
||||
test();
|
||||
char input[] = "A bird came down the walk";
|
||||
printf("Parsing the input string '%s'\n", input);
|
||||
char *token = strtok(input, " ");
|
||||
while(token) {
|
||||
printf("%s\n", token);
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
printf("Contents of the input string now: '");
|
||||
for(size_t n = 0; n < sizeof input; ++n)
|
||||
input[n] ? printf("%c", input[n]) : printf("\\0");
|
||||
printf("'");
|
||||
return 0;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#define N_THREADS 5
|
||||
|
||||
_Thread_local int counter;
|
||||
once_flag flag = ONCE_FLAG_INIT;
|
||||
|
||||
void init() {
|
||||
puts("Hey I got a call");
|
||||
}
|
||||
|
||||
int f(void* thr_data) {
|
||||
call_once(&flag, init);
|
||||
for(int n = 0; n < 5; ++n)
|
||||
counter++;
|
||||
puts("Finished");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
thrd_t thread[N_THREADS];
|
||||
for(int i = 0; i != N_THREADS; ++i) {
|
||||
int status = thrd_create(&thread[i], f, NULL);
|
||||
if(status == thrd_error) {
|
||||
puts("Failed creating threads");
|
||||
}
|
||||
}
|
||||
for(int i = 0; i != N_THREADS; ++i) {
|
||||
int res;
|
||||
if(thrd_join(thread[i], &res) == thrd_error) {
|
||||
puts("Failed waiting on thread");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
static const char *const wday[] = {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday", "-unknown-"
|
||||
};
|
||||
|
||||
int main() {
|
||||
// July 4, 2001: Wednesday
|
||||
struct tm time_str;
|
||||
time_str.tm_year = 2001 - 1900;
|
||||
time_str.tm_mon = 7 - 1;
|
||||
time_str.tm_mday = 4;
|
||||
time_str.tm_hour = 0;
|
||||
time_str.tm_min = 0;
|
||||
time_str.tm_sec = 1;
|
||||
time_str.tm_isdst = -1;
|
||||
time_t timestamp;
|
||||
if((timestamp = mktime(&time_str)) == (time_t)(-1)) {
|
||||
time_str.tm_wday = 7;
|
||||
}
|
||||
char const *day_of_week = wday[time_str.tm_wday];
|
||||
struct tm *gmt = gmtime(×tamp);
|
||||
struct tm *local = localtime(×tamp);
|
||||
puts(asctime(gmt));
|
||||
puts(asctime(local));
|
||||
time_t cur_time = time(NULL);
|
||||
puts(ctime(&cur_time));
|
||||
return 0;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
// TODO: won't work until %a is implemented
|
||||
int main(int argc, char **argv) {
|
||||
double lo = -1;
|
||||
double hi = 1;
|
||||
double step = 0.0001;
|
||||
FILE *out = fopen("bin/data.csv", "w");
|
||||
for(double i = lo; i < hi; i += step) {
|
||||
fprintf(out, "%f", i);
|
||||
fprintf(out, ", ");
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
for(double i = lo; i < hi; i += step) {
|
||||
fprintf(out, "%a", asin(i));
|
||||
fprintf(out, ", ");
|
||||
}
|
||||
fclose(out);
|
||||
return 0;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
#include <unicode.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
char *mbstr = u8"улыбок тебе дед макар";
|
||||
{
|
||||
char *str = mbstr;
|
||||
uchar_t ch;
|
||||
int len;
|
||||
while((len = utf8_dec(str, &ch)) > 0 && ch != 0) {
|
||||
printf("char: %d\n", ch);
|
||||
str += len;
|
||||
}
|
||||
if(len <= 0) {
|
||||
printf("This string is not utf8\n");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
#include <wctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
if(iswalpha(L'я')) {
|
||||
printf("Symbol 'я' is indeed a letter\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue