Skip to content

Commit

Permalink
Feature convenience macros refactoring (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
CrusaderSVK287 authored Aug 29, 2023
2 parents e46308e + 7b826fb commit a350539
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 51 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,4 @@ deps:
install: $(BIN)
sudo cp $(BIN) /usr/lib/$(BINNAME)
sudo cp $(SRCDIR)cclog.h /usr/include/cclog.h
sudo cp $(SRCDIR)cclog_macros.h /usr/include/cclog_macros.h
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,14 @@ There are several macros provided for convenience
* if_failed_log(val, label, log_level, priv, msg, ...) - if val is other than 0, make a log and jump to the label
* if_null_log(val, label, log_level, priv, msg, ...) - if val is null, make a log and jump to the label

To use these macros you need to include this header file
```c
#include <cclog_macros.h>
```

if_failed macros have a positive and negative variants which fire if the val is eighter positive or negative but not zero.\
These variants have eighter p or n at the end. Example: `if_failed_logp` will log and jump to label if value is greater than 0
These variants have eighter p or n at the end. Example: `if_failed_log_p` will log and jump to label if value is greater than 0.
There are way more macros than this. Look inside documentation or src/cclog_macros.h file
***
## Example
Example for a simple program using cclog library
Expand All @@ -107,29 +113,32 @@ Example for a simple program using cclog library

#include <stdio.h>
#include <cclog.h>
#include <cclog_macros.h>

int main()
{
/*
* Initialise the logger.
* We will be using a single file called my_log_file
* We dont need to specify proc_name since we are sure
* path isnt NULL
*/
cclogger_init(LOGGING_SINGLE_FILE, "./my_log_file", NULL);
/*
* Initialise the logger.
* We will be using a single file called my_log_file
* We dont need to specify proc_name since we are sure
* path isnt NULL
*/
cclogger_init(LOGGING_SINGLE_FILE, "./my_log_file", NULL);

/* We write a message to the file only */
cclog(CCLOG_LEVEL_MSG, NULL, "Lets do some logging");
/* We write a message to the file only */
cclog(CCLOG_LEVEL_MSG, NULL, "Lets do some logging");

/* We write a message both to file and to terminal */
if (2 + 2 != 10) {
cclog(CCLOG_LEVEL_ERR, NULL, "Error, bad result");
}
/* We write a message both to file and to terminal */
int val = -1;
if_failed_log(val, error, CCLOG_LEVEL_ERR, NULL, "Error, bad result");

printf("This should not appear\n");

/* Uninitialise logger */
cclogger_uninit();
error:
/* Uninitialise logger */
cclogger_uninit();

return 0;
return 0;
}
```
my_log_file.log:
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Recommended reading order:
* [Basic usage](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/basic_usage)
* [Log levels](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/log_levels)
* [Message formatting](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/message_format)
* [Macros](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/macros)
* [Configuration](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/config)
* [Server](https://github.com/CrusaderSVK287/CCLog/tree/docs_advanced_usage/docs/server)

58 changes: 58 additions & 0 deletions docs/macros/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Macros
CClogger provides a number of convenience macros. To use these macros you need to use
```c
#include <cclog_macros.h>
```
The macros are defined in different header file to not clutter the main API and to be optitional for usage.

## Usage
There are a lot of macros defined and the best way to learn everything about them is to look into the [header file](https://github.com/CrusaderSVK287/CCLog/blob/main/src/cclog_macros.h) itself since every macro has a comment above it saying shortly what it does.\
However, a short introduction is also found in this documentation. We have 3 kinds of macros:
* on condition jump
* on condition make a log and then jump
* on condition just make a log

Here, jumping is meant using `goto`. Most people don't like to use gotos, hence why the 3rd kind of macro was added. Lets look at some details.

## Common traits
If we take a look on one of each "group" of macros we can see some similiarities
```c
/* Fires if val is 0 */
#define if_success(val, label) {if (val == 0) {goto label;}}

/* Fires if val is greater than zero */
#define if_failed_logp(val, label, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

/* Fires if val is null, doesnt jump to label */
#define if_null_log_ng(val, log_level, priv, msg, ...) {\
if (val == (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
```
First, we can see that the naming scheme of the macros looks like this: `if_(success|failed)[_log][_(p|n|pe|ne)][_ng]`. This is the basic naming scheme. The first part, `if_(success|failed)`
if_success or if_failed doesnt have any effect on functionality, it's just to enable denotig that the jump is supposed to be performed if the operation was successfull. \
Note: The only difference between success/failed is that basic(that is without suffix) if_success makes a val == 0 comparison and if_failed make a val != 0 comparison.\
The second part `[_log]`, just indicates whether the macro produces a log or not.\
The third part `[_(p|n|pe|ne)][_ng]` are the suffixes. These are explained in the next chapter
## Suffixes
You may have noticed that there are a lot of macros that almost the same but have some suffix to them. These suffixes indicates how the macro compares value.
For all the macro goups, these suffixes are used.
* p - comparison is (val > 0)
* n - comparison is (val < 0)
* pe - comparison is (val >= 0)
* ne - comparison is (val <= 0)
The third macro group (on condition just make a log) has its own suffix since it does exactly the same thing as the second group (on condition make a log and jump) but without jumping to any label. All macros in this group also have a suffix `ng` (abreviation of "no goto").
### Suffix Examples
`if_failedn` : suffix is n, meaning will jump if val is **n**egative\
`if_success_log_p` : suffix is p, meaning will jump if val is **p**ositive\
`if_failed_log_pe_ng` : suffix is p, so it will fire if value is more or equal to zero, **but** it also has a `ng` suffix meaning it won't jump to label
35 changes: 1 addition & 34 deletions src/cclog.h
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
#ifndef __CCLOG_H__
#define __CCLOG_H__

#define __CCLOG_VERSION__ "v1.0.0"
#include <stdbool.h>

/* convenience macros */
#define if_failed(val, label) {if (val != 0) {goto label;}}
#define if_failedn(val, label) {if (val < 0) {goto label;}}
#define if_failedp(val, label) {if (val > 0) {goto label;}}
#define if_null(val, label) {if (val == (void*)0) {goto label;}}

#define if_failed_log(val, label, log_level, priv, msg, ...) {\
if (val != 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

#define if_failed_logn(val, label, log_level, priv, msg, ...) {\
if (val < 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

#define if_failed_logp(val, label, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

#define if_null_log(val, label, log_level, priv, msg, ...) {\
if (val == (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

/**
* Log callback function pointer typedef. Declare such function like this:
* int name_of_cb_func(const char* msg, void *priv)
Expand Down
199 changes: 199 additions & 0 deletions src/cclog_macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#ifndef __CCLOG_MACROS_H__
#define __CCLOG_MACROS_H__

#define __CCLOG_MACROS_VERSION__ "v1.0.0"
/**
* Macros for conditional jumping if expression evaluates to true
*/

/* Fires if val is 0 */
#define if_success(val, label) {if (val == 0) {goto label;}}
/* Fires if val is greater than zero */
#define if_success_p(val, label) {if (val > 0) {goto label;}}
/* Fires if val is greater or equal to zero */
#define if_successp_e(val, label) {if (val >= 0) {goto label;}}
/* Fires if val is less than zero */
#define if_success_n(val, label) {if (val < 0) {goto label;}}
/* Fires if val is less or equal to zero */
#define if_success_ne(val, label) {if (val <= 0) {goto label;}}
/* Fires if val is not zero */
#define if_failed(val, label) {if (val != 0) {goto label;}}
/* Fires if val less than zero */
#define if_failed_n(val, label) {if (val < 0) {goto label;}}
/* Fires if val less or equal to zero */
#define if_failed_ne(val, label) {if (val <= 0) {goto label;}}
/* Fires if val is greater than zero */
#define if_failed_p(val, label) {if (val > 0) {goto label;}}
/* Fires if val is greater or equal to zero */
#define if_failed_pe(val, label) {if (val >= 0) {goto label;}}
/* Fires if val is null */
#define if_null(val, label) {if (val == (void*)0) {goto label;}}
/* Fires if val is not null*/
#define if_not_null(val, label) {if (val == (void*)0) {goto label;}}

/**
* Macros for logging and jumping if expression evaluates to true
*/

/* Fires if val is 0 */
#define if_success_log(val, label, log_level, priv, msg, ...) {\
if (val == 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires of val is less than zero */
#define if_success_log_n(val, label, log_level, priv, msg, ...) {\
if (val < 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires of val is less or equal to zero */
#define if_success_log_ne(val, label, log_level, priv, msg, ...) {\
if (val <= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is greater than zero */
#define if_success_log_p(val, label, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is greater or equal to zero */
#define if_success_log_pe(val, label, log_level, priv, msg, ...) {\
if (val >= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is not zero */
#define if_failed_log(val, label, log_level, priv, msg, ...) {\
if (val != 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is less than zero */
#define if_failed_log_n(val, label, log_level, priv, msg, ...) {\
if (val < 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is less or equal to zero */
#define if_failed_log_ne(val, label, log_level, priv, msg, ...) {\
if (val <= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is greater than zero */
#define if_failed_log_p(val, label, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is greater or equal to zero */
#define if_failed_log_pe(val, label, log_level, priv, msg, ...) {\
if (val >= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is null */
#define if_null_log(val, label, log_level, priv, msg, ...) {\
if (val == (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}
/* Fires if val is not null */
#define if_not_null_log(val, log_level, priv, msg, ...) {\
if (val != (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
goto label;\
}\
}

/**
* No goto variants of log Macros
*/

/* Fires if val is 0, doesnt jump to label */
#define if_success_log_ng(val, log_level, priv, msg, ...) {\
if (val == 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires of val is less than zero, doesnt jump to label */
#define if_success_log_n_ng(val, log_level, priv, msg, ...) {\
if (val < 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires of val is less or equal to zero, doesnt jump to label */
#define if_success_log_ne_ng(val, log_level, priv, msg, ...) {\
if (val <= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is greater than zero, doesnt jump to label */
#define if_success_logp_ng(val, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is greater or equal to zero, doesnt jump to label */
#define if_success_log_pe_ng(val, log_level, priv, msg, ...) {\
if (val >= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is not zero, doesnt jump to label */
#define if_failed_log_ng(val, log_level, priv, msg, ...) {\
if (val != 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is less than zero, doesnt jump to label */
#define if_failed_logn_ng(val, log_level, priv, msg, ...) {\
if (val < 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is less or equal to zero, doesnt jump to label */
#define if_failed_log_ne_ng(val, log_level, priv, msg, ...) {\
if (val <= 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is greater than zero, doesnt jump to label */
#define if_failed_logp_ng(val, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is greater or equal to zero, doesnt jump to label */
#define if_failed_log_pe_ng(val, log_level, priv, msg, ...) {\
if (val > 0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is null, doesnt jump to label */
#define if_null_log_ng(val, log_level, priv, msg, ...) {\
if (val == (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
/* Fires if val is not null, doesnt jump to label */
#define if_not_null_log_ng(val, log_level, priv, msg, ...) {\
if (val != (void*)0) {\
cclog(log_level, priv, msg, ## __VA_ARGS__);\
}\
}
#endif // !__CCLOG_MACROS_H__
1 change: 1 addition & 0 deletions src/logger.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "logger.h"
#include "cclog.h"
#include "cclog_macros.h"
#include "json.h"
#include "options.h"
#include "server.h"
Expand Down
1 change: 1 addition & 0 deletions src/logger_init.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "cclog.h"
#include "cclog_macros.h"
#include "options.h"
#include "logger.h"
#include "json.h"
Expand Down
Loading

0 comments on commit a350539

Please sign in to comment.