<commit_before>/*
 * blogc: A blog compiler.
 * Copyright (C) 2015-2016 <NAME> <<EMAIL>>
 *
 * This program can be distributed under the terms of the BSD License.
 * See the file LICENSE.
 */

#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "datetime-parser.h"
#include "template-parser.h"
#include "renderer.h"
#include "../common/error.h"
#include "../common/utils.h"


const char*
blogc_get_variable(const char *name, bc_trie_t *global, bc_trie_t *local)
{
    const char *rv = NULL;
    if (local != NULL) {
        rv = bc_trie_lookup(local, name);
        if (rv != NULL)
            return rv;
    }
    if (global != NULL)
        rv = bc_trie_lookup(global, name);
    return rv;
}


char*
blogc_format_date(const char *date, bc_trie_t *global, bc_trie_t *local)
{
    const char *date_format = blogc_get_variable("DATE_FORMAT", global, local);
    if (date == NULL)
        return NULL;
    if (date_format == NULL)
        return bc_strdup(date);

    bc_error_t *err = NULL;
    char *rv = blogc_convert_datetime(date, date_format, &err);
    if (err != NULL) {
        bc_error_print(err, "blogc");
        bc_error_free(err);
        return bc_strdup(date);
    }
    return rv;
}


char*
blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
    bc_slist_t *foreach_var)
{
    // if used asked for a variable that exists, just return it right away
    const char *value = blogc_get_variable(name, global, local);
    if (value != NULL)
        return bc_strdup(value);

    // do the same for special variable 'FOREACH_ITEM'
    if (0 == strcmp(name, "FOREACH_ITEM")) {
        if (foreach_var != NULL && foreach_var->data != NULL) {
            return bc_strdup(foreach_var->data);
        }
        return NULL;
    }

    char *var = bc_strdup(name);

    size_t i;
    size_t last = strlen(var);

    long int len = -1;

    // just walk till the last '_'
    for (i = last - 1; i > 0 && var[i] >= '0' && var[i] <= '9'; i--);

    if (var[i] == '_' && (i + 1) < last) {  // var ends with '_[0-9]+'
        // passing NULL to endptr because our string was previously validated
        len = strtol(var + i + 1, NULL, 10);
        if (errno != 0) {
            fprintf(stderr, "warning: invalid variable size for '%s' (%s), "
                "ignoring.\n", var, strerror(errno));
            len = -1;
        }
        else {<commit_msg>renderer: fixed strtol error detection bug in freebsd<commit_after>/*
 * blogc: A blog compiler.
 * Copyright (C) 2015-2016 <NAME> <<EMAIL>>
 *
 * This program can be distributed under the terms of the BSD License.
 * See the file LICENSE.
 */

#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "datetime-parser.h"
#include "template-parser.h"
#include "renderer.h"
#include "../common/error.h"
#include "../common/utils.h"


const char*
blogc_get_variable(const char *name, bc_trie_t *global, bc_trie_t *local)
{
    const char *rv = NULL;
    if (local != NULL) {
        rv = bc_trie_lookup(local, name);
        if (rv != NULL)
            return rv;
    }
    if (global != NULL)
        rv = bc_trie_lookup(global, name);
    return rv;
}


char*
blogc_format_date(const char *date, bc_trie_t *global, bc_trie_t *local)
{
    const char *date_format = blogc_get_variable("DATE_FORMAT", global, local);
    if (date == NULL)
        return NULL;
    if (date_format == NULL)
        return bc_strdup(date);

    bc_error_t *err = NULL;
    char *rv = blogc_convert_datetime(date, date_format, &err);
    if (err != NULL) {
        bc_error_print(err, "blogc");
        bc_error_free(err);
        return bc_strdup(date);
    }
    return rv;
}


char*
blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
    bc_slist_t *foreach_var)
{
    // if used asked for a variable that exists, just return it right away
    const char *value = blogc_get_variable(name, global, local);
    if (value != NULL)
        return bc_strdup(value);

    // do the same for special variable 'FOREACH_ITEM'
    if (0 == strcmp(name, "FOREACH_ITEM")) {
        if (foreach_var != NULL && foreach_var->data != NULL) {
            return bc_strdup(foreach_var->data);
        }
        return NULL;
    }

    char *var = bc_strdup(name);

    size_t i;
    size_t last = strlen(var);

    long int len = -1;

    // just walk till the last '_'
    for (i = last - 1; i > 0 && var[i] >= '0' && var[i] <= '9'; i--);

    if (var[i] == '_' && (i + 1) < last) {  // var ends with '_[0-9]+'
        char *endptr;
        len = strtol(var + i + 1, &endptr, 10);
        if (*endptr != '\0') {
            fprintf(stderr, "warning: invalid variable size for '%s', "
                "ignoring.\n", var);
            len = -1;
        }
        else {
{'fraction_non_alphanumeric': 0.1421820423258681, 'fraction_numerical': 0.009040476679679475, 'mean_word_length': 2.5506929248723558, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 28, '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': '1316618', 'n_tokens_mistral': 1739, 'n_tokens_neox': 1688, 'n_words': 487}