Better testing setup

This commit is contained in:
flysand7 2023-06-18 21:41:55 +11:00
parent 9c643bd0a8
commit 6197b6747e
25 changed files with 445 additions and 590 deletions

5
readme
View File

@ -42,14 +42,15 @@ Processor Architecture:
- x86-64 - x86-64
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
USAGE USING THE LIBRARY
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Using ciabatta with msvc is not supported. The only compiler that the library Using ciabatta with msvc is not supported. The only compiler that the library
have been compiled and tested with is clang. have been compiled and tested with is clang.
Note that the library can only be used with 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: 2. Grab the following files into your project's directory:
- The ./include folder - The ./include folder
- The ./ciabatta.lib archive file - The ./ciabatta.lib archive file

View File

@ -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"

View File

@ -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;
}

440
test/crt_functions.c Normal file
View File

@ -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;
}

View File

@ -1,7 +0,0 @@
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}

View File

@ -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;
}

View File

@ -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()

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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]);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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]);
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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");
}
}
}

View File

@ -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(&timestamp);
struct tm *local = localtime(&timestamp);
puts(asctime(gmt));
puts(asctime(local));
time_t cur_time = time(NULL);
puts(ctime(&cur_time));
return 0;
}

View File

@ -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;
}

View File

@ -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");
}
}
}

View File

@ -1,10 +0,0 @@
#include <wctype.h>
#include <stdio.h>
int main() {
if(iswalpha(L'я')) {
printf("Symbol 'я' is indeed a letter\n");
}
return 0;
}