Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: c
dist: bionic
dist: focal

compiler:
- gcc
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(panic C)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wpedantic -pedantic-errors")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -Werror -pedantic-errors")

# dependencies
include_directories(deps)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019 Davide Di Carlo
Copyright (c) 2020 Davide Di Carlo

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
Expand Down
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,32 @@

[![Build Status](https://travis-ci.org/daddinuz/panic.svg?branch=master)](https://travis-ci.org/daddinuz/panic)

A panic library to abort execution on non-recoverable errors with a detailed message.
A panic library to abort execution of the current thread on non-recoverable errors with a detailed message.

```c
#include <stdlib.h>
#include <stdio.h>
#include <panic.h>

double divide(const double dividend, const double divisor) {
panic_when(0 == divisor);
// thread local handler called before terminating the thread.
static void panicHandler(void) {
fprintf(stderr, " Here: '%s:%d (%s)'\n", __FILE__, __LINE__, __func__);
}

// global handler called before terminating the whole program, this handler will run after panicHandler.
static void exitHandler(void) {
fprintf(stderr, " Here: '%s:%d (%s)'\n", __FILE__, __LINE__, __func__);
}

static double divide(const double dividend, const double divisor) {
panic_assert(0.000001 < divisor || divisor < -0.000001, "Division by zero");
return dividend / divisor;
}

int main() {
printf("%lf\r\n", divide(8, 0));
int main(void) {
atexit(exitHandler);
panic_registerHandler(panicHandler);
printf("%f\r\n", divide(8, 0));
return 0;
}
```
Expand All @@ -26,8 +39,10 @@ Traceback (most recent call last):
[0]: (main)
->-: (divide) current function

At: '/panic/examples/main.c:37'
Cause: `0 == divisor`
At: '/panic/examples/main.c:43'
Cause: Division by zero
Here: '/panic/examples/main.c:34 (panicHandler)'
Here: '/panic/examples/main.c:39 (exitHandler)'
```

### Optional features
Expand Down
9 changes: 5 additions & 4 deletions clib.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "panic",
"repo": "daddinuz/panic",
"version": "2.0.0",
"version": "3.0.0",
"license": "MIT",
"description": "A panic library to abort execution on non-recoverable errors with a detailed message.",
"keywords": [
Expand All @@ -14,11 +14,12 @@
"sources/panic.c"
],
"development": {
"daddinuz/traits": "4.0.1",
"daddinuz/traits-unit": "4.0.2"
"daddinuz/traits": "4.1.0",
"daddinuz/traits-unit": "4.1.0"
},
"dependencies": {
"daddinuz/trace": "2.0.0"
"daddinuz/trace": "3.0.0",
"daddinuz/stringify": "3.0.0"
},
"makefile": "sources/build.cmake"
}
2 changes: 1 addition & 1 deletion deps/stringify/clib.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stringify",
"repo": "daddinuz/stringify",
"version": "2.0.0",
"version": "3.0.0",
"license": "MIT",
"description": "Stringify all the things!",
"keywords": [
Expand Down
6 changes: 3 additions & 3 deletions deps/stringify/stringify.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Davide Di Carlo
* Copyright (c) 2020 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -31,8 +31,8 @@
extern "C" {
#endif

#define __stringify(s) #s
#define stringify(s) __stringify(s)
#define stringify_quote(s) #s
#define stringify_lazyQuote(s) stringify_quote(s)

#ifdef __cplusplus
}
Expand Down
4 changes: 2 additions & 2 deletions deps/trace/clib.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "trace",
"repo": "daddinuz/trace",
"version": "2.0.0",
"version": "3.0.0",
"license": "MIT",
"dependencies": {
"daddinuz/stringify": "2.0.0"
"daddinuz/stringify": "3.0.0"
},
"src": [
"sources/trace.h"
Expand Down
4 changes: 2 additions & 2 deletions deps/trace/trace.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Davide Di Carlo
* Copyright (c) 2020 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -33,7 +33,7 @@
extern "C" {
#endif

#define __TRACE__ __FILE__ ":" stringify(__LINE__)
#define TRACE __FILE__ ":" stringify_lazyQuote(__LINE__)

#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions deps/traits-unit/clib.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "traits-unit",
"repo": "daddinuz/traits-unit",
"version": "4.0.2",
"version": "4.1.0",
"license": "MIT",
"description": "Unittest framework written in C99.",
"keywords": [
Expand All @@ -14,10 +14,10 @@
"test-framework"
],
"development": {
"daddinuz/traits": "4.0.1"
"daddinuz/traits": "4.1.0"
},
"dependencies": {
"daddinuz/trace": "2.0.0"
"daddinuz/trace": "3.0.0"
},
"src": [
"sources/traits-unit.h",
Expand Down
4 changes: 2 additions & 2 deletions deps/traits-unit/traits-unit.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Davide Di Carlo
* Copyright (c) 2020 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -132,7 +132,7 @@ static void traitsUnit_signalHandler(int signalId);
/*
* Define internal macros
*/
#define traitsUnit_panic(fmt, ...) do { __traitsUnit_panic(__TRACE__, fmt, __VA_ARGS__); abort(); } while(false)
#define traitsUnit_panic(fmt, ...) do { __traitsUnit_panic(TRACE, fmt, __VA_ARGS__); abort(); } while(false)

/*
* Define public functions
Expand Down
6 changes: 3 additions & 3 deletions deps/traits-unit/traits-unit.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Davide Di Carlo
* Copyright (c) 2020 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -135,10 +135,10 @@ extern int main(int argc, char *argv[]);
#define __traitsUnit_featureId(Name) __traitsUnit_tokenJoin(traitsUnit_userFeature, Name)

#define __traitsUnit_runFeature(Name, Fixture, ...) \
{.fixture=&__traitsUnit_fixtureId(Fixture), .feature=stringify(Name), .call=__traitsUnit_featureId(Name), .skip=false}
{.fixture=&__traitsUnit_fixtureId(Fixture), .feature=stringify_quote(Name), .call=__traitsUnit_featureId(Name), .skip=false}

#define __traitsUnit_skipFeature(Name, Fixture, ...) \
{.fixture=&__traitsUnit_fixtureId(Fixture), .feature=stringify(Name), .call=__traitsUnit_featureId(Name), .skip=true}
{.fixture=&__traitsUnit_fixtureId(Fixture), .feature=stringify_quote(Name), .call=__traitsUnit_featureId(Name), .skip=true}

extern jmp_buf __traitsUnitJumpBuffer;

Expand Down
5 changes: 3 additions & 2 deletions deps/traits/clib.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "traits",
"repo": "daddinuz/traits",
"version": "4.0.1",
"version": "4.1.0",
"license": "MIT",
"description": "Assertions library written in C99.",
"keywords": [
Expand All @@ -10,7 +10,8 @@
"assertions-library"
],
"dependencies": {
"daddinuz/trace": "2.0.0"
"daddinuz/trace": "3.0.0",
"daddinuz/stringify": "3.0.0"
},
"src": [
"sources/traits.h"
Expand Down
33 changes: 17 additions & 16 deletions deps/traits/traits.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Davide Di Carlo
* Copyright (c) 2020 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand All @@ -25,6 +25,7 @@

#pragma once

#include <stringify/stringify.h>
#include <trace/trace.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -143,7 +144,7 @@ __traits_assert(const bool condition, const char *const __trace, const char *con
/*
* Basic
*/
#define __assert_that(c, ...) __traits_assert((c), __TRACE__, stringify(c), __VA_ARGS__)
#define __assert_that(c, ...) __traits_assert((c), TRACE, stringify_lazyQuote(c), __VA_ARGS__)
#define __assert_that0(c) __assert_that(c, NULL)
#define __assert_that1(c, ...) __assert_that(c, __VA_ARGS__)
#define assert_that(...) __traits_overload1(__assert_that0, __assert_that1, __VA_ARGS__)
Expand All @@ -153,84 +154,84 @@ __traits_assert(const bool condition, const char *const __trace, const char *con
/*
* Boolean
*/
#define __assert_true(c, ...) __traits_assert(eq(true, c), __TRACE__, stringify(c), __VA_ARGS__)
#define __assert_true(c, ...) __traits_assert(eq(true, c), TRACE, stringify_lazyQuote(c), __VA_ARGS__)
#define __assert_true0(c) __assert_true(c, "Expected to be true.\r\n")
#define __assert_true1(c, ...) __assert_true(c, __VA_ARGS__)
#define assert_true(...) __traits_overload1(__assert_true0, __assert_true1, __VA_ARGS__)

#define __assert_false(c, ...) __traits_assert(eq(false, c), __TRACE__, stringify(c), __VA_ARGS__)
#define __assert_false(c, ...) __traits_assert(eq(false, c), TRACE, stringify_lazyQuote(c), __VA_ARGS__)
#define __assert_false0(c) __assert_false(c, "Expected to be false.\r\n")
#define __assert_false1(c, ...) __assert_false(c, __VA_ARGS__)
#define assert_false(...) __traits_overload1(__assert_false0, __assert_false1, __VA_ARGS__)

/*
* Numerical
*/
#define __assert_equal(e, a, ...) __traits_assert(eq(e, a), __TRACE__, stringify(eq(e, a)), __VA_ARGS__)
#define __assert_equal(e, a, ...) __traits_assert(eq(e, a), TRACE, stringify_lazyQuote(eq(e, a)), __VA_ARGS__)
#define __assert_equal0(e, a) __assert_equal(e, a, "Expected to be equal.\r\n")
#define __assert_equal1(e, a, ...) __assert_equal(e, a, __VA_ARGS__)
#define assert_equal(...) __traits_overload2(__assert_equal0, __assert_equal1, __VA_ARGS__)

#define __assert_not_equal(e, a, ...) __traits_assert(ne(e, a), __TRACE__, stringify(ne(e, a)), __VA_ARGS__)
#define __assert_not_equal(e, a, ...) __traits_assert(ne(e, a), TRACE, stringify_lazyQuote(ne(e, a)), __VA_ARGS__)
#define __assert_not_equal0(e, a) __assert_not_equal(e, a, "Expected to be not equal.\r\n")
#define __assert_not_equal1(e, a, ...) __assert_not_equal(e, a, __VA_ARGS__)
#define assert_not_equal(...) __traits_overload2(__assert_not_equal0, __assert_not_equal1, __VA_ARGS__)

#define __assert_greater(e, a, ...) __traits_assert(gt(e, a), __TRACE__, stringify(gt(e, a)), __VA_ARGS__)
#define __assert_greater(e, a, ...) __traits_assert(gt(e, a), TRACE, stringify_lazyQuote(gt(e, a)), __VA_ARGS__)
#define __assert_greater0(e, a) __assert_greater(e, a, "Expected to be greater.\r\n")
#define __assert_greater1(e, a, ...) __assert_greater(e, a, __VA_ARGS__)
#define assert_greater(...) __traits_overload2(__assert_greater0, __assert_greater1, __VA_ARGS__)

#define __assert_greater_equal(e, a, ...) __traits_assert(ge(e, a), __TRACE__, stringify(ge(e, a)), __VA_ARGS__)
#define __assert_greater_equal(e, a, ...) __traits_assert(ge(e, a), TRACE, stringify_lazyQuote(ge(e, a)), __VA_ARGS__)
#define __assert_greater_equal0(e, a) __assert_greater_equal(e, a, "Expected to be greater or equal.\r\n")
#define __assert_greater_equal1(e, a, ...) __assert_greater_equal(e, a, __VA_ARGS__)
#define assert_greater_equal(...) __traits_overload2(__assert_greater_equal0, __assert_greater_equal1, __VA_ARGS__)

#define __assert_less(e, a, ...) __traits_assert(lt(e, a), __TRACE__, stringify(lt(e, a)), __VA_ARGS__)
#define __assert_less(e, a, ...) __traits_assert(lt(e, a), TRACE, stringify_lazyQuote(lt(e, a)), __VA_ARGS__)
#define __assert_less0(e, a) __assert_less(e, a, "Expected to be less.\r\n")
#define __assert_less1(e, a, ...) __assert_less(e, a, __VA_ARGS__)
#define assert_less(...) __traits_overload2(__assert_less0, __assert_less1, __VA_ARGS__)

#define __assert_less_equal(e, a, ...) __traits_assert(le(e, a), __TRACE__, stringify(le(e, a)), __VA_ARGS__)
#define __assert_less_equal(e, a, ...) __traits_assert(le(e, a), TRACE, stringify_lazyQuote(le(e, a)), __VA_ARGS__)
#define __assert_less_equal0(e, a) __assert_less_equal(e, a, "Expected to be less or equal.\r\n")
#define __assert_less_equal1(e, a, ...) __assert_less_equal(e, a, __VA_ARGS__)
#define assert_less_equal(...) __traits_overload2(__assert_less_equal0, __assert_less_equal1, __VA_ARGS__)

/*
* Pointer
*/
#define __assert_null(x, ...) __traits_assert(eq(NULL, x), __TRACE__, stringify(x), __VA_ARGS__)
#define __assert_null(x, ...) __traits_assert(eq(NULL, x), TRACE, stringify_lazyQuote(x), __VA_ARGS__)
#define __assert_null0(x) __assert_null(x, "Expected to be null.\r\n")
#define __assert_null1(x, ...) __assert_null(x, __VA_ARGS__)
#define assert_null(...) __traits_overload1(__assert_null0, __assert_null1, __VA_ARGS__)

#define __assert_not_null(x, ...) __traits_assert(ne(NULL, x), __TRACE__, stringify(x), __VA_ARGS__)
#define __assert_not_null(x, ...) __traits_assert(ne(NULL, x), TRACE, stringify_lazyQuote(x), __VA_ARGS__)
#define __assert_not_null0(x) __assert_not_null(x, "Expected to be not null.\r\n")
#define __assert_not_null1(x, ...) __assert_not_null(x, __VA_ARGS__)
#define assert_not_null(...) __traits_overload1(__assert_not_null0, __assert_not_null1, __VA_ARGS__)

/*
* Memory
*/
#define __assert_memory_equal(e, a, s, ...) __traits_assert(eq(0, memcmp(e, a, s)), __TRACE__, stringify(eq(0, memcmp(e, a, s))), __VA_ARGS__)
#define __assert_memory_equal(e, a, s, ...) __traits_assert(eq(0, memcmp(e, a, s)), TRACE, stringify_lazyQuote(eq(0, memcmp(e, a, s))), __VA_ARGS__)
#define __assert_memory_equal0(e, a, s) __assert_memory_equal(e, a, s, NULL)
#define __assert_memory_equal1(e, a, s, ...) __assert_memory_equal(e, a, s, __VA_ARGS__)
#define assert_memory_equal(...) __traits_overload3(__assert_memory_equal0, __assert_memory_equal1, __VA_ARGS__)

#define __assert_memory_not_equal(e, a, s, ...) __traits_assert(ne(0, memcmp(e, a, s)), __TRACE__, stringify(ne(0, memcmp(e, a, s))), __VA_ARGS__)
#define __assert_memory_not_equal(e, a, s, ...) __traits_assert(ne(0, memcmp(e, a, s)), TRACE, stringify_lazyQuote(ne(0, memcmp(e, a, s))), __VA_ARGS__)
#define __assert_memory_not_equal0(e, a, s) __assert_memory_not_equal(e, a, s, NULL)
#define __assert_memory_not_equal1(e, a, s, ...) __assert_memory_not_equal(e, a, s, __VA_ARGS__)
#define assert_memory_not_equal(...) __traits_overload3(__assert_memory_not_equal0, __assert_memory_not_equal1, __VA_ARGS__)

/*
* String
*/
#define __assert_string_equal(e, a, ...) __traits_assert(eq(0, strcmp(e, a)), __TRACE__, stringify(eq(0, strcmp(e, a))), __VA_ARGS__)
#define __assert_string_equal(e, a, ...) __traits_assert(eq(0, strcmp(e, a)), TRACE, stringify_lazyQuote(eq(0, strcmp(e, a))), __VA_ARGS__)
#define __assert_string_equal0(e, a) __assert_string_equal(e, a, "Expected to be equal.\r\n")
#define __assert_string_equal1(e, a, ...) __assert_string_equal(e, a, __VA_ARGS__)
#define assert_string_equal(...) __traits_overload2(__assert_string_equal0, __assert_string_equal1, __VA_ARGS__)

#define __assert_string_not_equal(e, a, ...) __traits_assert(ne(0, strcmp(e, a)), __TRACE__, stringify(ne(0, strcmp(e, a))), __VA_ARGS__)
#define __assert_string_not_equal(e, a, ...) __traits_assert(ne(0, strcmp(e, a)), TRACE, stringify_lazyQuote(ne(0, strcmp(e, a))), __VA_ARGS__)
#define __assert_string_not_equal0(e, a) __assert_string_not_equal(e, a, "Expected to be not equal.\r\n")
#define __assert_string_not_equal1(e, a, ...) __assert_string_not_equal(e, a, __VA_ARGS__)
#define assert_string_not_equal(...) __traits_overload2(__assert_string_not_equal0, __assert_string_not_equal1, __VA_ARGS__)
Expand Down
Loading