<commit_before>#include "test_in_lpg.h"
#include "find_builtin_module_directory.h"
#include "handle_parse_error.h"
#include "lpg_allocate.h"
#include "lpg_assert.h"
#include "lpg_c_backend.h"
#include "lpg_check.h"
#include "lpg_ecmascript_backend.h"
#include "lpg_interpret.h"
#include "lpg_load_module.h"
#include "lpg_monotonic_clock.h"
#include "lpg_optimize.h"
#include "lpg_path.h"
#include "lpg_read_file.h"
#include "lpg_remove_dead_code.h"
#include "lpg_rename_file.h"
#include "lpg_save_expression.h"
#include "lpg_standard_library.h"
#include "lpg_stream_writer.h"
#include "lpg_thread.h"
#include "lpg_write_file.h"
#include "lpg_write_file_if_necessary.h"
#include "test.h"
#include <inttypes.h>
#include <string.h>
#ifdef LPG_WITH_DUKTAPE
#include "duktape.h"
#endif

static sequence parse(unicode_view const input)
{
    test_parser_user user = {{input.begin, input.length, source_location_create(0, 0)}, NULL, 0};
    expression_parser parser = expression_parser_create(find_next_token, &user, handle_error, &user);
    sequence const result = parse_program(&parser);
    expression_parser_free(parser);
    REQUIRE(user.base.remaining_size == 0);
    return result;
}

static void expect_no_errors(complete_semantic_error const error, void *user)
{
    (void)error;
    (void)user;
    FAIL();
}

static external_function_result assert_impl(value const *const captures, void *environment, optional_value const self,
                                            value *const arguments, interpreter *const context)
{
    (void)context;
    (void)self;
    (void)captures;
    (void)environment;
    ASSUME(arguments[0].kind == value_kind_enum_element);
    enum_element_id const argument = arguments[0].enum_element.which;
    REQUIRE(argument == 1);
    return external_function_result_from_success(value_from_unit());
}

#ifdef LPG_WITH_DUKTAPE
static duk_ret_t ecmascript_assert(duk_context *const duktape)
{
    duk_int_t const argument_type = duk_get_type(duktape, 0);
    duk_inspect_callstack_entry(duktape, -3);
    duk_get_prop_string(duktape, -1, "lineNumber");
    long const line = (long)duk_to_int(duktape, -1);
    duk_pop_2(duktape);
    REQUIRE_WITH_MESSAGE((argument_type == DUK_TYPE_BOOLEAN), "immediate caller is executing on line %ld\n", line);
    REQUIRE_WITH_MESSAGE(duk_get_boolean(duktape, 0), "immediate caller is executing on line %ld\n", line);
    return 0;
}

static duk_ret_t ecmascript_fail(duk_context *const duktape)
{
    duk_inspect_callstack_entry(duktape, -3);
    duk_get_prop_string(duktape, -1, "lineNumber");
    long const line = (long)duk_to_int(duktape, -1);
    duk_pop_2(duktape);
    fprintf(stderr, "failure on line %ld\n", line);
    FAIL();
}

static void *duktape_allocate(void *udata, duk_size_t size)
{
    (void)udata;
    return allocate(size);
}

static void *duktape_realloc(void *udata, void *ptr, duk_size_t size)
{
    (void)udata;
    if (size == 0)
    {
        if (ptr)
        {
            deallocate(ptr);
        }
        return NULL;
    }
    return reallocate(ptr, size);
}

static void duktape_free(void *udata, void *ptr)
{
    (void)udata;
    if (!ptr)
    {
        return;
    }
    deallocate(ptr);
}

static void duktake_handle_fatal(void *udata, const char *msg)
{
    memory_writer const *const source = udata;
    fwrite(source->data, source->used, 1, stderr);
    fprintf(stderr, "\n%s\n", msg);
    FAIL();
}
#endif

static void run_c_test(unicode_view const test_name, unicode_view const c_source, unicode_view const c_test_dir)
{
    ASSUME(test_name.length > 0);
    unicode_view const last_success_pieces[] = {c_test_dir, unicode_view_from_c_str("last_success.c")};
    unicode_string const last_success = path_combine(last_success_pieces, LPG_ARRAY_SIZE(last_success_pieces));
    {
        unicode_string const last_success_zero = unicode_view_zero_terminate(unicode_view_from_string(last_success));
        blob_or_error const last_success_read = read_file(last_success_zero.data);
        unicode_string_free(&last_success_zero);
        if (!last_success_read.error)
        {
            bool const equal = ((last_success_read.success.length == c_source.length) &&
                                !memcmp(last_success_read.success.data, c_source.begin, c_source.length));
            blob_free(&last_success_read.success);
            if (equal)
            {
                goto out;
            }
        }
    }
    unicode_view const source_pieces[] = {c_test_dir, unicode_view_from_c_str("generated_test.c")};
    unicode_string const source_file_path = path_combine(source_pieces, LPG_ARRAY_SIZE(source_pieces));
    write_file_if_necessary(unicode_view_from_string(source_file_path), c_source);
    {
        unicode_view const cmakelists_pieces[] = {c_test_dir, unicode_view_from_c_str("CMakeLists.txt")};
        unicode_string const cmakelists = path_combine(cmakelists_pieces, LPG_ARRAY_SIZE(cmakelists_pieces));
        memory_writer cmakelists_content = {NULL, 0, 0};
        stream_writer writer = memory_writer_erase(&cmakelists_content);
        REQUIRE(success_yes == stream_writer_write_string(writer, "cmake_minimum_required(VERSION 3.2)\n"
                                                                  "project(generated_test_solution)\n"
                                                                  "if(MSVC)\n"
                                                                  "    add_definitions(/WX)\n"
                                                                  "    add_definitions(/wd4101)\n"
                                                                  "    add_definitions(/wd4717)\n"
                                                                  "else()\n"
                                                                  "    add_definitions(-std=gnu99)\n"
                                                                  "endif()\n"));
        REQUIRE(success_yes == stream_writer_write_string(writer, "include_directories(\""));
        {
            unicode_view const pieces[] = {path_remove_leaf(path_remove_leaf(unicode_view_from_c_str(__FILE__))),
                                           unicode_view_from_c_str("c_backend"),
                                           unicode_view_from_c_str("environment")};
            unicode_string const include_path = path_combine(pieces, LPG_ARRAY_SIZE(pieces));
            REQUIRE(success_yes == stream_writer_write_unicode_view(writer, unicode_view_from_string(include_path)));
            unicode_string_free(&include_path);
        }
        REQUIRE(success_yes == stream_writer_write_string(writer, "\")\n"));<commit_msg>skip unnecessary C++ compiler checks in CMake<commit_after>#include "test_in_lpg.h"
#include "find_builtin_module_directory.h"
#include "handle_parse_error.h"
#include "lpg_allocate.h"
#include "lpg_assert.h"
#include "lpg_c_backend.h"
#include "lpg_check.h"
#include "lpg_ecmascript_backend.h"
#include "lpg_interpret.h"
#include "lpg_load_module.h"
#include "lpg_monotonic_clock.h"
#include "lpg_optimize.h"
#include "lpg_path.h"
#include "lpg_read_file.h"
#include "lpg_remove_dead_code.h"
#include "lpg_rename_file.h"
#include "lpg_save_expression.h"
#include "lpg_standard_library.h"
#include "lpg_stream_writer.h"
#include "lpg_thread.h"
#include "lpg_write_file.h"
#include "lpg_write_file_if_necessary.h"
#include "test.h"
#include <inttypes.h>
#include <string.h>
#ifdef LPG_WITH_DUKTAPE
#include "duktape.h"
#endif

static sequence parse(unicode_view const input)
{
    test_parser_user user = {{input.begin, input.length, source_location_create(0, 0)}, NULL, 0};
    expression_parser parser = expression_parser_create(find_next_token, &user, handle_error, &user);
    sequence const result = parse_program(&parser);
    expression_parser_free(parser);
    REQUIRE(user.base.remaining_size == 0);
    return result;
}

static void expect_no_errors(complete_semantic_error const error, void *user)
{
    (void)error;
    (void)user;
    FAIL();
}

static external_function_result assert_impl(value const *const captures, void *environment, optional_value const self,
                                            value *const arguments, interpreter *const context)
{
    (void)context;
    (void)self;
    (void)captures;
    (void)environment;
    ASSUME(arguments[0].kind == value_kind_enum_element);
    enum_element_id const argument = arguments[0].enum_element.which;
    REQUIRE(argument == 1);
    return external_function_result_from_success(value_from_unit());
}

#ifdef LPG_WITH_DUKTAPE
static duk_ret_t ecmascript_assert(duk_context *const duktape)
{
    duk_int_t const argument_type = duk_get_type(duktape, 0);
    duk_inspect_callstack_entry(duktape, -3);
    duk_get_prop_string(duktape, -1, "lineNumber");
    long const line = (long)duk_to_int(duktape, -1);
    duk_pop_2(duktape);
    REQUIRE_WITH_MESSAGE((argument_type == DUK_TYPE_BOOLEAN), "immediate caller is executing on line %ld\n", line);
    REQUIRE_WITH_MESSAGE(duk_get_boolean(duktape, 0), "immediate caller is executing on line %ld\n", line);
    return 0;
}

static duk_ret_t ecmascript_fail(duk_context *const duktape)
{
    duk_inspect_callstack_entry(duktape, -3);
    duk_get_prop_string(duktape, -1, "lineNumber");
    long const line = (long)duk_to_int(duktape, -1);
    duk_pop_2(duktape);
    fprintf(stderr, "failure on line %ld\n", line);
    FAIL();
}

static void *duktape_allocate(void *udata, duk_size_t size)
{
    (void)udata;
    return allocate(size);
}

static void *duktape_realloc(void *udata, void *ptr, duk_size_t size)
{
    (void)udata;
    if (size == 0)
    {
        if (ptr)
        {
            deallocate(ptr);
        }
        return NULL;
    }
    return reallocate(ptr, size);
}

static void duktape_free(void *udata, void *ptr)
{
    (void)udata;
    if (!ptr)
    {
        return;
    }
    deallocate(ptr);
}

static void duktake_handle_fatal(void *udata, const char *msg)
{
    memory_writer const *const source = udata;
    fwrite(source->data, source->used, 1, stderr);
    fprintf(stderr, "\n%s\n", msg);
    FAIL();
}
#endif

static void run_c_test(unicode_view const test_name, unicode_view const c_source, unicode_view const c_test_dir)
{
    ASSUME(test_name.length > 0);
    unicode_view const last_success_pieces[] = {c_test_dir, unicode_view_from_c_str("last_success.c")};
    unicode_string const last_success = path_combine(last_success_pieces, LPG_ARRAY_SIZE(last_success_pieces));
    {
        unicode_string const last_success_zero = unicode_view_zero_terminate(unicode_view_from_string(last_success));
        blob_or_error const last_success_read = read_file(last_success_zero.data);
        unicode_string_free(&last_success_zero);
        if (!last_success_read.error)
        {
            bool const equal = ((last_success_read.success.length == c_source.length) &&
                                !memcmp(last_success_read.success.data, c_source.begin, c_source.length));
            blob_free(&last_success_read.success);
            if (equal)
            {
                goto out;
            }
        }
    }
    unicode_view const source_pieces[] = {c_test_dir, unicode_view_from_c_str("generated_test.c")};
    unicode_string const source_file_path = path_combine(source_pieces, LPG_ARRAY_SIZE(source_pieces));
    write_file_if_necessary(unicode_view_from_string(source_file_path), c_source);
    {
        unicode_view const cmakelists_pieces[] = {c_test_dir, unicode_view_from_c_str("CMakeLists.txt")};
        unicode_string const cmakelists = path_combine(cmakelists_pieces, LPG_ARRAY_SIZE(cmakelists_pieces));
        memory_writer cmakelists_content = {NULL, 0, 0};
        stream_writer writer = memory_writer_erase(&cmakelists_content);
        REQUIRE(success_yes == stream_writer_write_string(writer, "cmake_minimum_required(VERSION 3.2)\n"
                                                                  "project(generated_test_solution C)\n"
                                                                  "if(MSVC)\n"
                                                                  "    add_definitions(/WX)\n"
                                                                  "    add_definitions(/wd4101)\n"
                                                                  "    add_definitions(/wd4717)\n"
                                                                  "else()\n"
                                                                  "    add_definitions(-std=gnu99)\n"
                                                                  "endif()\n"));
        REQUIRE(success_yes == stream_writer_write_string(writer, "include_directories(\""));
        {
            unicode_view const pieces[] = {path_remove_leaf(path_remove_leaf(unicode_view_from_c_str(__FILE__))),
                                           unicode_view_from_c_str("c_backend"),
                                           unicode_view_from_c_str("environment")};
            unicode_string const include_path = path_combine(pieces, LPG_ARRAY_SIZE(pieces));
            REQUIRE(success_yes == stream_writer_write_unicode_view(writer, unicode_view_from_string(include_path)));
            unicode_string_free(&include_path);
        }
        REQUIRE(success_yes == stream_writer_write_string(writer, "\")\n"));
{'fraction_non_alphanumeric': 0.10294117647058823, 'fraction_numerical': 0.005252100840336135, 'mean_word_length': 2.8170103092783507, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 52, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5902606', 'n_tokens_mistral': 4382, 'n_tokens_neox': 4265, 'n_words': 732}