Skip to content
Merged
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: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# c_traceback
A colorful, lightweight error-propagation framework for C.

Website (in development): [https://www.alvinng4.github.io/c_traceback/](https://www.alvinng4.github.io/c_traceback/)

This library is in early development. Come back later!
57 changes: 32 additions & 25 deletions website/content/docs/API/call_stack_management.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import ParamsTable from "components/params-table.tsx";
# Call Stack Management

In order to obtain the traceback in run time, we need to actively manage the call stack.
It is not difficult, but functions or code blocks have to be wrapped with a macro, which
is quite verbose.
Unfortunately, C doesn't provide an easy way to do this. Therefore, we will have to wrap
function calls or code blocks with a macro. While this approach can be quite verbose, it
is what makes our library possible.

## API

### `CTB_WRAP` <Badge text="Macro" />
Wrapper macro for expression to automatically manage call stack frames.
```c
CTB_WRAP(expr)
```

#### Parameters
<ParamsTable
Expand All @@ -22,32 +26,35 @@ Wrapper macro for expression to automatically manage call stack frames.
]}
/>

#### Expands to
```c
do \
{ \
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
(expr); \
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
} while (0)
```

#### Usage
```c
int function_a(void)
{
CTB_WRAP(function_b()); // Wrap a function call
CTB_WRAP(function_b()); // Wraps a function call
}

int function_b(void)
{
int i = 0;
CTB_WRAP(i = 2); // Wrap an assignment
CTB_WRAP(i = 2); // Wraps an assignment
}
```

#### Expands to
```c
do
{
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr);
(expr);
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr);
} while (0)
```

### `CTB_Block` <Badge text="Macro" />
Wrapper macro for a code block to automatically manage call stack frames.
```c
CTB_BLOCK(...)
```

#### Parameters
<ParamsTable
Expand All @@ -56,11 +63,21 @@ Wrapper macro for a code block to automatically manage call stack frames.
]}
/>

#### Expands to
```c
do \
{ \
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
__VA_ARGS__ \
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
} while (0)
```

#### Usage
```c
int function_a(void)
{
/* Wrap a code block */
/* Wraps a code block */
CTB_BLOCK(
int i = 0;
if (i == 0)
Expand All @@ -72,14 +89,4 @@ int function_a(void)
// Note: i is not accessible here
// printf("%d", i); <-- Illegal!
}
```

#### Expands to
```c
do
{
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__);
__VA_ARGS__
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__);
} while (0)
```
143 changes: 143 additions & 0 deletions website/content/docs/API/inline_logging.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
title: Inline Logging
---

import ParamsTable from "components/params-table.tsx";

# Inline Logging

Sometimes, we just want to log a simple message without the full traceback.
In this case, we can use the inline logging API.

## API

### `CTB_LOG_ERROR_INLINE` <Badge text="Macro" />
Wrapper for logging an error to stderr without stacktrace.
```c
CTB_LOG_ERROR_INLINE(ctb_error, msg, ...)
```

<Callout type="warning">Logging an inline error has no effect on the context / call stack. It only logs an error message.</Callout>

#### Parameters
<ParamsTable
params={[
{ name: "ctb_error", type: "CTB_Error", desc: "The error type." },
{ name: "msg", type: "const char *", desc: "Error message." },
{ name: "...", type: "N/A", desc: "Additional arguments for formatting the message." },
]}
/>

#### Expands to
```c
do \
{ \
ctb_log_error_inline( \
__FILE__, __LINE__, __func__, ctb_error, msg, __VA_ARGS__ \
); \
} while (0)
```

#### Usage
```c
double division(double x, double y)
{
if (y == 0)
{
CTB_LOG_ERROR_INLINE(
CTB_ZERO_DIVISION_ERROR,
"y cannot be zero! Received: %lf",
y
);
return 0.0;
}
return x / y;
}
```
Output:
```ansi
ZeroDivisionError: File "/home/alvinng/Desktop/c_trackback/examples/example.c", line 19 in division:
y cannot be zero! Received: 0.000000
```

### `CTB_LOG_WARNING_INLINE` <Badge text="Macro" />
Wrapper for logging a warning to stderr without stacktrace.
```c
CTB_LOG_WARNING_INLINE(ctb_warning, msg, ...)
```

#### Parameters
<ParamsTable
params={[
{ name: "ctb_warning", type: "CTB_Warning", desc: "The warning type." },
{ name: "msg", type: "const char *", desc: "Warning message." },
{ name: "...", type: "N/A", desc: "Additional arguments for formatting the message." },
]}
/>

#### Expands to
```c
do \
{ \
ctb_log_warning_inline( \
__FILE__, __LINE__, __func__, ctb_warning, msg, __VA_ARGS__ \
); \
} while (0)
```

#### Usage
```c
double some_function(void)
{
CTB_LOG_WARNING_INLINE(
CTB_DEPRECATION_WARNING,
"Function \"%s\" is deprecated. It will be removed in the next version.",
__func__
);

/* Do something */

return;
}
```
Output:
```ansi
DeprecationWarning: File "/home/alvinng/Desktop/c_trackback/examples/example.c", line 17 in some_function:
Function "some_function" is deprecated. It will be removed in the next version.
```

### `CTB_LOG_MESSAGE_INLINE` <Badge text="Macro" />
Wrapper for logging a message to stdout without stacktrace.
```c
CTB_LOG_MESSAGE_INLINE(msg, ...)
```

#### Parameters
<ParamsTable
params={[
{ name: "msg", type: "const char *", desc: "Message." },
{ name: "...", type: "N/A", desc: "Additional arguments for formatting the message." },
]}
/>

#### Expands to
```c
do \
{ \
ctb_log_message_inline(__FILE__, __LINE__, __func__, msg, __VA_ARGS__); \
} while (0)
```

#### Usage
```c
void inline_message(int i)
{
CTB_LOG_MESSAGE_INLINE("(Test %d) Hello, world! :)", i);
}
```

Output:
```ansi
Message: File "/home/alvinng/Desktop/c_trackback/examples/example.c", line 75 in inline_message:
(Test 0) Hello, world! :)
```