<commit_before>/**
 *
 * @author <NAME> <<EMAIL>>
 */
#ifndef UTILS_H
#define UTILS_H
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <event.h>

#define array_count(a) (sizeof(a)/sizeof 0[a])

#define SCROBBLE_BUFF_LEN 2

#define APPLICATION_NAME "mpris-scrobbler"
#define CREDENTIALS_PATH APPLICATION_NAME "/credentials"

#define LOG_ERROR_LABEL "ERROR"
#define LOG_WARNING_LABEL "WARNING"
#define LOG_DEBUG_LABEL "DEBUG"
#define LOG_TRACING_LABEL "TRACING"
#define LOG_INFO_LABEL "INFO"

static const char* get_log_level (log_level l) {
    switch (l) {
        case (error):
            return LOG_ERROR_LABEL;
        case (warning):
            return LOG_WARNING_LABEL;
        case (debug):
            return LOG_DEBUG_LABEL;
        case (tracing):
            return LOG_TRACING_LABEL;
        case (info):
        default:
            return LOG_INFO_LABEL;
    }
}

#define _error(...) _log(error, __VA_ARGS__)
#define _warn(...) _log(warning, __VA_ARGS__)
#define _info(...) _log(info, __VA_ARGS__)
#define _debug(...) _log(debug, __VA_ARGS__)
#define _trace(...) _log(tracing, __VA_ARGS__)

static int _log(log_level level, const char* format, ...)
{
#ifndef DEBUG
    if (level == debug || level == tracing) { return 0; }
#endif

    extern log_level _log_level;
    if (level < _log_level) { return 0; }

    va_list args;
    va_start(args, format);

    const char *label = get_log_level(level);
    size_t l_len = strlen(LOG_WARNING_LABEL);
    size_t p_len = l_len + 1;
    char* preffix = (char *)calloc(1, p_len + 1);
    snprintf(preffix, p_len + 1, "%-7s ", label);

    char* suffix = "\n";
    size_t s_len = strlen(suffix);
    size_t f_len = strlen(format);
    size_t full_len = p_len + f_len + s_len;

    char* log_format = (char *)calloc(1, full_len + 1);

    strncpy(log_format, preffix, p_len);
    free(preffix);

    strncpy(log_format + p_len, format, f_len);
    strncpy(log_format + p_len + f_len, suffix, s_len);

    int result = vfprintf(stderr, log_format, args);
    free(log_format);
    va_end(args);

    return result;
}

void free_credentials(api_credentials *credentials) {
    if (NULL == credentials) { return; }
    if (NULL != credentials->user_name) { free(credentials->user_name); }
    if (NULL != credentials->password)  { free(credentials->password); }
    free(credentials);
}

void free_configuration(configuration *global_config)
{
    if (NULL == global_config) { return; }
    for (size_t i = 0 ; i < global_config->credentials_length; i++) {
        free_credentials(global_config->credentials[i]);
    }
    //free(global_config);
}

void zero_string(char** incoming, size_t length)
{
    if (NULL == incoming) { return; }
    size_t length_with_null = (length + 1) * sizeof(char);
    memset(*incoming, 0, length_with_null);
}

char* get_zero_string(size_t length)
{
    size_t length_with_null = (length + 1) * sizeof(char);
    char* result = (char*)calloc(1, length_with_null);
    if (NULL == result) {
        _log(error & tracing, "mem::could_not_allocate %lu bytes string", length_with_null);
#if 0
    } else {
        _log(tracing, "mem::allocated %lu bytes string", length_with_null);
#endif
    }

    return result;
}

#define CONFIG_DIR_NAME ".config"
#define TOKENIZED_HOME_USER_PATH "%s/%s/%s"
#define TOKENIZED_XDG_CONFIG_PATH "%s/%s"
#define HOME_VAR_NAME "HOME"
#define USERNAME_VAR_NAME "USER"
#define XDG_CONFIG_HOME_VAR_NAME "XDG_CONFIG_HOME"<commit_msg>Making use of get_zero_string in _log function<commit_after>/**
 *
 * @author <NAME> <<EMAIL>>
 */
#ifndef UTILS_H
#define UTILS_H
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <event.h>

#define array_count(a) (sizeof(a)/sizeof 0[a])

#define SCROBBLE_BUFF_LEN 2

#define APPLICATION_NAME "mpris-scrobbler"
#define CREDENTIALS_PATH APPLICATION_NAME "/credentials"

char* get_zero_string(size_t length)
{
    size_t length_with_null = (length + 1) * sizeof(char);
    char* result = (char*)calloc(1, length_with_null);
#if 0
    if (NULL == result) {
        _trace("mem::could_not_allocate %lu bytes string", length_with_null);
    } else {
        _trace("mem::allocated %lu bytes string", length_with_null);
    }
#endif

    return result;
}

#define LOG_ERROR_LABEL "ERROR"
#define LOG_WARNING_LABEL "WARNING"
#define LOG_DEBUG_LABEL "DEBUG"
#define LOG_TRACING_LABEL "TRACING"
#define LOG_INFO_LABEL "INFO"

static const char* get_log_level (log_level l) {
    switch (l) {
        case (error):
            return LOG_ERROR_LABEL;
        case (warning):
            return LOG_WARNING_LABEL;
        case (debug):
            return LOG_DEBUG_LABEL;
        case (tracing):
            return LOG_TRACING_LABEL;
        case (info):
        default:
            return LOG_INFO_LABEL;
    }
}

#define _error(...) _log(error, __VA_ARGS__)
#define _warn(...) _log(warning, __VA_ARGS__)
#define _info(...) _log(info, __VA_ARGS__)
#define _debug(...) _log(debug, __VA_ARGS__)
#define _trace(...) _log(tracing, __VA_ARGS__)

static int _log(log_level level, const char* format, ...)
{
#ifndef DEBUG
    if (level == debug || level == tracing) { return 0; }
#endif

    extern log_level _log_level;
    if (level < _log_level) { return 0; }

    va_list args;
    va_start(args, format);

    const char *label = get_log_level(level);
    size_t l_len = strlen(LOG_WARNING_LABEL);

    size_t p_len = l_len + 1;
    char* preffix = get_zero_string(p_len);
    snprintf(preffix, p_len + 1, "%-7s ", label);

    char* suffix = "\n";
    size_t s_len = strlen(suffix);
    size_t f_len = strlen(format);
    size_t full_len = p_len + f_len + s_len;

    char* log_format = get_zero_string(full_len);
    strncpy(log_format, preffix, p_len);
    free(preffix);

    strncpy(log_format + p_len, format, f_len);
    strncpy(log_format + p_len + f_len, suffix, s_len);

    int result = vfprintf(stderr, log_format, args);
    free(log_format);
    va_end(args);

    return result;
}

void free_credentials(api_credentials *credentials) {
    if (NULL == credentials) { return; }
    if (NULL != credentials->user_name) { free(credentials->user_name); }
    if (NULL != credentials->password)  { free(credentials->password); }
    free(credentials);
}

void free_configuration(configuration *global_config)
{
    if (NULL == global_config) { return; }
    for (size_t i = 0 ; i < global_config->credentials_length; i++) {
        free_credentials(global_config->credentials[i]);
    }
    //free(global_config);
}

void zero_string(char** incoming, size_t length)
{
    if (NULL == incoming) { return; }
    size_t length_with_null = (length + 1) * sizeof(char);
    memset(*incoming, 0, length_with_null);
}

#define CONFIG_DIR_NAME ".config"
#define TOKENIZED_HOME_USER_PATH "%s/%s/%s"
#define TOKENIZED_XDG_CONFIG_PATH "%s/%s"
#define HOME_VAR_NAME "HOME"
#define USERNAME_VAR_NAME "USER"
#define XDG_CONFIG_HOME_VAR_NAME "XDG_CONFIG_HOME"
{'fraction_non_alphanumeric': 0.13249611965570762, 'fraction_numerical': 0.004233102864399605, 'mean_word_length': 3.773063973063973, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1912310', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2564, 'n_words': 588}