Skip to content
Closed
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
60 changes: 60 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Base style configuration
# Inherit all formatting rules from the LLVM style as a starting point.
BasedOnStyle: LLVM

# Indentation settings
# - IndentWidth: number of spaces per indent level.
# - TabWidth: visual width of tab characters.
# - UseTab: whether to emit real tab characters.
# - NamespaceIndentation: ident namespaces
IndentWidth: 2
TabWidth: 2
UseTab: Never
NamespaceIndentation: All

# Include directives
# - SortIncludes: controls ordering of #include statements.
# - IncludeBlocks: allow empty lines for includes.
SortIncludes: true
IncludeBlocks: Preserve

# Short constructs on single lines
# Disallow collapsing blocks, loops, cases, ifs, and functions into a single line.
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false

# Access modifiers formatting
# Shift class access specifiers (public/protected/private) relative to class indent.
AccessModifierOffset: -2

# Brace placement
# Attach opening braces to the control statement or declaration line.
BreakBeforeBraces: Attach

# Spacing around parentheses and casts
# ControlStatements: space before parens in if/for/while only.
# No extra spaces inside parentheses, angles, container literals, or square brackets.
SpaceBeforeParens: ControlStatements
SpaceAfterCStyleCast: false
SpacesInParentheses: false
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false

# Template keyword spacing
# Always place a space after the 'template' keyword.
SpaceAfterTemplateKeyword: true

# Line length
# ColumnLimit: 0 disables automatic wrapping; allows unlimited line length.
ColumnLimit: 0

# Pointer alignment
# DerivePointerAlignment: ignore inference, use PointerAlignment setting.
# PointerAlignment: align the '*' or '&' to the left with the type.
DerivePointerAlignment: false
PointerAlignment: Left
54 changes: 54 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# .clang-tidy

# Enable broad sets, disable one modernize check explicitly.
Checks: >
clang-diagnostic-*,
clang-analyzer-*,
cppcoreguidelines-*,
modernize-*,
-modernize-use-trailing-return-type
-cppcoreguidelines-avoid-magic-numbers

# Lint everything. Set a regex (e.g. ^src/|^include/) to scope.
HeaderFilterRegex: ''

# Use clang-format's "google" style when auto-fixing.
FormatStyle: google

# Per-check options, grouped for readability.
CheckOptions:
# --- CERT ---
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: '0'

# --- CppCoreGuidelines ---
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: '1'
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1'

# --- Google Readability ---
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'

# --- Modernize ---
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: 'reasonable'
- key: modernize-loop-convert.NamingStyle
value: 'CamelCase'
- key: modernize-pass-by-value.IncludeStyle
value: 'llvm'
- key: modernize-replace-auto-ptr.IncludeStyle
value: 'llvm'
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CClarify CI

on:
push:
pull_request:
branches: [master]

jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
std: [99, 11, 17, 23]
compiler: [gcc, clang]

runs-on: ${{ matrix.os }}

steps:
- name: Install conan
uses: conan-io/setup-conan@v1

- name: Checkout code
uses: actions/checkout@v4
with:
submodules: true

- name: Build & test
run: conan create . -o std=${{ matrix.std }} -s compiler=${{ matrix.compiler }} -s compiler.version=14 -s compiler.libcxx=libstdc++
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "dist/munit"]
path = dist/munit
url = https://github.com/nemequ/munit
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.15)
project(hyper-cclarify C)

message(STATUS "Using C standard: ${CMAKE_C_STANDARD}")

add_library(cclarify src/cclarify.c)
target_include_directories(cclarify PUBLIC include)

set_target_properties(cclarify PROPERTIES PUBLIC_HEADER "include/cclarify/cclarify.h")
install(TARGETS cclarify)
4 changes: 0 additions & 4 deletions Makefile

This file was deleted.

143 changes: 86 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,72 +25,101 @@
- [About project](#about-cclarify)
- [Installation](#installation)
- [Usage](#usage)
- [Assign](#assign)
- [Exec](#exec)
- [Msg](#msg)
- [Display](#display)
- [Quickstart](#quickstart)
- [Loglevels](#loglevels)
- [Formatting rules](#formatting-rules)
- [Global formatter API](#global-formatter-api)
- [Using custom loggers](#using-custom-loggers)


# About CClarify
CClarify is a small framework for creating advanced logging system. It can write to your custom descriptor, pointing to buffer, and can save everything to file, if you set it to do so.
CClarify is a small logging library, written in pure C, that doesn't use any heap memory.

## Installation
1. Download main header [cclarify.h](cclarify.h)
2. Include it to your source file, where you want to add logging
3. Now you should set up everything.
```c
GLOBAL_INIT(); // Init logger variables
Clarifier clar; // Create logger object
// If you have int descriptor like stdout
init_loggerd(clar, descriptor);

// If you want it to write logs to file
init_loggerf(clar, fd);

// If you want it to write logs to both destinations
init_loggerfd(clar, descriptor, fd);
```
4. You are good to go now!
## Usage
### Assign
If you want to assign some value to variable (custom types are not supported) you should do this:
```c
ASSIGN(clar, variable, value);
```
It will output something like:
If you use **Conan**, add the the package:
```
==> Assigning value "value" to "variable", old value: "old_var_val"
```
### Exec
If you wanna execute some function, and signal if function started or stopped, do this:
```c
EXEC(clar, function());
```
It will notify you about started execution:
```
==> Starting execution of function "function()"
```
And about end of function execution.
```
==> Execution of function "function()" finished
hyper-cclarify/<version>
```
You can choose a version in **Releases** tab.

### Msg
To display some king of message, you need just to use MSG() function.
## Usage
### Quickstart
If you don't need all these fancy things, you can just start logging - it will work!
```c
// To display green info message, do this
MSG(clar, "Hello World!", INFO);
// Yellow - warning
MSG(clar, "Warning", WARNING);
// Red - error
MSG(clar, "Error", ERROR);
#include "cclarify.h"

int main() {
clar_info("Program is running");
}
```

### Display
Sometimes you want just to display variable value. Do this:
```c
DISPLAY(clar, variable);
### Loglevels
CClarify has the following loglevels:
- **CLAR_LOG_DEBUG**
- **CLAR_LOG_INFO**
- **CLAR_LOG_WARNING**
- **CLAR_LOG_ERROR**
- **CLAR_LOG_FATAL**

**Example**:
If you will set loglevel to **CLAR_LOG_WARNING**, all log calls with priority lower than this (i. e. **CLAR_LOG_INFO** and **CLAR_LOG_DEBUG**) won't print anything at all.

### Formatting rules
| %Y | Insert current year (for example, **2025**) |
|----|-----------------------------------------------------------------------------------------|
| %M | Insert abbreviated month name (for example, **Sep**) |
| %d | Insert abbreviated day of week name (for example, **Mon**) |
| %D | Insert day of month as a decimal (for example, **09**) |
| %H | Insert hour as a decimal (for example, **13**) |
| %m | Insert minute as a decimal (for example, **32**) |
| %s | Insert second as a decifuncleuncal (for example, **47**) |
| %l | Insert formatted string from log() call |
| %x | Inserts message, specific to current loglevel (applying colors, if writing to terminal) |
| %% | Inserts a single percent |
| % | Inserts a single percent too - if the next character is not a valid format specifier |

### Global formatter API
`void clar_set_global_rotation(const char* filename, uint16_t max_files, uint32_t max_file_size)` - Enables log rotation when you enabled global output to file. Max file size is set in bytes.

`void clar_set_global_format(const char* fmt)` - Sets global format string. Notice, that this is NOT a format string, that is used by libc's *printf functions! See [formatting rules](#formatting-rules) for more.

`void clar_set_global_loglevel(__clar_loglevel loglevel)` - Sets global loglevel.

`void clar_log(__clar_loglevel loglevel, const char* fmt, ...)` - Uses global logger and provided loglevel to log.

`void clar_debug(const char* fmt, ...)` - Uses global logger and **CLAR_LOG_DEBUG** loglevel to log.

`void clar_info(const char* fmt, ...)` - Uses global logger and **CLAR_LOG_INFO** loglevel to log.

`void clar_warn(const char* fmt, ...)` - Uses global logger and **CLAR_LOG_WARNING** loglevel to log.

`void clar_error(const char* fmt, ...)` - Uses global logger and **CLAR_LOG_ERROR** loglevel to log.

`void clar_fatal(const char* fmt, ...)` - Uses global logger and **CLAR_LOG_FATAL** loglevel to log.

### Using custom loggers

#### Create custom logger:
```
and you will get something like:
struct clarifier clar = clar_create_logger(CLAR_LOG_DEBUG, clar_create_logtarget("test.log", CLAR_OUT_STDOUT | CLAR_OUT_FILE), "[%x] %l");
```
==> Variable "variable" value: "420"
```
What we are doing here:
- Create logger with **CLAR_LOG_DEBUG** loglevel
- With logtarget:
- Write to file test.log
- Write to both file and stdout, i. e. terminal
- With formatting string "[%x] %l"

#### How to use:
`void clar_log_with(struct clarifier* clar, __clar_loglevel loglevel, const char* fmt, ...)` - Uses custom logger and provided loglevel to log.

`void clar_debug(struct clarifier* clar, const char* fmt, ...)` - Uses custom logger and **CLAR_LOG_DEBUG** loglevel to log.

`void clar_info(struct clarifier* clar, const char* fmt, ...)` - Uses custom logger and **CLAR_LOG_INFO** loglevel to log.

`void clar_warn(struct clarifier* clar, const char* fmt, ...)` - Uses custom logger and **CLAR_LOG_WARNING** loglevel to log.

`void clar_error(struct clarifier* clar, const char* fmt, ...)` - Uses custom logger and **CLAR_LOG_ERROR** loglevel to log.

`void clar_fatal(struct clarifier* clar, const char* fmt, ...)` - Uses custom logger and **CLAR_LOG_FATAL** loglevel to log.

Loading